Showing posts with label How to Better. Show all posts
Showing posts with label How to Better. Show all posts

Thursday, April 21, 2016

How to Be a Better Programmer - Part 3



https://mp.weixin.qq.com/s/W1PBOScBCxbHfoyccg5tGw
$ 程序员的高傲:提交的代码被任何人读起来都应该是优雅的;交付给测试的功能点一定是自己反复验证过的,出现低级BUG丢不起那人;敬畏生产环境,上线脚本/配置/变量/步骤/困难全都罗列的一清二楚,上线失败如同过掉门将面对空门将球打飞,可笑又可耻。

$ 装逼套路:能用命令行绝不用图形界面,能用快捷键绝不用鼠标,IDE必须黑色主题,桌面墙纸必须个性,案头必备一本英文原版书(就算垫显示器),必须盲敲数字键(别笑,我不认为现在程序员有多少可以做得到或者做得6)
总之,在编程起步的这段模仿路上,从例行工作到三余读书,从照搬仿效到习惯养成,从实际行为(形)到思想境界(神),其实你会发现这模仿本身也是个成长的过程,只是这路不是你自己摸索的而是踩着前人的脚印。您再看,这个过程缘何我模仿的自得其乐?因为我把自己视作孩童,放低身段,自降一维,只求成长。


https://zhuanlan.zhihu.com/p/34293012
因为他们只有第一年的时候在学习如何适应工作,如何提高工作效率,如何与同事沟通。以至于后面的九年都在用第一年积累的经验以及所学习到的技能。
许岑老师说:成年人是靠任务驱动的。




什么叫任务驱动?就是我干这件事是有我要解决的问题的,我是奔着我的目标去的。现在很多 App 很多产品都提倡利用你的碎片化时间,所以你就扑腾扑腾不断跑来跑去捡了很多的树枝,后来发现自己的院子里堆满了树枝,而想象中的参天大树毫无踪迹。碎片化时间的基础是,你要有自己强壮的主干,慢慢去吸收阳光吸收养料,碎片化地成长树叶和树枝,这样子你才有成为参天大树的可能,否则就只是在院子里堆满树枝了。





以我自己为例子,我从来没觉得我好像很喜欢大数据,机器学习,知识图谱,分布式系统这些单个的技术,我只是培养了自己学习的能力。我几乎能在一两周的时间内熟悉一个小东西并且搭一个应用把它利用起来,然后把它讲给我的小伙伴们听,如果我的小伙伴们听懂了,他们也可以去创造自己的应用了,这个时候的我对于这项技术也基本都掌握了。所以我的目标是很明确的,我学习这项技术第一是为了完成我手头的事情,第二是为了把它分享给我的小伙伴们,这样子下来,我就有了充足的任务去学习了。

你说你不知道怎么做,我可以告诉你。首先做好你手头的事情,让它们更优质更快速更有效率完成,然后帮助你的团队伙伴也跟你一样。做到这两样我保证你会有非常不同的感受。



这样做了以后呢,同时保持你的大脑是足够开放的,遇到负反馈就改进,遇到正反馈就要思考是不是真的,能够接受所有的信息。大脑进化了这么久,很喜欢听到赞美,不喜欢看到反对的意见,这是潜意识里基因里决定的,不是大脑能决定的,但是我们人类最大的优势就是我们可以决定不顺从它。


http://www.yacoset.com/Hoe/signs-that-you-re-a-good-programmer
http://blog.jobbole.com/87799/

1. The instinct to experiment first

The compiler and runtime can often answer a question faster than a human can. Rather than seek out a senior programmer and ask them "will it work if I do this?", a good programmer will just try it and see if it works before bringing their problem to someone else.
  1. 代码还没运行就能预知其中的 bug。

2. Emotional detachment from code and design

Code is like kleenex: you use it when it's useful and throw it away when it no longer serves. We all like to think that code-reuse is important, and while it is, it's not meant to be about raising a child. Code doesn't feel. Code doesn't care. Code will turn on you like a Frankenstein monster. Code is just bytes. Code is a liability.

Symptoms

  1. Almost no committed code that is commented out
  2. Willingly throws away weeks or months of work in order to adopt another programmer's superior code
  3. Puts finger to lips, furrows brow and says "hmm" when faults in their work are pointed out, while looking at the code and not the critic
  4. Indifferent to the way the IDE wants to auto-format code, uninterested in "tabs-vs-spaces" arguments
  5. Refers to it as "the code" rather than "my code", unless accepting blame
  6. Has abandoned a design of theirs that was previously used in a successful product
  7. Doesn't become defensive when the boss mentions that they're looking for an off-the-shelf alternative to what they've been writing for the past few years

it's you who controls the idea, not the idea that controls you.

Find the code that you're the most proud of and delete it, now re-write it from scratch in a different way. Use a "design pattern" that confuses you, or that you hate (e.g.: the Singleton) and figure out how to make it work. If necessary, delete that after you've got it working and try again with a new pattern or language. Not only will you learn that there's More Than One Way To Do It, but you'll learn that your code is transitory. Code, by its nature, is not just inextricably glued to its language, platform, and the APIs it consumes, but written in the form of ephemeral static charges, orientations of magnetic particles, subject to the whims of the market, Moore's Law, and your employer.

