20年来作为软件工程师学到的20件事

原文: 20 Things I've Learned in my 20 Years as a Software Engineer - Simple Thread

注意:请先阅读此内容

即将展现的是一篇包含大量建议的 blog ; 向前人学习对成功至关重要,但是,我们常常忘记另外一个重要警告: 几乎所有的建议都是上下文相关的, 但是,很少对上下文提供细节;

"你需要收取更多费用!" 这经营了20年的公司说, 多年以来收费"太低",无法赢得客户并取得成功;

"你需要将一切构建为微服务!" 该公司表示, 构建了一个快速的整体,获得了数千客户,然后,在开始遇到问题时, 全面转向了微服务;

如果不了解上下文, 建议就毫无意义,甚至更糟糕,有害; 如果那些人早点听从他们自己的建议,他们自己可能会因此受苦; 对于任何建议很难逃脱这个陷阱; 我们可能是我们经历的终点,但是,我们却是通过现在的镜头来观察;

因此,为了让你了解一下这些建议的来源,特此说明: 我在职业生涯的前半段担当软件工程师,为各种小型企业和初创公司工作, 然后,我进入咨询行业并在许多非常太的企业工作; 最后, 我开创了 Simple Thread, 我们从一个2人团队成长为一个25人的团队; 10年前, 我们主要和中小型企业合作,现在我们和大型和小型企业合作;

我的所有建议来自于:

  • 几乎总是在小而精干的团队中,我们必须用很少的资源作很多事情
  • 重视工作软件而不是特定工具
  • 一直在开始新项目,同时还要维护一些系统
  • 重视工程师的生产力,超过其它大多数考虑因素
  • ...

我过去20年的经历塑造了对软件的偏见, 并使我形成了一些信念; 我试图将这些信念压缩为一个易于使用的列表, 希望你能发现她们的价值;

建议清单:

1. 我仍然懂的不是太多

"你怎么不知道 BGP ?"

"你从来没听说过 Rust?"

我们大多数人都被人这么说过, 而且可能听的太频繁了; 我们中许多人喜欢软件的原因就是因为我们是终身学习者, 在软件领域, 无论你从哪个方向看, 都有广阔的知识前景向各个方向发展, 而且每天都在扩展; 这意味着即便你在职业生涯中度过数十年, 但是, 和同样在看似相似的角色中度过数十年的人相比, 仍然存在巨大的知识差距; 越早意识到这点, 就能越早开始摆脱 "顶替者综合症" , 转而乐于向他人学习和教导他人;

2. 软件最难的部分是构建正确的东西

我知道在这点上算陈词滥调, 但是, 大多数软件工程师并不相信的原因是, 他们认为这在贬低他们的工作; 我个人认为这是无稽之谈; 相反,这突出了我们必须工作的环境本身复杂性和不合理性, 这故居了我们的挑战; 你可以设计出世界上技术上最令人印象深刻的东西, 然后, 却无人愿意使用; 这种事儿一直在发生; 设计软件主要是一种倾听活动, 我们经常不得不成为竕软件工程师, 部分通灵师, 以及部分人类学家; 投资在这个设计过程, 无论是通过专门的 UX 团队, 还是通过简单的自我教育, 都将带来巨大的回报; 因为, 你如何计算构建错误软件的真正成本? 这不仅仅是损失工程时间...

3. 最好的软件工程师像设计师一样思考

伟大的软件工程师会思考他们代码的用户体验; 他们可能不会用各种术语来考虑, 而是考虑应该是外部API/编程API/用户界面/协议还是其它任何界面; 伟大的工程师会考虑谁将使用, 为什么要使用,如何使用, 以及这些对用户来说什么是最重要的; 牢记用户的需求, 确认是良好用户体验的核心;

4. 最好的代码是没有代码,或是你不必维护的

我只想说: "码农只能编码"; 你问任何行业的人如何解决问题, 他们都会在他们擅长的领域犯错误; 叫只是人性; 大多数软件工程师总是会在编写代码时出错, 尤其是当非技术解决方案不明朗时; 你不必维护的代码也是如此; 当很多轮子已经存在时, 工程团队很容易想要重新发明轮子; 这是一种平衡行为, 有很多理由让你自己再来一遍, 但是, 要提防这种 "没在此现实"(“Not Invented Here”) 综合症;

