您现在的位置是:首页 >技术杂谈 >《这就是软件工程师》- 每位软件工程师值的看的一本书,尤其是刚刚步入IT行业的年轻人网站首页技术杂谈
《这就是软件工程师》- 每位软件工程师值的看的一本书,尤其是刚刚步入IT行业的年轻人
文章目录
第一部分|行业地图
1、现实:为什么会有996?
1)行业处于特定的发展阶段
互联网处于原始积累阶段(圈地运动,谁圈的地多,谁圈的快,谁才会赢)。
2)公司组织管理问题
国内很多组织效率有问题,软件工程师白天工作不停的被打断,杂事一大堆,只能晚上加班。
2、进阶:软件工程师的四大台阶
1)新手阶段【执行力】
上级会明确告知你任务是什么,用什么方法达成什么样的目标,你按照方法一步步去做,保质保量完成。
2)进阶阶段【设计能力】
上级给你布置任务,不会告知你如何去做,你需要把具体问题抽象、拆解,并独立设计解决方案。
3)高手阶段【融会贯通能力】
你不仅要看到系统从过去到今天是怎么变化的,还要看到外界哪些需求、内部哪些技术导致了这些变化,并且预判系统未来要朝什么方向发展。你需要把技术的演进、需求的变化、系统的发展等多个维度综合起来考虑。
4)大神阶段【沉淀方法论和开创新领域能力】
大家都公认你是行业的权威,你能够沉淀出一个方法,这个方法不只适用于当前的领域,别人把你这套东西拿过来,还可以解决另外的问题。
3、周期:是否存在35岁的坎儿
35岁危机更多和能力、水平相关,如果能力到了,年龄就不是问题,但如果能力不到,到35岁就可能面临淘汰的风险,也可能到不了35岁就会被淘汰。(性价比要高)
1)如何达到资深工程师水平?
- 拥有思考、总结、抽象的能力
- 需要持续学习、保持进步的心态
这个行业不存在真正年龄的坎儿,只存在能力的坎儿。
社会一定会把重担交给30-40岁这群人,这群人必须变成中坚力量,没什么好选的。如果你接不住这个重担,一定会掉队,可一旦接住了,35岁不是坎儿,反而是你事业发展的高峰期。
2)怎样才能接住重担,成为中坚力量?
做出贡献:为公司带来资源、吸引人才、带来效益、提供更好、更简单有效的方法和创意。
带动团队:能够自驱为公司和团队制定方向和实施计划,并能够解决执行时的所有问题。
创新优化:提出小而美的创新,并推动和执行。
前瞻能力:感知行业变化,技术潮流,思考行业和公司未来,做好准备。
探路能力:只要方向没问题,即使没有路,也能蹚出路来。
解决难题:带动团队解决一切拦路虎。
提高标准:发现不足并弥补,解决问题,提高标准。
降本增效:降低成本(金钱、时间、人力、物力),提升效率(人效)
防火能力:能够发现重要问题,并提前解决,避免意外发生。
如果在公司按部就班的工作,听命做事的人,很容易会被替换掉。
4、挑战:持续学习是刚性要求
软件工程师对于持续学习的要求,几乎是所有职业中最高的,如果不能够持续学习,很容易被甩在后面。
你必须与时俱进。真的是逆水行舟,不进则退,你如果不能前进,肯定会被淘汰。你如果想入软件工程师这一行,就得有这个心理准备。
5、趋势:软件工程师即将遍布各行各业
各行各业都有软件开发部门,软件会成为各行各业的基础设施,软件工程师也会成为各行各业的基本人才配置。
可能一两代人之后,孩子们从小学习编程,软件行业会消失,因为所有人都会做。
第二部分|新手上路
进入软件工程师这一行的,主要有两类人:科班出身的毕业生和半路出家的转行者,无论是哪一类人,都要有一下几个方面的基本储备
入门编程语言推荐:JavaScript、Python
入门必学编程工具:编程工具VSocde
正式入门编程语言:Java
其它:数学和英语
1、选择平台:去面向未来、技术驱动的公司
1)这家公司的做的事情,能不能适应未来的发展
计算机于互联网的发展都太快,如果要选择,一定优先选走在未来航道上的那些快速发展的公司。因为高速成长的公司需要人才,它需要解决的问题也是新的。
2)去的这家公司是不是一家技术驱动、以技术文化为主导的公司
如果一家公司不崇尚技术,对软件工程师的成长完全不重视,你进去干几年,像钉子一样只会干很窄的一个领域的事情,沉淀不下什么东西,后期的发展就会非常受限。
2、认识自己:找到适合自己的路线
兴趣:兴趣是再难再累都不会放弃的事情,不怕困难,痴迷其中,就算没有特长,你也是头部人才。
**方法:**如果没有特长和兴趣,就要学习方法,比如学习时间管理、学习做计划、学习统筹、学习总结犯过的错误,举一反三,学习探究事物之间的因果关系等。
**勤奋:**如果你前面都没有,你还能做的事就是勤奋。勤奋注定会让你成为一个比较劳累的人,也是很有可能被淘汰的人。随着你的年龄越来越大,你的勤奋会变得不值钱。因为年轻人会比你更勤奋,比你斗志更强,比你要钱更少。
知识都是死的,只要不怕困难总有一天会懂的。最可怕的是畏难,为自己找借口。
3、公司差异:即使没有规范,也得自我要求
有没有规范,已经有什么样的规范,跟每家公司的文化高度相关,这一点新人们要做到心中有数。
公司之所以要花时间、精力制定规范,是为了:
- 确定标准、提高效率;
- 整齐划一,工作效率才高(你的代码我能改,我的代码你也能改),协同起来没有障碍;
- 提升标准,才能做出更好的东西,给用户更好体验以及更强竞争力。
一套完整的规范包括三方面:
1)编码规范
- 代码评审
- 单元测试
代码规范推荐书籍:《代码大全》、《代码整洁之道》、《重构:改善既有代码的设计》
2)设计规范
- 接口规范
- 设计模式
- 架构规范
设计规范推荐书籍:《设计模式:可复用面向对象软件基础》、《架构整洁之道》、《微服务设计》
3)生产规范
生成规范是一套标准化上线的流程
生产规范推荐书籍:《人月神话》、《持续交付:发布可靠软件的系统方法》
4、优质代码:好代码没有止境
优质代码可以分为三个等级:
1)初级:可读
- 命名好,好的命名是有语义的
- 布局清晰,分支尽量少,不要用太多嵌套
- 注释明确,为什么用这段代码,怎么用这段代码
- 一个文件或一个函数的代码量不要太大
- 代码不要重复;不要有反逻辑
2)中级:可拓展
一段代码写出来不是一成不变的,它要根据需求的变化而变化,面向对象和函数式的各种设计模式,都可以让你的代码达到这个级别。
3)高级:可复用
写出的代码可以重复使用在很多场景里。
请记住,好的代码没有止境,如果不追求好的代码,你就只是一个“代码操作员”。
5、整洁代码:不是写出来的而是读出来的
不是写的人说自己的代码整洁就算整洁,而是读的人觉得整洁才算整洁。
整洁代码的核心:你心理要装着将来要阅读这段代码的人,从方便阅读的角度去布局、设计。
6、代码注释:像说明书一样清晰
代码注释不仅仅要说明这段代码是什么,也要说明什么时候、怎么样使用以及注意事项。
7、编程原则:教科书没有告诉你的“为什么”
软件工程师要坚持的编码原则:
1)避免重复原则
把雷同或相似的片段想办法提取出来,抽象成一段独立的代码,然后用这一段代码解决多种问题。
2)单一职责原则
一个类或者一个模块应该且只有一个职责,也就是各司其职。
3)高内聚、低耦合原则
内聚:一个模块内各个元素彼此结合的紧密程度
耦合:让每一个模块做到独立,做到精益求精,同时把模块间的耦合降到最低,不会因为动了一个模块,而导致其他模块出问题。
8、全面思考:做测试比写代码难
1)单元测试
单元测试是离着问题最近的地方,离问题越近,解决问题的成本越低。
2)功能测试
一个功能是由很多个单元模块组装起来的,如果这些单元模块没有很好的配合在一起,互相矛盾,那整个功能也就不能正常实现了。
3)集成测试
集成测试是模块和模块之间或者系统和系统之间的测试。
4)非功能测试
是用户不直接关心,但开发者要关心的部分,比如:性能测试、安全测试、稳定性测试、健壮性测试、破坏性测试、可用性测试、灵活性测试等等。
5)回归测试
回归测试是把以前做过的测试以及犯过的错误再测一遍,主要目的是确保代码或配置的修改、需求的增加不会影响现有的功能。
9、阅读代码:重要的不是写代码,而是读代码
对于新人来说,重要的不是写代码,而是读代码。读代码是一种有益的精进方式。
读代码要点:
1)被反复使用的代码,要重点研究,看看它好在哪里。
2)穿越时间的代码,如果一段代码用了10年及以上都没被淘汰,说明设计思想很棒
3)好调试的代码,如果有些代码你调试起来非常顺手,大概率是因为写代码的人为你准备好了基础工具,比如:日志、可回溯、测试方面的东西。
好的代码读的越多,你能摸到的门道就越多,你能快人一步获得成长。
10、潜移默化:和优秀的人一起工作
和厉害的同事在一起工作,对一个人的成长帮助更大,别人身上解决问题的方法和能力,会潜移默化地成为你的一部分,和他们在一起,你基本上不会掉队。
第三部分|进阶通道
1、设计程序:学会谋篇布局
软件工程师必须考虑到整个系统的方方面面,从框架到模块到细节,一旦软件工程师缺少全面思考问题的能力,漏掉某些方面,就会出问题。
软件工程师更多的需要的是谋篇布局、思考总结的能力,到这个阶段,就要有一定的独立思考的能力,别人给你一个问题,你要给出合理的、科学的解决方案。
2、高度抽象:设计需要抽象能力
原型设计一般是面向用户的,相当于提前打个样,原型只是一个简单演示,比如:演示一个订餐系统里的界面长什么样,怎么加购物车等等。
架构设计一般是面向开发人员的,相当于一份详细的施工蓝图,包括:概要设计、详细设计、技术调研,架构师需要做好抽象和分解,画出整个程序的流程图,明确程序由哪些模块组成,它们之间是什么逻辑关系,等等。
3、高度抽象:设计需要抽象能力
1)考虑系统的异常情况
假设任何环节都会出现问题,出现异常,基于这种假设,去做更周全的架构设计,我们需要知道每个异常出现后应该怎么解决。
2)考虑系统的极限情况
提前考虑这个系统最大能承受多大的流量,在发生一些极限情况时,系统会怎么反应。
4、技术调研:寻找最优解决方案
1)技术调研做的好不好,和阅读代码的能力高度相关。
代码读的越快,意味着你的搜索能力越强,越能快速定位自己想要的东西,技术调研也类似。
2)分析优缺点,结合场景才有效
5、软件工程:不同的开发模式
1)瀑布开发模式(传统开发模式)
一层一层地开发,先需求分析,产出需求文档,再做概要设计、技术选型等,接着做详细设计,事无巨细的梳理流程和细节,最后是编码、测试、上线。
2)敏捷开发模式
把任务拆解成一个个小模块,拆的越细约好,接着让每个团队(甚至每个人)负责其中一块,大家根据协议并行开发,最后拼在一起。
敏捷开发的特点是:不需要一直做到很完整的程度再上线,而是做一点发一点,小步快跑,快速迭代。本质是化繁为简。
3)班车模式(火车头模式)【目前使用的最多的一个开发模式】
每周(比如每周三)发布上线一次,如果你做的功能赶得上就跟着一起发,赶不上就等下一班。
一个需求从提出到开始,三周后必须发车(上线),与此同时,每一周都会有一个版本发出去(相当于每周发一趟车)。这周发的车,实现的是三周前的需求;下周发的就是两周前的需求;下下周发出的是一周前的需求,以此类推,需求是并行实现的。
4)分布式微服务开发模式(DevOps开发模式)
把代码库、数据库全部分开,每个服务都由一个全功能的小团队(前端、后端、开发、测试、运维、产品)来负责,这样就可以吧一个大部门拆分成多个小分队,让代码更容易维护和上线。
6、外部沟通:知道怎么“规训”业务
1)不要把技术仅仅当做需求解决方
业务如果只是把技术当做需求解决方,得到的就是被动的技术团队,而如果真正把技术当做解决问题的参与方,技术的主观能动性就能被调动起来。
2)不要将需求丢给技术,而是要告诉技术真正想解决的核心问题是什么
有时候业务提出的需求并不是真正的需求,他只是给了技术团队自己认为的解决方案,要求技术去实现。但是业务真正想解决的核心问题,可能并不是用这个方案能解决的,或者这个方案不是最好的。如果业务能把自己想解决的问题告诉技术,那么技术就会一起来想办法,还可能会想到更好的方法。
3)今天我们面临的所有问题都不是单纯的技术问题,大家一起努力,才能从根本上解决问题
明确哪些需要技术解决,哪些需要业务解决。
总之,技术只有知道如何和业务沟通,才能把需求实现好。
7、内部协作:平衡前台团队和中后台团队
内部团队目标不一致,团队之间的诉求不一样,就很容易发生矛盾。这时候,就需要大家相互理解,理解对方的诉求是什么、真正的痛点在哪里。
8、直击内核:打牢基础,以不变应万变
计算机行业总会传很多新东西,变化无处不在,怎么学习新技术?怎么跟上新变化?要相应对变化,很重要的一点叫以无招胜有招,以不变应万变。因为变化都是表面的东西,内在的东西其实变化不大。所以要应对变化,你一定要打牢自己的理论基础,提升内功修养,比如编程的一些方式、解耦、提升代码复用等。
你必须学习基础的理解知识,如果只学一些表面上的解题思路和方法,技术的形式一变化,你会发现以前学的都没用了,要从头再学一遍。
技术基础包含以下四类:
1)程序语言
- 语言的原理
- 类库的实现原理
- 设计模式
- 编程技术(并发、异步等)
2)系统原理
- 计算机系统
- 操作系统
- 网络协议
- 数据库原理
3)中间件
- 消息队列
- 缓存系统
- 网关代理
- 调度系统
4)理论知识
- 算法和数据结构
- 数据库范式
- 分布式系统
9、主动学习:提高你的学习效率
主动学习我们称之为深度学习,如果你不能深度学习,你就不能真正学到东西。
因此要想更高效地学习,你必定要经历一个从被动学习到主动学习的转换过程。对软件工程师来说,写博客、做分享都是很好的主动学习的方式。
如果你关注求件工程师的各大论坛就会发现。“做技术还是做管理”、“35岁了还不管人,是不是就晚了”、“天天熬夜敲代码有没有前途”这类问题被讨论的非常多,这是因为软件工程师走过进阶阶段以后,需要往高手阶段发展,这个时候恰恰是最容易卡壳的节点。
一方面,每个人都面临着“做技术还是做管理”的选择:如果一直做技术,自己能够做到顶尖吗?遇到技术难题怎么解决?如果选择做管理,团队怎么带?任务怎么分?内部合作出问题了怎么办?当这些问题一股脑儿摆在你面前,难免会有迷茫和纠结。
另一方西,高手不是想做就能做的,很多人代码写得好,也会独立设计程序,但一到重大问题的决策上,一遇到技术难题就无所适从。这是因为,要想在高手阶段做得游刃有余,你需要融会贯通的能力,比如你要做一个技术决策,就得想到这个决策不仅要解决当下的问题,还要考虑几年后可能发生的情况,你需要对行业可能朝着什么方向发展有一个预判;再比如你要对现有的系统进行重新布局,就得想清楚自己做什么、不做什么,要解决什么问题、不解决什么问题,说到底,你需要在一个复杂的系统里做预判和取舍。做不好这些,难以成为高手。
第四部分|高手修养
1、上升通道:技术路线和管理路线
技术路线 指的是在特定的技术领域做深入的探索和研究。
管理路线 更侧重系统筹团队完成一个个研发项目。
到了高手阶段,很多软件工程师会纠结,究竟是走技术路线,还是管理路线?你待在一个做产品的公司,它一定会给你技术、管理两条晋升通道。你如果喜欢做技术就一直做技术,你喜欢做管理就去做管理。
2、预见未来:软件工程师要有前瞻能力
1)你一定要有知识的广度,需要去读论文,读业内各大公司的资料,还要去各个公司做广泛的交流,保证有足够多的不同的信息进入你的视野。
2)多做跨行业的交流,跳出自己的圈子,跟其他行业的人交流,特别是投资人、创业者等见多识广的人群。
3、高手重要的事情:攻克技术难题、技术决策、代码评审
1)攻克技术难题
技术难题之所以难,是因为情况复杂,没有通用的解决办法,唯一通用的是保持一个好心态,你需要尝试不同的技术解决方案,需要做好失败的准备,很多技术难题是没法解决的,在攻克难题是,想方设法尝试不同的方案是最重要的。
2)技术决策(技术选型)
- 这项技术解决的是不是大问题(格局更大的问题)
- 技术解决问题的方式是否让人有想象空间(一种可以干很多事情的感觉)
- 有没有大公司撑腰
- 有没有很好的技术社区
3)代码评审
代码评审就是Code Review,就是对代码从头到尾把别人写的代码审一遍,看看有没有需要改进的问题。
做不做代码评审,直接关系到代码的工程水平,所谓的“工作忙”“时间不够”“需求总变”,不是拒绝评审的理由,如果业务很紧,让技术人员疲于奔命,那应该是需求管理和项目管理的问题。
代码评审需要关注的方面
- 设计:代码是否经过精心设计并适合系统
- 功能:代码是否符合开发者意图
- 复杂性:代码是否可以更简洁
- 测试:代码是否经过了自动化测试
- 命名:代码命名是否规范
- 注释:代码注释是否清晰有效
- 风格:代码是否遵循了相应的代码规范
- 文档:开发人员是否同步更新了相关文档
4、实力服众:工程师宁愿被leade,不愿被manage
在软件工程师的领域,只懂管理,不懂技术或技术不够牛,基本上是不可行的。这个行业对管理者的独特要求在于,你的技术得足够牛,如果不能证明你有一定的技术水平和素养,下面的同学就会不服。
5、敢于放手:从工程师变成管理者
刚成为管理者时,你要按捺住,要克服和适应,要做好思想的转变,之前你想的都是怎么让自己变得更好,现在你要做的是怎么样让其他人更好,怎么样让团队变得更好。
6、招聘面试:考查一个人的元能力
从技术角度不能只看技术管理者所在的公司是不是牛,规模大不大,还要关注他所在的公司的业务模式对技术要求的复杂度和挑战性到底有多高。
在招聘时除了要看候选者简历上的经验,更重要的是评选候选者的一些元能力,看他工作过程中沉淀出了哪些基本素质,哪些可以持续拥有的能力。比如系统设计、代码的结构化,通过分析找到关键问题,这都是元能力的体现。
7、团队建设:做好人才布局
管理者不仅要从专业上给下属指导,还要在工作中有倾向性地培养下属,关注他们的发展,并做好人才布局(把每个人放到合适的位置上)。
8、布局长远:关注长期目标
管理者在推进当前业务需求的同时,也要布局未来更有效的解决方式,平衡好短期目标和长期目标。
具体怎么做呢?
**首先,**管理者需要判断,哪些事情需要长期投入,做了之后能产生规模效应。
**其次,**管理者要坚定地投入到长期目标上,之所以强调坚定,是因为眼前的事情太多,一不小心,长期的项目就半途而废了。
因此,技术管理者要在完成短期目标的同时,时时刻刻要记住长期目标的推进。
9、协同机制:保持公开透明的信息协同
谷歌大到公司的战略,小到每个人每周做了什么、写了什么代码,大家都是互相看得到的。只要感兴趣,你可以去看任何人的信息:目标是什么,完成了什么,写了哪些代码、哪些设计文档,都是完全透明的。
设计文档是公开的,你想要找什么东西,搜一搜就能看到,大家可以相互讨论,整个体系都非常自动化。
鼓励公开透明的协作,让大家把自己做的东西工具化、开源化,让所有人都能看到和使用就很重要。
10、合作共赢:找到利益共同点
很多技术人员在协作上很容易出现大家各干各的,互不支持。如果你讲清楚这件事的厉害,现在的投入是为了更好的解决未来可能出现的更严重的问题,找到双方利益的共同点(比如:去理解对方的KPI),就可以更好地进行协作。
在团队协作中,管理者要对其他团队的诉求有深入的了解,找到利益共同点,有目的的推进,合作就会顺畅很多。
第五部分|行业大神
软件工程师这一行,大神级的人物层出不穷,他们每个人对世界都做出了巨大的贡献。这些大神级的软件工程师要么沉淀出了自己的一套方法论,供后辈学习;要么打破常规,开创出一个个全新的领域,是行业内灯塔一般的人物。这些人以超凡实力改变了我们的世界,是每个软件工程师学习的榜样。
1、丹尼斯· 里奇:保持简洁
里奇是“C语言之父”,也是UNIX系统的联合发明人。
保持简单和直接,这就是著名的KISS原则。
KISS( Keep It Simple, Stupid)原则——保持简单,愚蠢。
KISS原则使代码简单、清晰、易于理解。编程语言是为人类所理解的,所以保持编码的简单和直接,让人类理解。保证你的方法尽量很小;每个方法都不应该超过40-50行代码。
每个方法应该只解决一个小问题,而不是实现很复杂的功能。如果你在方法中有很多条件,把它们分解成更小的单独的方法。它不仅更易于阅读和维护,而且可以更快地发现bug。
违反KISS原则
我们都经历过在项目中由于一些糟糕的代码,需要大家努力加班解决问题。“既然我们可以只用2-3行就完成同样的事情,他们为什么要写这些不必要的行和条件呢?”
2、林纳斯· 托瓦兹:只是为了好玩
林纳斯· 托瓦兹是“Linux之父”,发明了GitHub。
在林纳斯· 托瓦兹的世界里,只有好玩和不好玩的事,没有值得和不值得的事。
3、吉多· 范罗苏姆:允许不完美、保持开放
吉多· 范罗苏姆 “Python之父”
设计原则:
- 不必担心性能,必要时再来优化
- 别追求完美,“足够好”就是完美;
- 有时可以抄近道,尤其是在你之后能改正的情况下。
4、玛格丽特· 汉密尔顿:拯救人类登月计划
玛格丽特担任阿波罗登月计划的软件编程部部长,负责制订一套应急预案,一旦飞船出现问题,就启动这套应急预案。2次的飞船事故,通过玛格丽特编写的上传到事故飞船,化解了2次人类登月计划的失败和事故,两次绝境之下的拯救,显示了她的超凡实力。
最后值的一提的是,玛格丽特是第一个提出了软件工程师的称呼,所以现在程序员们也才有了软件工程师的称号。
5、杰夫· 迪恩:开创分布式系统
今天我们看到的整个云服务运用的分布式存储、分布式计算,以及一些硬件、网络技术,都是基于迪恩的分布式系统方向产生、蓬勃发展的。
6、法布里斯· 贝拉:一个人就是一支队伍
贝拉的成就横跨软件工程师的各个领域,比如:QEMU、FFmpeg、TinyC、QuickJS等。如今,将近50岁的贝拉依然奋斗在编程一线。