Other techniques to break the abusive relationship:
  1. Maintain somebody else's code
  2. Experience, either by accident or bloody intention, what it's like to lose a week's work to a failed backup or a botched commit and have to re-write it all over again
  3. Work for start-ups where you'll get laid-off when the second or third round of financing doesn't come through
  4. Be stupid enough to post your best code on Reddit

3. Eager to fix what isn't broken

Programs are infrastructure: they're built to serve a specific need, but needs always change. Good programmers realize that hard-coded values buried in code are bad, that a destoryBaghdad() function is immoral, and that it's a priority to eliminate "code smells". Not for pride. Not for backslapping attaboys from your peers or the authors of methodology books. But because you will itch until it is fixed.

  1. Doesn't take the spec by its word and tries to find out who wrote it and what they were thinking
  2. Hunts down and talks to the people who will use the program each day
  3. Owns a book written by a guy called Martin Fowler
  4. Tends to express extreme like or dislike for popular technologies such as XML, ORM and REST, and has also switched positions on one or more of these in the past
  5. Likes to use abstraction layers, but doesn't like to add more than one layer on top of what's already in the language or platform
  6. Talks about "low cohesion"
  7. At least 10% or more of their commits reduce the line-count of the project without adding new functionality
  8. Before adding a new feature, checks to see if an existing one can be re-designed to perform both tasks or replaced entirely with a better method
Code lets you learn in stages where you don't need to re-write everything from scratch. You re-write pieces after you understand what they need to do and what they'll never need to do, make them simpler, shorter and beautiful.

Aim for these, in increasing order of importance:
  1. Code that does the same thing, but is shorter or more efficient
  2. Code that does the same thing, but uses an appropriate "wheel" built-into the platform instead of reinventing its own
  3. Code that does the same thing, but is easier to modify for similar needs
  4. Code that does the same thing, but is easier to read and understand
  5. Code that doesn't exist

4. Fascinated by the incomprehensible


5. Compelled to teach

  1. Blogs about their work
  2. Has an active Wikipedia account
  3. Unhesitant to pick up a marker and approach a whiteboard
  4. Commits changes to the repository that consist only of comments
  5. Lets new hires borrow books that cost them $100 to buy

1. Incorruptible patience

  1. Unbothered by office politics
  2. Can predict a bug before the code is ever run

2. A destructive pursuit of perfection

3. Encyclopedic grasp of the platform

Encyclopedic knowledge takes decades to acquire, but every Guru in the world got there by doing roughly the same three things each day:
  1. Struggling to solve problems they find to be difficult
  2. Writing about how they solved difficult problems
  3. Reflecting on how they solved difficult problems

4. Thinks In Code

5. When In Rome, Does As Romans Do

  1. No automatic interest in cross-platform frameworks
  2. Contemptuous of "language wars"
  3. Doesn't see a strategic disadvantage in maintaining the same program in multiple languages
  4. Assumes their own code is the source of a bug before blaming the compiler, library or operating system
  5. Displays a plush Tux penguin or Android in their cubicle soon after being assigned to a project targeting that platform
  6. Switches brand of cell phone or tablet in the same circumstance
  7. Hits a stack of technical manuals before assuming a data-type like double or decimal will do what they think on a new device

6. Creates their own tools

  1. Has set up an automated build server
  2. Has written their own benchmark or specialized profiler
  3. Maintains an open-source project on GitHub
  4. Has re-invented LISP at least once
  5. Knows what a Domain Specific Language is, and has designed and written an interpreter for one
  6. Extends their IDE/Editor with custom macros

Signs that you're destined for more

1. Indifferent to Hierarchy

Richard Feynman once pointed out that "it doesn't matter who your dad knows", if something is wrong then it's wrong no matter who says its right. Don't fear the consequences to your career, you''ll find another job. Society never wastes real talent.
  1. Getting into arguments with the CEO
  2. Quitting on principle
  3. Organizing teams without permission
  4. Creating new products after-hours while hiding from the Rent-a-Cops
  5. Re-organizing the workspace "Peopleware" style, against company policy
  6. Helps themselves to the boss's private stash of bottled water

2. Excited by failure

3. Indifferent to circumstances

  1. Stock options and bonuses are ineffective retainment techniques
  2. Cashes-in their 401k to fund their next venture

4. Unswayed by obligations

5. Substitutes impulse for commitment

6. Driven by experiences

The idea of recursion is easy enough to understand, but programmers often have problems imagining the result of a recursive operation in their minds, or how a complex result can be computed with a simple function. This makes it harder to design a recursive function because you have trouble picturing "where you are" when you come to writing the test for the base condition or the parameters for the recursive call.

Symptoms

  1. Hideously complex iterative algorithms for problems that can be solved recursively (eg: traversing a filesystem tree), especially where memory and performance is not a premium
  2. Recursive functions that check the same base condition both before and after the recursive call
  3. Recursive functions that don't test for a base condition
  4. Recursive subroutines that concatenate/sum to a global variable or a carry-along output variable
  5. Apparent confusion about what to pass as the parameter in the recursive call, or recursive calls that pass the parameter unmodified
  6. Thinking that the number of iterations is going to be passed as a parameter

Remedies