5. 软件是达到目的的手段

任何软件工程师的主要工作是交付价值;

很少有软件开发者理解这一点, 将其内化的就更少了; 真正将其内化后, 能导致解决问题的不同方式, 以及观察工具的不同方式; 如果真真的相信软件是从属于结果的, 你就会准备好找到真正"适合的工具", 有时可能根本不是软件;

6. 有时你必须停止磨锯,直接开始砍屎

有些人倾向于跳入问题, 并立即开始编写代码; 其它人往往想要研究和陷入硬件分析进而瘫痪; 在这些情况中,为自己设定一个截止日期, 然后, 开始探索解决方案; 当你开始解决问题时,你很快能学习到更多, 这也将引导你迭代到更好的解决方案;

7. 如果你不能很好的理解所有可能性, 就无法设计出好的系统

这是我一直在努力解决的问题, 因为, 我的职责使我在软件工程的日常工作中越来越远; 峎上开发者生态是一项巨大的工作, 但是,了解什么是可能的至关重要; 如果你不了解给定生态中有什么是可能的,以及什么是可用的, 那么你将发现除了最简单的问题之外, 不可能设计出一个合理的解决方案来解决所有问题; 总而言之, 要警惕那些很长时间没有编写任何代码的架构专家;

8. 每个的了了的都很糟粕,克服丫的

Bjarne Stroustrup 有句名言: "只有两种语言: 人们抱怨的语言, 和没人使用的语言";

这也可以拓展到大型系统; 没有"正确"的架构, 你永远无法偿还所有技术债务, 你永远无法设计出完美的界面, 你的测试总是太慢; 这不是永不让事情变得更好的借口, 而是一种给你观点的方式; 少担心优雅和完美; 相反, 努力持续改进并创建一个你的团队喜欢在其中工作, 并可以持续创造价值的宜人系统;

9. 无人问足"为什么"

抓住任何机会质疑"作事方式"的假设和方法; 有新人加入嘛? 注意他们在哪里感到困惑以及他们在问什么问题; 有没有无意义新功能请求? 确保你了解目标以及是什么推动了对这一功能的渴望; 如果你没有得到明确的答案, 请继续问为什么, 直到你明白为止;

10. 我们应该更专注于避免0.1x 程序员,而不是寻找 10x 程序员

10倍速程序员是一个愚蠢的神话; 某人可以在1天里生产出另外一位有能力/勤奋/有类似经验的程序员需要在2周以内生产代码的想法是愚蠢的; 我见过程序员编写10倍的代码, 然后, 你必须修复它10倍以上的次数; 某珍爱可以成为10倍程序员的唯一方法, 是将他们和 0.1 倍速程序员进行比较; 有人浪费时间, 不寻求反馈, 不测试代码, 不考虑边缘情况等等...

我们应该关心让 0.1 倍速程序员远离我们的团队, 而不是寻找神话般的 10 倍速程序员;

11. 高级工程师和下级工程师间最大的区别之一是他们已经形成了对事情应该如何发展的偏见

没有什么比对他们的工具或是如何构建软件没有有意见的高级工程师更让我担心的事儿了;

我宁愿有人给有强烈的反对意见, 也不愿他们完全没有意见; 如果你正在使用你的工具,而且你还没有更多喜欢或是讨厌的情绪, 那么, 你需要更多体验; 你需要探索其它语言/库/范例; 没有什么比积极寻找其它人如何使用和你不同的工具和技术来完成任务更快提高技能的方法了;

12. 人们并不是真想创新

人们经常谈论创新, 但是, 他们通常寻找的是廉价的胜利和新奇; 如果你在真正的创新, 并想改变人们作事的方式, 那么大多数情况下都会收到负面反馈; 如果你相信自己在作的事儿, 并知道确实会改善事情, 那么为自己的长期战斗作好准备;

13. 数据是你系统中最重要的部分

