17 软件设计能力:工程师的核心竞争壁垒
你好,我是李云。这一讲我们来聊一聊工程师的竞争壁垒。
从我们进入职场开始,职业安全就是一个让人敏感的关注焦点。比如,35岁年龄焦虑就是一个老生常谈的话题,时不时撩动着人的神经。可年龄焦虑还没解决,人工智能焦虑又来了,以ChatGPT为代表的人工智能技术在2023年取得突破性进展的同时,程序员要失业了的声音尘嚣甚上。
当然,每个人都会被社会淘汰,只是时间早晚的问题。担心职业安全的同时,我们不禁要问,如何构建自己在职场的竞争壁垒,让自己被社会淘汰得慢点呢?
为了避免讨论时太发散,我得提醒下,这一讲是从专业技能的维度去展开的,毕竟个人的职业竞争壁垒是一个多维度且相当复杂的话题。另外,专业技能是靠手艺吃饭的工程师最关心的方向。
依我看,有这么两大原因导致了工程师的职业安全焦虑。第一,年轻的工程师每年一批批进入职场,我们拿什么来与精力旺盛、学习能力强的他们竞争。第二,人工智能这类新技术的出现,我们应如何看待和应对。
不过啊,这两个都是外因,咱也控制不了,没有办法消除它们来解决自己的职业安全焦虑问题。是的,个人的职场竞争壁垒一定是从内因下手才对,构建一种能力让我们能应对外因的到来。
竞争壁垒在哪
既然竞争壁垒是一种能力,那这种能力一定是行业所需才行,否则就会出现一拳打在棉花上的感觉。那工程师在行业最稀缺的是什么能力呢?注意我加上了“最”这个字,因为“最”才意味着更有价值和更持久。
16讲咱们聊到布鲁克斯的一个观点,他指出软件开发活动由根本任务和次要任务组成。进一步我总结为,根本任务是“软件设计”,次要任务是“编码”,所以我们会有“软件开发 =k × 软件设计 + 编码”这个公式,其中k是远大于1的系数,以便体现软件设计是根本任务。如果从能力视角来解读这个公式,那么我们可以得出,软件设计能力才是行业最稀缺的能力。换句话说,软件设计能力是工程师的核心竞争壁垒。
你想啊,软件开发活动的关键是要解决现实问题,这就需要我们根据纷繁复杂的现象和需求,通过抽象和洞察化繁为简。
先来说说抽象能力。抽象动作的背后,需要咱有良好的概念能力才行。说到概念能力,估计你想到了16讲中所聊到的,它也是工程师软件设计能力背后所需要的核心能力。
软件设计能力之所以能成为工程师的竞争壁垒,是因为背后所需的概念能力需要花很多时间来培养,无法速成。因为它不仅涉及到信息和知识的累积,还包括对这些知识的深入理解和应用能力。概念能力涵盖了从基础概念到复杂问题的抽象和概括,以及在不同情境中灵活运用这些概念的能力。
为了帮助你理解为何概念能力无法速成,我总结了以下三条。
- 对复杂概念和系统的深刻理解需要时间。我们需要在实践中反复应用这些概念,从而深化理解。
- 经验积累需要时间。概念能力往往与个人的经验紧密相关,通过经历不同的项目、挑战和失败,我们才能更好地理解和应用抽象概念。
- 思维模式的转变需要时间。发展概念能力,通常需要我们改变和扩展现有的思维模式,这种转变并非一蹴而就,而是随着时间和经验的积累逐渐完成的。
说完抽象能力,接下来咱来说一说洞察能力,或简称为洞察力。洞察力通常指对现象或问题深刻而敏锐的理解,它涉及快速准确地捕捉到核心问题或隐藏的模式,并能理解背后的深层含义。洞察力是概念能力的一部分,但更侧重于直觉。
就概念能力和洞察力,我简单总结一下。概念能力是一种更广泛的认知能力,涵盖了从现象抽象和形成概念的能力;而洞察力则是在此基础上,对特定情境的深入理解和感知。两者共同作用,使个体能够有效地理解和处理复杂的问题,最后做出有洞察力的行为,比如决策、表达观点等。
你可能意识到了,作为一名软件工程师,我们在职业生涯中除了要锻炼自己的概念能力,还得进一步培养自己的洞察力。还有啊,洞察的对象不只是针对产品需求的代码实现,更有用户的需要和行业发展背后的规律等。无论是做技术还是技术管理,洞察力是高级职位所必须掌握的能力。
为了让你对洞察力有更具体的认识,就软件设计我想和你分享我的两个洞察。
第一个洞察是,越复杂的软件,对工程师软件设计能力的要求就越高。因此,我鼓励你抓住机会,参与更大规模软件项目的开发工作。或者,在已参与的软件项目中,承担更大范围的软件维护和迭代演进责任。这些机会都能很好地锻炼咱驾驭复杂软件的能力,锻炼个体的软件设计能力。
第二个洞察是,规模越大的软件,软件设计质量对整个软件产品质量的贡献也越大。下图示例说明了我的这一洞察。
这个洞察能很好地解释为何有些软件再怎么修补,它的产品质量水平都无法提高,因为只要软件设计的质量没有提高,再怎么“贴狗皮膏药”也于事无补。对于那些有一定规模和历史的软件来说,要改变软件设计可不是一件小事,那可以复杂到对整个软件的重新开发。
好,现在咱知道了竞争壁垒是什么,那针对开始提出的两个职业安全问题,我们如何化解呢?
化解职业安全焦虑
我们先来聊第一个职业安全焦虑。年轻的工程师进入职场有一个成长过程,这一点我们初入职场时也经历过了。由于他们的概念能力不如我们,所以没有办法应对复杂任务,需要我们这些有经验的人,运用自己的概念能力,将复杂任务分解成小的任务,再将小任务分派并指导他们完成。
我得提醒一下,此时我们与年轻工程师的关系不是竞争而是共赢。换句话说,我们的立场应是用好他们精力旺盛、学习能力强的特点,一起干出更大的成绩,借事修人,共同成长。你想啊,我们刚入职场时,是不是也希望身边有经验的人也这样待咱呢?
当我们错误地用竞争关系取代共赢,来定义咱与年轻工程师的关系时,很可能就会以提防的心态与他们共事,这其实并不利于发挥集体的力量,最终是双输。还记得11讲中谈到的“知识因分享而增值,因封闭而贬值”这个观点吗?
你可能发现了,应对这个焦虑的办法,是假设你有良好的软件设计能力。或者你可以认为,这就以终为始地告诉了你,个人的专业技能发展,需要一直重视软件设计能力的培养。如果不这样,那一批批年轻人进到职场,就确实会让人很慌。
接下来,我们来聊第二个职业安全焦虑。也就是,人工智能这样新技术的出现,会取代程序员吗?
我的观点是,人工智能目前没有办法取代具有良好软件设计能力的程序员。因为它没有人类所特有的工作、生活经历,很难锻炼出解决现实问题的概念能力和洞察力,只能解决软件开发活动中的次要任务,即一定程度地解决编码问题。换句话说,边边角角的编码工作人工智能是可以胜任的。
如果哪一天人工智能真解决了开发活动中的根本任务,那样的话,布鲁克斯所预言的“没有银弹”也就走到了终点。在我看来,人工智能要真正全面取代程序员,那时的一个前提条件是,人类可以轻松且无缝地将自己的工作与生活经历传递给人工智能。换句话说,脑机结合技术已完全攻克并普及。
你可能会说,现在的人工智能也一定程度能解决软件设计问题啊?即使是,我们别忘了,软件设计是需要不断演进的,我们教人工智能如何演进软件设计,现在看来是一个成本非常高的事。
应对人工智能所带来的焦虑,我们依然要注意自己的格局。学会用好人工智能这个助手,而不是将它当作是自己的竞争者。前者让人工作起来更轻松,后者却只能以失败告终。
哦,前面提到了年龄焦虑这个问题,但并没有正面回答,可能会让你觉得这一讲缺了点什么。我认为,年龄焦虑的背后是对成长慢的焦虑。这与工程师忽视软件设计能力的培养和持续专业化是一回事。
总结时刻
现在让我们梳理一下这讲所学的主要内容。这一讲我们从每位工程师都关心的职业安全聊起,探索了个人专业技能的核心竞争壁垒,从打造核心竞争壁垒的视角来化解对职业安全的焦虑。
软件设计能力之所以能成为工程师的核心竞争壁垒,原因在于背后所需要的概念能力和洞察力是无法速成的,需要花很长的时间去实践、积累、试错才能掌握。此外,软件行业的两个特征,也导致了软件设计能力能成为工程师的核心竞争壁垒。一个是,越复杂的软件对工程师软件设计能力的要求就越高;另一个是,规模越大的软件,软件设计质量对整个软件产品质量的贡献也越大。
基于我对工程师核心竞争壁垒的认识,化解职业安全焦虑的关键在于,工程师应持续提升自己的软件设计能力。当我们有了良好的软件设计能力,就能建立起职业安全的护城河。
最后,再和你唠叨几句心里话。我这么强调软件设计的重要性,花这么大的篇幅来讲软件设计,是因为我看到在行业中真正理解软件设计的人非常少,可以说80%的人根本就没有好好思考过这件事。我以前面试软件开发专家时会问候选人一个问题,“什么是软件设计”。就这一个问题,10个人中有8个会被Pass掉。
太多太多的人会写代码,但思考太少了。真正会关注软件设计的人,就会从美学上看待这份职业。这确实是更高的要求,但也正因如此才能真正构建起工程师的职业壁垒。我们需要真正从软件设计层面来学习和成长,不然很多都是花架子,也确实不会有多大的竞争力。这就好比武功的招式学了很多,可内功没有上去,招式再多也白练。
好了,最后的最后,还是老规矩,我想请你思考,你会如何定义“软件设计”这个概念呢?期待你留言与我分享交流。
我们下一讲见。
- pyhhou 👍(6) 💬(1)
老师说的很好,我也说说自己的理解,还望老师指正。 用一句话来定义软件设计——对需要的场景,制定一套易于理解且稳定的流程或方法。 你可能会说,你说的是不是太简单了,我觉得要做到一点都不简单。这里的重点在于 “需要的场景” 和 “易于理解且稳定”。场景越大,你需要考虑的情况就越多,也越复杂,就像文章中说的,规模越大的项目就越考验设计能力。并且你还要能保证第二点,你设计出来的东西可以很轻易的交给别人,并且别人不需要有过多的经验就可以实现,维护并且拓展。这需要日积月累的经验,之前踩过的坑,碰过的壁,犯过的错都会帮助你设计出更完善的系统,当然还需要你学习解决问题的方法,行业的最佳实践等等,这才能让你设计出来的东西更简单且实用。 那些好的,且历经岁月依然被广泛使用的软件或标准,是不是都很好地做到了这两点?这里举些例子: - TCP/IP 协议 - Unix 系统 - AWS 里的 Java API 接口 想要做好软件设计,需要心中有追求,不能带着完成任务的心态去设计,写程序。要时时刻刻都想着怎样才能把自己负责的部分做到不会出错,又怎样才能让他人非常容易地就理解自己设计出来的东西。并且还要时不时地回过头去想想那些前人总结出来的最佳实践,比如设计模式、编程范式、设计原则等等,不断尝试新的领域,不断经历,不断踩坑,不断犯错,又不断回过头去反思这些方法,你的软件设计能力就会逐步提高了。 Linus 说过,这世界程序员之所有高下之分,最大的区别就是程序员的 “品味” 不一样。是的,软件设计就是程序员的品味,争取做一个有品味的程序员:)
2024-04-23 - 到不了的塔 👍(2) 💬(1)
李老师,你好, 随着微服务的流行, 服务的规模和复杂度都大大降低,这是不是也意味着对软件设计质量的要求也越来越低。如果行业对软件设计质量的要求降低,那软件工程师的竞争壁垒又在哪呢?
2024-04-19 - 极客001 👍(1) 💬(1)
老师您好,我觉得的软件设计是在明确用户需求的前提下对用户需求进行归纳总结,然后确定整体技术架构,最后通过代码一步一步进行功能实现,最终形成一个完整的系统。在系统流程设计中,要站在客户角度进行思考,在满足需求的前提下尽可能将系统的操作设计的简单明了,让用户有一个好的体验,真正便利于客户的工作生活,真正做到科技改变生活。
2024-04-26 - FireMo 👍(1) 💬(1)
软件设计,目的是设计出一个符合业务需求的软件,首先是从业务需求出发,要充分理解需求,然后抽象出概念,基于概念确定功能点,将一个或几个功能组合成模块,从面向对象的角度在模块内部实现高内聚,模块之间的通信实现低耦合;各个模块之间相互隔离。一定要从美学角度出发,设计出让别人看一眼就能懂的软件,后续才能写出让别人一眼就能看懂的代码。
2024-04-22 - 卢泽华 👍(1) 💬(1)
我理解的软件设计就是 给软件里面某些元素(服务、组件、模块、对象、函数)分配职责,也就是这些元素要干什么,然后这些元素如何配合。也就是概念及其关系。软件要应对复杂度和需求的变化,所以就需要对软件元素进行抽象。关键在于如何抽象,抽到哪个层次上,比如把变化原因一样的对象放在一起(单一职责),把变化频率一样的放在一起(也就是分层)。面向对象建模里面也就是名词和动词,有哪些对象(名词),这些对象的职责是什么(动词)。
2024-04-18 - SMTCode 👍(1) 💬(1)
我理解的软件设计是:通过理解项目或产品的需求,对需求进行抽象,选择合适的技术,然后进行拆分,先通过最小原型去验证与需求的契合度和设计的合理性,然后再同过不断迭代,完善项目机能,同时还要考虑如何进行测试和确保质量的方式,在合适的时间对小部分代码进行再拆分和重构,让代码有一个易维护、可扩展的基础底座。
2024-04-18 - java小霸王 👍(0) 💬(1)
软件设计:识别出元素,以及元素之间的关系
2024-05-11