Get your feet wet and be prepared for some stack overflows. Begin by writing code with only one base-condition check and one recursive call that uses the same, unmodified parameter that was passed. Stop coding even if you have the feeling that it's not enough, and run it anyway. It throws a stack-overflow exception, so now go back and pass a modified copy of the parameter in the recursive call. More stack overflows? Excessive output? Then do more code-and-run iterations, switching from tweaking your base-condition test to tweaking your recursive call until you start to intuit how the function is transforming its input. Resist the urge to use more than one base-condition test or recursive call unless you really Know What You're Doing.
Your goal is to have the confidence to jump in, even if you don't have a complete sense of "where you are" in the imaginary recursive path. Then when you need to write a function for a real project you'd begin by writing a unit test first, and proceeding with the same technique above.

5.难以看透递归

递归的思想很容易理解,但程序猿们经常在自己脑子里想象一次递归操作的结果时遇到困难,或想不通一个简单函数是怎么计算出复杂结果的。这些不解使得要设计一个递归函数变得难上加难,因为当你要对初始条件或递归调用的参数进行测试时,你想象不出“当前走到哪一步了”。
特征
  1. 对问题设计极其复杂的迭代算法,但其实可以通过递归解决(比如:遍历一个文件系统树),尤其是在不用保证内存和性能的情况下。
  2. 递归函数在递归调用前后都会检查相同的初始条件。
  3. 递归函数没有测试初始条件。
  4. 递归子程序连接到一个全局变量或支持输出的变量上,或者累计这些变量的和。
  5. 对于递归调用中要传递什么参数表现出明显的困惑,或是不理解传递未修改参数的递归调用。
  6. 认为迭代的次数会被作为参数传递。
补救措施
先体会一下,准备好迎接某种堆栈溢出吧。首先,在代码里只写一个初始条件检测并只调用一次递归,递归中使用同一个被传递的未修改参数。即使你觉得写得不够好也要停下来,无论如何,让代码运行一下。它抛出了一个堆栈溢出的异常,那么现在返回去继续写,在递归调用中传递参数的已修改拷贝。产生了更多的堆栈溢出错误?输出过度?那就接着反复修改代码再运行,从修改初始条件测试转向修改递归调用,直到你开始凭直觉就知道函数怎么转换它的输入参数。忍住冲动,使用的初始条件测试或递归调用不要超过一次,除非你真的知道自己在做什么
你的目标是勇于进行递归调用,即使在这条想象中的递归路径上,你没有完全搞清楚“自己在哪里”。那么,等你需要为一个真正的项目去写一个函数时,你会从写单元测试开始,并且运用上面提到的相同技术来一步步推进。

2. Lack of critical thinking

Unless you criticize your own ideas and look for flaws in your own thinking, you will miss problems that can be fixed before you even start coding. If you also fail to criticize your own code once written, you will only learn at the vastly slower pace of trial and error. This problem originates in both lazy thinking and egocentric thinking, so its symptoms seem to come from two different directions.
Start with a book like Critical Thinking by Paul and Elder, work on controlling your ego, and practice resisting the urge to defend yourself as you submit your ideas to friends and colleagues for criticism.