我见过很多系统, 其中希望数据完备性是系统主要机制; 在这种系统中, 任何在黄金路径之外发生的事情,都会心产生部分脏数据; 将来处理这些数据将是一场噩梦; 请记住, 你的数据可能会比你的代码要长寿; 花精力保持数据秩序和清洁,从长远看会有好的回报;

14. 寻找技术鲨鱼

仍然存在的旧技术是鲨鱼而不是恐龙; 他们解决问题能力如此之强,以至在技术世界不断发生的快速变化中幸存下来; 不要和这些技术打赌, 只有在有充分理由的情况下才负担它们; 这些工具不会华而不实, 也不会令人兴奋, 得是不是, 它们能在没有很多不眠之夜的情况下完成工作;

15. 还要把谦逊误认为无知

有很多软件工程师除非被直接问到, 否则不会发表意见; 永远不要认为仅仅因为有人没有将意见扔到你面前, 他们就没有什么可以补充的; 有时, 最吵闹的人是我们最不想听的; 和周围人交谈, 寻求他们的反馈和建议; 你会庆幸你这么作了;

16. 软件工程师应该定期写作

软件工程师应该定期写 blog/日记/文档, 通常作需要他们保持书面沟通技巧的事儿; 写作可以帮助你思考问题, 并帮助你能更有效的和团队以及未来的自己沟通; 良好的书面沟通是任何软件工程师都必须掌握的最重要技能之一;

17. 尽可能保持流程简洁

现在每个人想想变得敏捷, 但是,"敏捷"就是以小块的方法构建事物/学习/然后迭代; 如果有人试图在其中塞入更多东西, 那么,他们可能只是在卖东西; 这并不是说人们不需要问责或是帮助以便用这种方式协作, 但是, 你有多少次听到你最喜欢的科技公司或是大型开源项目成员有吹嘘他们的 Scrum 流程有多NB? 保持精益过程, 直到你知道你需要更多; 相信你的团队,他们能交付成果;

18. 软件工程师和所有人一样,需要有主人翁精神

如果你将某人从他们的工作成果小分离出来, 他们就会更彡关心他们的工作; 我认为这几乎是必然的; 这是跨职能团队作的如此出色, 以及 DevOps 变得如此流行的主要原因; 这不仅仅是关于交接和效率低下, 而是关于从头到尾拥有整个过程, 并且是直接的负责交付价值; 让一群充满激情的人完全拥有设计/构建和交付软件(或任何东西)的权利, 惊人的事情就会发生;

(译注: 当然, 得是有意义的事务, 为领导一些幻想去努力很难有什么主人翁精神能触发)

19. 面试对于告诉某人将成为团队成员有多赞,几乎毫无价值

面试最好花在了解某人是谁, 以及他们对特定专业领域的兴趣程度上; 试图推测他们将成为多么优秀的团队成员是徒劳的; 相信我, 一个人有多聪明或是多博学也不能很好的证明他们将成为一名优秀的团队成员; 没有人会在面试中告诉你他们不可靠/爱辱骂/自负或是从不准时参加会议; 人们可能会声称他们对这些事情有"信号"... "如果他们在第一面试时询问请假,那么他们永远不会去请假!" 但是, 这些都是废话; 如果你使用这种信号, 只是在猜测并拒绝优秀的候选人;

20. 始终努力构建一个更小的系统

有很多力量促使你预先构建更大的系统; 预算分配, 无法测定应该精减哪些功能, 希望提供系统的"最佳版本"; 所有,这些事情都非常有力的推动我们构建更多; 你应该阻止这个; 你在构建一个系统时学到了很多东西, 你最终将迭代到一个比你最初设计的系统更好的版本; 令人惊讶的必须, 这对太多数人来说是难以接受的;

你的故事呢?

这是全部了, 20年的软件生涯提炼出来的的20条精辟断言;

如果有什么能引发你的共鸣, 我很很听听; 我也很想知道你在职业生源中积累的智慧并愿意分享出来; 请在评论中留言吧;

refer.

关键参考

很有人不同意所有观点: January 25, 2023 at 7:25 pm

Hard disagree with most of the 20 items.

  1. Writing software is difficult, tedious and needs real work. No silver bullet libraries, no methodology, no framework, no IOT, no amount of unit tests will get the work done faster.

  2. Developers collect tools, libraries and pet technologies and make projects go over their time and budget by doing it.

  3. Code should encapsulate algorithms and not be structured other wise. Code should follow the business logic and be readable and match business requirements easily.

  4. Forgetting history keeps the productivity and industry down. Microsoft re-discovering the same old technology which existed on 1960s mainframes for the 7th time just to sell products, trademark buzzwords, training, certification and everything is an anchor around the modern developer’s neck. Think file transfer -> X12 -> serial communication -> raw socket packets -> corba -> xml soap -> xml http -> Rest JSON http -> gRpc as a 50 year journey of rediscovering the same thing repeatedly, each not really that much better than the older technologies, wrapping mounds of interlarded crud on top of fragile, hard to program libraries and the square peg in a round hole mismatch.

  5. Refusing to hold W3C and large tech companies accountable for not fixing web HTTP, HTML, CSS and JavaScript for 25+ years. – How can I create a control which has HTML, CSS, JS which has encapsulated CSS, encapsulated HTML, encapsulated JS without a 10,000 file framework? – How to match HTML DOM elements with JS without using quoted magic strings? Quoted magic strings were proven anti-productivity and anti-quality in the 1960s – How to have a UI without the everything is a call back and function pointer? Function pointers with modern wrappings are just as bad as the 1060s computed jump to function tables

  6. Forgetting that tech is a business with a 7 year hype cycle, with the new thing being embryonically hyped for 2 years by cutting edge bloggers, then 2 years by sales marketing of companies, then 3 years of disappointment for companies trying to implement it. Followed by, abandonment when the ROI does not work out. Resume driven development, just for business persons. And yes, there’s a new hype every 2 years to waste time and money on

  7. Not holding tech companies accountable when they release major products, .net core, which have less than a 5 year full support lifecycle. Long term support .net is under 3 years. That is a forced upgrade every 3 years for every .net system just to pass the IT auditors at a large company

  8. Devaluing your own worth and work as a developer by telling everyone that the proposed product/task is easy. Software dev is hard work, less than 1 of a 1000 people can even do it poorly. I would not go to a brain surgeon that told everyone that what he does is easy.

  9. Forgetting that software development is a hard, tedious, isolated job where people desiring lots of human interaction will rapidly leave the field by their own choice and lots of people not getting into the field by their own choice.

  10. Not telling people that you as a developer have to say “No, it’s too expensive” or “No, it’s too risky” as a regular part of your job. Persons not developing software treating you poorly with career ending consequences just because you won’t accept the death march cross to bear of impossible requirements of an impossibly short deadline

  11. Not helping your fellow developers out. Speak well of your co-developers, team, and industry. Don’t downplay the difficulty, complexity or contribution of software.

  12. Not calling people out when they think that more data, metrics for everything will automatically solve problems. Ask for a business case, ask for the questions they want to answer (in written form), get the business case and questions they want to answer from the requestor, make sure they are approved before committing to a tight deadline

  13. Not damaging the next developer on your project – too many technologies, framework of the month, just another nuget package, one more class, have another 3 patterns, data on disk, data in database structure and consistency is not important and, yes, this system will never receive/send upstream/downstream data

  14. Accepting code without parameter checking, error handling or in-line comment documentation (cough vendor’s happy path ‘doc’ page or cough signature only documentation with no example code or error handling.)

  15. Misguided acceptance that best practices are best and not just a short nicely sized blog entry. Best practices, in many cases, do not scale for large 1,000,000+ line of code systems and make maintenance harder.

  16. Not challenging the ‘more technology is better’ approach

logging

版本记要

  • ..
  • 230201 ZQ init.
            _~∽&`~_
        \) /  ◷ ◴  \ \/
          '_   V   _'
          \ '--.--' \

...act by ferris-actor v0.2.4 (built on 23.0303.201916)

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可;-)