Once you get used to other people examining your ideas, start examining your own ideas yourself and practice imagining the consequences of them. In addition, you also need to develop a sense of proportion (to have a feel for how much design is appropriate for the size of the problem), a habit of fact-checking assumptions (so you don't overestimate the size of the problem), and a healthy attitude towards failure.
Finally, you must have discipline. Being aware of flaws in your plan will not make you more productive unless you can muster the willpower to correct and rebuild what you're working on.

4. Unfamiliar with the principles of security

Symptoms

  1. Storing exploitable information (names, card numbers, passwords, etc.) in plaintext
  2. Storing exploitable information with ineffective encryption (symmetric ciphers with the password compiled into the program; trivial passwords; any "decoder-ring", homebrew, proprietary or unproven ciphers)
  3. Programs or installations that don't limit their privileges before accepting network connections or interpreting input from untrusted sources
  4. Not performing bounds checking or input validation, especially when using unmanaged languages
  5. Constructing SQL queries by string concatenation with unvalidated or unescaped input
  6. Invoking programs named by user input
  7. Code that tries to prevent an exploit from working by searching for the exploit's signature
  8. Credit card numbers or passwords that are stored in an unsalted hash

Remedies

The following only covers basic principles, but they'll avoid most of the egregious errors that can compromise an entire system. For any system that handles or stores information of value to you or its users, or that controls a valuable resource, always have a security professional review the design and implementation.
Begin by auditing your programs for code that stores input in an array or other kind of allocated memory and make sure it checks that the size of the input doesn't exceed the memory allocated for storing it. No other class of bug has caused more exploitable security holes than the buffer overflow, and to such an extent that you should seriously consider a memory-managed language when writing network programs, or anywhere security is a priority.
Next, audit for database queries that concatenate unmodified input into the body of a SQL query and switch to using parameterized queries if the platform supports it, or filter/escape all input if not. This is to prevent SQL-injection attacks.
After you've de-fanged the two most infamous classes of security bug you should continue thinking about all program input as completely untrustworthy and potentially malicious. It's important to define your program's acceptable input in the form of working validation code, and your program should reject input unless it passes validation so that you can fix exploitable holes by fixing the validation and making it more specific, rather than scanning for the signatures of known exploits.
Going further, you should always think about what operations your program needs to perform and the privileges it'll need from the host to do them before you even begin designing it, because this is the best opportunity to figure out how to write the program to use the fewest privileges possible. The principle behind this is to limit the damage that could be caused to the rest of the system if an exploitable bug was found in your code. In other words: after you've learned not to trust your input you should also learn not to trust your own programs.
The last you should learn are the basics of encryption, beginning with Kerckhoff's principle. It can be expressed as "the security should be in the key", and there are a couple of interesting points to derive from it.
The first is that you should never trust a cipher or other crypto primitive unless it is published openly and has been analyzed and tested extensively by the greater security community. There is no security in obscurity, proprietary, or newness, as far as cryptography goes. Even implementations of trusted crypto primitives can have flaws, so avoid implementations you aren't sure have been thoroughly reviewed (including your own). All new cryptosystems enter a pipeline of scrutiny that can be a decade long or more, and you want to limit yourself to the ones that come out of the end with all their known faults fixed.
The second is that if the key is weak, or stored improperly, then it's as bad as having no encryption at all. If your program needs to encrypt data, but not decrypt it, or decrypt only on rare occasions, then consider giving it only the public key of an asymmetric cipher key pair and making the decryption stage run separately with the private key secured with a good passphrase that the user must enter each time.
The more is at stake, then the more homework you need to do and the more thought you must put into the design phase of the program, all because security is the one feature that dozens, sometimes millions of uninvited people will try to break after your program has been deployed.
The vast majority of security failures traceable to code have been due to silly mistakes, most of which can be avoided by screening input, using resources conservatively, using common sense, and writing code no faster than you can think and reason about it.


1. 不断学习
程序员的学习从Google开始。一遇到问题就求助于同事的程序员不仅会让正在紧张工作的同事感到反感而且还易养成依赖的坏毛病。正确的解惑姿势应该是擅用身边最大的资源器——搜索引擎,它检索的出来的信息远比你周围的同事能提供给你的多得多。

不断接受新的技术。程序员是一个非常残忍的职业。你所学所用的语言、框架、模式,很可能在数年内就成昨日黄花了。所以除了技术的深度之外,想成为优秀程序员的你还需要重视技术的广度,C语言、Java、PHP、C++、Perl….总之,越大越好。

阅读大量别人的代码。提升编程技能的一个鲜为人知的方法就是阅读大量别人编写的代码,吐槽的同时边阅读边思考:如果换成我应该如何编写这部分代码?这段代码是否还有可优化的空间?如何优化?这项技术如何应用在我过去已经编写的代码中?

2. 突发事件处理
斑斑一向认为如何处理bug、崩溃、调优、入侵等突发事件是比编程本身更能考验程序员能力的,也是一般程序员和优秀程序员的根本差距所在。当面对一个未知的问题时,你如何抽丝剥茧地分析问题的潜在原因、如何一点一点的排除干扰项找到问题的本源、如何选择最合适的解决方案,都是衡量一个程序员是否优秀的重要标准。一个优秀的程序员会用尽一切方法让事情前进。
3. 重视代码注释
如果你看自己三个月前写的代码,也许你能够凭借自己写代码的习惯和记忆中这段代码的运行结果而想明白当初自己为什么要这么写,但如果你看的是自己三年前写的代码,恐怕就没有这么好的运气了,这个时候你就需要注释来帮忙了。优秀的程序员不止代码是优秀的,注释也同样。简洁的代码配上详尽的注释,完美的简直不要不要的。
4. 学会与人沟通
沟通无处不在,而且不可避免,一个优秀程序员的沟通绝不是简单的和策划、产品经理讨价还价,而是善于运用沟通的技巧更精确的表达出自己的立场。斑斑一直认为沟通也是编写代码的一部分,沟通出问题势必会影响代码的编写质量,使最终的呈现结果出现瑕疵。立志成为优秀程序员的你绝不会被区区沟通所打败,不是吗


5. 习惯优化代码

“代码能跑”可不是优秀程序员编程的终极目标,编程人员工作的第一步就是编写出符合要求的代码,但这也仅仅只是第一步而已。作为一名优秀的的程序员,你需要经常性地进行代码优化,把自己编写的代码当成是一件艺术品,精益求精。如果真的有让你忍无可忍的代码,麻烦请重构。

6. 热爱分享

7. 社区意识

https://blog.fundebug.com/2018/01/17/coding-in-the-night
Deliberate practice,即刻意练习,强调的就是训练方法。如果方法不够科学,训练再久也没用。这次,我不聊具体的训练方法,而只想强调一点:Practice must be focused。如果写代码的时候不能保持专注,一直被打断的话,代码质量可能都有问题,更谈不上刻意练习,也就不能有效提高编程技能。
于是,我做了一个艰难的决定:晚上写代码。做决定往往比做事情更痛苦,这次也不例外,这事比想象中有意思多了:
  • 没有外界打扰,至少不需要和同事或者用户沟通,可以更加专注;
  • 在家里,环境和心情更加放松,可以稍微健身一下,洗个澡,来点饮料和水果,再开始写代码;
  • 夜深人静,思路更加清晰,至少我是这样的;
现在,我每天晚上大概会写1~2个小时代码,工作量不会太多,但是对代码质量的要求会更高。对我而言,晚上写代码更多的是练习编程技能,而不是单纯为了完成工作任务。这样,我会花更多时间去思考:如何写出更好的代码?如何提高编程效率?哪些是我的知识盲点?至少我会写更加全面的单元测试
我挺喜欢写代码的,因此每天可以多写点代码的话,感觉还是很不错的。白天工作的时候,也可以更加从容一些,不再因为写代码的事而焦虑。
并不一定非得晚上写代码,重要的是你应该在找到合适的时间段,专注地练习,这样才能真正有所提高。


Thursday, March 24, 2016

Lessons Learned in Software Development



http://usersnap.com/blog/developers-lessons-learned/
8. Test first, release often.
11. Learn how to code no matter how old you are.
12. Learn how to say “No”
13. Follow other developer’s practices
I think the main thing there is just to use it – to practice and to get better at it, and to follow not so much the technologies but the practices that people are exploring. Staying on top of current practices at this point is really more important for us than technology.
14. Don’t be afraid to remove features of your product
http://henrikwarne.com/2015/04/16/lessons-learned-in-software-development/
1. Start small, then extend.
2. Change one thing at a time.
3. Add logging and error handling early.
4. All new lines must be executed at least once.
5. Test the parts before the whole.
6. Everything takes longer than you think.
7. First understand the existing code. 8. Read and run.
TROUBLESHOOTING
9. There will always be bugs.
10. Solve trouble reports.
11. Reproduce the problem.
12. Fix the known errors, then see what’s left.
13. Assume no coincidences. When testing and troubleshooting, never believe in coincidences. You changed a timer value, and now the system restarts more often. Not a coincidence. A new feature was added, and an unrelated feature becomes slower? Not a coincidence. Instead, investigate.
14. Correlate with timestamps. When troubleshooting, use the timestamp of events as a help. Look for even increments. For example, if the system restarted, and a request was sent out around 3000 milliseconds before, maybe a timer triggered the action that lead to the restart.

COOPERATION

15. Face to face has the highest bandwidth. 16. Rubber ducking. Whenever you are stuck, go to a colleague and explain the problem to them. Many times, as you talk, you realize what the problem is, even if your colleague doesn’t say a word. Sounds like magic, but works surprisingly often.
17. Ask. Reading and running the code is often great for figuring out what it does and how it works. But if you have the possibility to ask someone knowledgeable (perhaps the original author), use that option too. Being able to ask specific questions, and follow-up questions to those, can give you information in minutes that would otherwise take days to get.
18. Share credit. 

MISCELLANEOUS

19. Try it. 
20. Sleep on it. 
21. Change. 
22. Keep learning. 
Get your priorities right. Implement essential features before playing with the more interesting, but expendable nice-to-haves.

  • Get your priorities right. Implement essential features before playing with the more interesting, but expendable nice-to-haves. I used to have a dynamically editable upload form with zebra striping and all, implemented as a generic JavaScript component. Very cool and fun to code. But the actual upload functionality wasn’t implemented for a week.
  • Try to write reusable, abstract code, but don’t go over the top. Your code should survive minor specification changes, but it doesn’t have to withstand a complete overturning of the project’s purpose. You’re not building a nuclear shelter. Before you go into developing a cool library completely decoupled from the rest of your code, pause for a while and try to assess what are the odds you will ever need this functionality somewhere else.
  • Don’t use technical terms in user interfaces. Normal people don’t understand them. Be prepared to name interface elements in a way that seem illogical to you.
http://home.hiwaay.net/~taylorc/software/development/lessons/
  1. Write it down!
  2. It's one thing to know you need documentation and peer review. It's another to know why. Without the latter, your application of the former will be useless.
  3. Without a clear description of the software requirements, not only does the developer not know when he's completed his task; he also can't possibly know that he hasn't completed it.
  4. Apply established standard formats for documentation rather than relying on ad hoc formats.
  5. Disastrous results can occur in an electric circuit when electrons follow the path of least resistance. The same thing can happen to a software product when developers are told to do the same.
  6. Following the path of least resistance eventually makes that path more resistant than the path of due diligence.
  7. Aggressively pursue opportunities to improve the architecture of the system.
  8. By forgoing peer reviews, your developers lose opportunities to learn from the successes, mistakes, and experiences of their colleagues. Consequently, your products aren't as robust, efficient, and maintainable as they could be. Read more.
http://www.slideshare.net/thaljef/lessons-learned-about-software-development
Lesson 1: The best code is no code at all.
Open source and commercial products are another good way to avoid code. Despite what you
might like to think, you are not special. A lot of problems have already been solved by people a
lot smarter than you or I. And if their solutions don't seem to fit, then you really need to think
hard and justify why your needs are so different.
Software itself is actually full of code-avoidance mechanisms: subroutines, libraries, object
orientation, web services, virtualization, cloud computing. These all exist for the purpose of not
writing code. Use them.
As developers, it is hard to resist the temptation to write code. That's what we are here for after
all. But that isn't really your job. Your job is to help solve problems in the most effective and
prudent way that you know how. Code is just *one* of the weapons in your problem-solving
arsenal. So think about that before you write your next line of code.

Lesson 2: Code is for humans first, and computers second.
Lesson 3: You Are Not As Smart As You Think You Are.
More importantly, you must learn how to learn effectively. You must question your old
habits, seek alternative perspectives, and acquire knew knowledge. And just as important, you
must act on that knowledge. Otherwise, it is just trivia.

Lesson 4: Software development is 80% social and 20% technical.
The really hard part is figuring out *what*
code to write.
Figuring out what to write requires asking a lot of questions: What is the real problem we are
trying to solve? Which parts of the problem are constant? Which parts are subject to change?
How likely is it to change? Which are the critical features? Which features are fluff? What kind
of resources to we have available? The answers to these questions require conversations with
actual human beings.
So the message here is that to succeed in this industry, your social skills need be just as good
(or even better) than your technical skills. You need to be able to communicate with people and
find out what they really need, how they feel, what their history is, what their goals are, what they
are doing.



Saturday, March 5, 2016

How to be Better Tech Leader



CTO教你如何脱颖而出成为公司里的leader?
争取完成大量工作来赢得影响力

在创业团队,往往人少活多,通过花费大量的时间和精力来完成比别人多得多的工作,就会得到越来越多的机会,从而影响力也会迅速提升。

业务和技术精湛,同事在工作中仰仗你来赢得影响力

业务能力和技术能力是一切个人影响力的支撑。只有能力出众,别人才会服你。如果在工作中总是解决各种难题,帮同事解决问题,问题总是止于你而得到解决。那上级和同事就会越来越仰仗你,你的影响力自然会大幅提升,成为leader也只是时间问题。

危难之际,挺身而出,勇于去接手重任

创业公司往往突发需求特别多,经常会出现新需求来了,没人来接的情况。此时往往大多数人六神无主,束手无策,如果你有足够的信心和胆量的话,那么你就应该挺身而出,临危受命,这是你树立个人影响力的关键时刻。比如一个紧急的需求,你能完美的解决;比如上级紧急的安排,你有条理的完成。这些都是画龙点睛之笔。这需要你平时能提前高质量的完成手上的工作,才有富余的时间来接手更多的任务。

乐于分享,愿意把功劳给别人

如果取得一些成就,受到上级的表扬,要擅于把功劳记在帮助你的人身上,这样才能得到别人的信服。如果学到一些新的技术或知识,能及时的分享给别人,愿意帮助别人一起进步,这样得到你帮助的人会乐意追随你,你的影响力会潜移默化的大幅度提高。

要想建立个人影响力,需要长时间的坚持,才能看到效果,这与产品或企业的影响力是一样的,只有一如既往地给大家反馈同一种积极的信号,时间长了,自然就形成了影响力。

随着创业公司的发展,公司的组织结构也会慢慢的形成,你能管理的团队的大小和项目的多少,会与你在公司的个人影响力成正比。而创业刚开始指派的一些leader,如果影响力缩小,也会慢慢别影响力更大的人替换。所以,从现在开始,请提高你在公司的个人影响力。

http://www.cnblogs.com/archy_yu/p/5243947.html
1:首先是总是丢需求,这一点也是总监跟我说了n次的地方,可是仍旧是在这里犯了n-1次错误;拿最近这个商城来说,因为是基于微信,所以需求中要体现对微信的接口和约束;更要体现如果去管理微信公众号,这块确实是被我忽视了,的的确确的被忽视的,完完整整的丢掉了;而没有这块就无法接入微信,切记切记;后来在读一本书的时候,提到了约束,如果丢掉了约束,可能就会导致最终的产品进行大返工,切记切记。
2: 需求不完整,一些活动的需求,无法形成闭环,或者说有疏漏的地方,这里确实要再文档成型之前,对每一个模块,每一个功能,每一个需求,每一个流程做一个头脑风暴;虽说无法避免疏漏的地方,但是一定要避免无法形成闭环,无法形成闭环,无法形成闭环,重要的事情说三遍,切记!

说说整体架构这块:
1:首先是一定要多视图;因为利益相关者不同,架构设计文档要给到程序,运维,老板,其他架构师等不同的角色看,所以架构设计要从不同的视图来体现,比如给程序的,要从模块划分,层次划分的角度来;给运维的,要从不同机器之前联系的角度来,等等,总之要多视图
2:抛出难题,或者说风险控制,总之把风险全部抛出,分析那个风险最大,那个所需要考虑和投入设计的精力也就最多
3:考虑扩展,考虑分布,考虑负载
4:考虑客户端,这块一直是疏漏,总监也总是提醒我,要多关注些客户端,客户端不可太大,否则加载会很慢,考虑压缩,考虑框架的选取,以轻,稳,简为原则,这块的的确确是疏漏的

我们再说说做计划:
1:可能是对这种javaweb的项目不熟悉,所以最初也就是贾哥给了一个泛泛的计划节点,就是demo版本的deadline;现在熟悉了,切记切记,要做计划做计划,分解计划,做到周计划。
2:根据开发进度调整计划,在实际的开发过程中,常常发现缺界面,丢逻辑之类的事情,虽说可以通过前期需求和设计避免,但是这样又需要在需求分析和概要设计上花费太久时间,所以需要补充的功能之后,要调整计划,调整计划,切记狂加班消耗开发热情。
3:美工的计划要早于开发,工程师在开发任务的时候,切记切记,美工已经把界面给到,这样就需要保证美工的计划要早开发一个星期左右的时间,这样才能保证开发顺畅的进行。


Tuesday, March 1, 2016

How to be Better



https://m.signalvnoise.com/sleep-deprivation-is-not-a-badge-of-honor-f24fbff47a75
http://www.jianshu.com/p/1b8be9a92a79
Stubbornness: When I’m really tired, it always seems easier to plow down whatever bad path I happen to be on instead of reconsidering the route.
  • Lack of creativity: What separates programmers who are 10x more effective than the norm is not that they write 10x as many lines of code. It’s that they use their creativity to solve the problem with a tenth of the effort. The creativity to come up with those 1/10 solutions drops drastically when I’m tired.
  • Diminished morale
Irritability: Your ability to remain patient and tolerant is severely impacted when you’re tired. 

http://katemats.com/7-proven-ways-to-get-more-done-in-less-time/
Planning. 
Prioritization.
Be on time
Be present and focus.
Keep track of everything in one place.
Set deadlines and establish timelines.

http://www.devstore.cn/essay/essayInfo/6147.html
在职场中,并不需要时刻比拼智商,大部分情下,做事认真一点、考虑更深入一点、积极主动一点,已经好于70%的同学了,这样的同学我们都称之为“靠谱”。
获得了合作伙伴包括主管的认可,自然获得的机会就会更多,做的事也会更复杂,合作伙伴也会越来越强,这样就会形成正循环,成长就会比较快。所以前3年需要通过做事形成自己的影响力,积累人脉,锻炼自己的对未知事物的判断能力,因为随着你做的事情越来越多,专业知识能覆盖的范围会越来越小,遇到越来越多自己不懂的领域。你不可能掌握所有知识,因此培养判断力非常重要。包括对事物未知发展方向的判断、事情产生价值的判断,以及对人的判断等。
所谓后3年做人,是更多发挥出人的价值,不仅仅把事做好就行,包括在合适的时间做合适的事。在公司里做先烈的情况有很多,找到多个团队的共同价值点把事情一起做好,其实这个最难,因为越有价值的事情,涉及到的利益方也会越多,平衡好各方的诉求是事情成败的关键。事情做好后还要有人帮你宣传等,这当中可能会涉及人的性格、交际能力、向上管理等综合能力。
善于发现兴奋点
1.发现工作中可以提升效率的地方,可以把琐事的事情工具化,记得当时在做一个搜索需求时,发现传给搜索的参数非常多,而且每次拼URL异常麻烦。因为工具是给运营同学用,所以便做了一个页面,把参数做成表单,运营同学只要在对应的字段(含义有说明)表单中填入值,就可以自动生成最终URL,提升了他们生成URL的效率,也肯定受到了运营同学的好评。
2.除了发现工作中可以提升的效率外,还可以积累人品,比如我们曾经有个小图书馆,借书信息需要一位同学人肉记录,于是我做了个图书管理系统给那个同学用,收获了友谊。
3.除了在主动和积累人品外,最重要的还是要积累技能,我曾把在公司用到的中间件都深入学习一遍,并且写成学习文档,和其他同学写那种简单的使用心得型文档不同,我写的学习文档都是分析设计原理,为什么这么设计,用到了哪些设计模式,关键的技术点等。那些工作几年,对中间件熟悉的同学也会有兴趣来看。但公司的同事毕竟有限,写作文章也会花费不少精力,所以我要寻找新的动力继续写下去。当时我从写公司独有的框架转到写公司内外通用的技术框架,如Spring、iBATIS、Tomcat等JVM技术。并且找机会投到杂志和网站上,一方面有经济回报,另外更重要的是能收到反馈信息。
善于从工作中找到源动力非常重要,做一件事情从不同角度发现其中的价值可以始终保持做事的激情,如果事情做好,可以得到感谢、称赞和认可,获得更多知识。找到正向的反馈,附带获得知识和影响力,然后促使自己持续把事情做好。
写文章和总结有多种好处:
可以系统地沉淀和总结自己的学到的知识,只有经历这样的过程,知识才记得牢。
可以增加影响力,因为分享给别人带来价值,才有人关注你。
给做事增加动力,尤其是那些琐碎的事。如果把琐碎的事情都连接起来,说不定也能收效显著。
与人协作
在与人协作上,这几年我的感触也很深,从最初的想一个人完成所有事,到现在尽量让别人完成所有事,这种转变真是很特别。公司中的大部分事都是团队协作,以公司中常用的项目运作模式为例,一般会有一个项目经理(PM)、一个或者多个架构师,若干个不同功能的开发,其他就是不同的岗位分工,如PD、UED、测试、PE等。PM和架构师两个角色刚好给两个同质的团队利益分配提供了很好的选择,PM一般会拿到业务结果,而架构师能体现这个项目中的技术成果,典型的场景是一个很好的技术通过PM来落地而达到双赢。与人协助上有几个阶段需要经历。

积极主动给老板带来一些惊喜,是你获得更多机会的助燃剂,老板一般喜欢两种人,一种是听话的人,兢兢业业的完成交给的任务;第二种是总有新想法并且爱折腾的人,有想法还不够,最好是有结果。很显然第二种人更容易获得提拨。
适当给老板找些麻烦也有好处,这里所谓的找麻烦有两重含义:
一是,要有自己独立的主见,即当发现明显有问题时还听之任之,只会让老板觉得你没有主见。积极表达自己的观点。当然,这要基于大家都是正直的人,如果你的老板小肚鸡肠,那还是好自为之吧。
二是,尽量不要让老板的认知范围完全覆盖你的认知。如图2所示,如果这样,你在老板眼里就是个透明人,因为你的所有思考和行动都在他的可预知范围内。所以在工作场景中用到的知识深度、广度或者其他技能上你要有所长。比如技能上你擅长前端,或者线上运维非常好,又或者思考问题非常全面,再或者逻辑推导能力很好,图2是一种比较理想的状态。
“当然有种情况也要避免,就是当你掌握的知识如果大于你的老板的话,你可能会觉得老板不如你,但是千万不要忘了,他的推理范围可能还是远远覆盖你,也就是对事情的判断能力,所以也不要过于自大。”

前期精力都应该放到具体的小事上。先以事服人,再以德服人。
你每天90%的注意力,都浪费在了鸡毛蒜皮上

于是一个清晰的事实出现了,浅尝辄止的人很可能将一无所获,而专注投入走到最后的人将获得超额收益。
——采铜《如果你的资源贫乏,那么专注做好一件事将是你的唯一出路》






专注当下从做计划开始
  • 所有事项都要记在一个地方
  • 养成列To do list的习惯后,就把所有要做的东西都记下来
  • 每天记得定时查看,不然一样会忘事
真正有智慧的人从不让手机束缚自己
手机的出现不是让别人随时找到你,而是让别人在“你想让他们找到你的时候”找到你。






想把一件事做精就必定要学会取舍
只关注你生活中
最重要的事情
 很多时候,我们会慢慢变成我们专注的那个人或事。

你是否注意到,结婚多年的夫妻会变得越来越像对方,而在性格上,很多人会逐渐和他们工作的上司、同事甚至是和他朝夕相处的宠物越来越像。

人的精力是有限的,如果你一下操心太多事情,就坚持2-3件你已经开始操心的事情,然后放弃剩下的那些。 
这些放弃不仅包括一些工作和生活上的目标,甚至会包括你长久以来的生活习惯甚至是你的一些人脉关系,但是请你记住,你是在为自己的人生做选择。
为什么大部分人的勤奋是完全无效的
生活中存在一种怪圈,一些埋头苦干,很努力工作的人往往不会混得太好,当然混得也不会太差

他们身上都有一些特质,比如勤奋。这里的勤奋,我指的是埋头苦干,努力工作,少了些活学巧用。

然而,这部分人却很少知道,这些勤奋大多都是无效的。因为太沉迷于执行,而少了些思考。

俗话说“磨刀不误砍柴工”,当你觉得自己很努力了,依然陷入瓶颈期时,脱身出来想想这些点你是否都中枪了?
不会充分利用琐碎时间
(2)全方位调动感官
(3)推荐基本时间管理的书
说多了理论,真正还是需要靠自己去实践。找出适合自己的方式才是王道。

推荐基本时间管理的书,根据理论自己详细规划。

《如何掌控自己的时间和生活》
里面提到一个重要的方法,就是做任务分解,先把大目标分解成小目标。再把任务分成ABC,按优先等级完成。

《番茄工作法》
将工作时间分成小部分,以25分钟为一个单位,当时实践这个理论的时候在iphone上面找到了一个关于番茄工作法的软件,发现实践的非常好。

《拖延心理学》
为你分析拖延的原因,看见我们自身潜意思里的害怕与恐惧。

还有《GTD》、《80/20法则》这类书籍都很推荐。曾经还使用过一些国外的时间管理软件,例如43 Things\Like Tick\Goal Migo\大芝麻......都可以尝试使用。
学习不系统
很多人学习都是粗暴学习法,囫囵吞枣。刷刷知乎大V,看看专业微博文章,就觉得学到了真本事,其实不然。长期接受碎片信息的后果,就是让你的思维变得狭隘,难以进行复杂的思考。

因为这些碎片信息通常具备这样的特征,它们往往大量简化了推演过程,将多路径简化为单一路径,不够严谨、全面。


不专业、不权威
都说跟对师傅很重要,学习也同理,要看经典的图书,跟着专业的老师学,否则再怎么努力都是白费劲。

比如想成为Java 开发工程师就应该跟着浙江大学的翁恺老师学;想学C++就该跟大神级人物侯捷、硅谷技术大牛董飞;学office软件,就应该跟着职场老鸟秋叶......

名师出高徒,加上你的努力与勤奋。学习效果会更好。
不会利用零碎时间、不懂的系统学习,不跟着专业、权威老师学习......这些都是你为什么勤奋却不出成绩的原因。

Winning Habits: 4 Secrets that Will Change the Rest of Your Life
Be first on, last off, and add extra value!
Never trade results for excuses
Solve problems in advance
Always make those around you look good

http://codecloud.net/15199.html#1

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts