关注、星标公众号,直达精彩内容

知乎作者:刘贺

整理:技术让梦想更伟大 | 李肖遥

计算机科学有两类根本问题。

一类是理论:算法,数据结构,复杂度,机器学习,模式识别,等等等。

一类是系统:操作系统,网络系统,分布式系统,存储系统,游戏引擎,等等等等。

理论走的是深度,是在追问在给定的计算能力约束下如何把一个问题解决得更快更好。而系统走的是广度,是在追问对于一个现实的需求如何在众多的技术中设计出最多快好省的技术组合。

搞ACM的人,只练第一类。像你这样的更偏向于第二类。其实挺难得的,但很可惜的是第二类能力没有简单高效的测量考察方法,不像算法和数据结构有ACM竞赛,所以很多系统的苗子都因为缺少激励和正确引导慢慢就消隐了。

所以比尔盖茨才会说,看到现在学编程的人经常都把编程看作解各种脑筋急转弯的问题,他觉得很遗憾。

做系统,确实不提倡“重复发明轮子”。但注意,是不提倡“重复发明”,不是不提倡“重新制造”。恰恰相反的,我以为,系统的编程能力正体现在“重新制造”的能力。

能把已有的部件接起来,这很好。但当你恰好缺一种关键的胶水的时候,你能写出来吗?当一个已有的部件不完全符合你的需求的时候,你能改进它吗?如果你用的部件中有bug,你能把它修好吗?在网上繁多的类似功能的部件中,谁好谁坏?为什么?差别本质吗?一个开源代码库,你能把它从一个语言翻译到另一个语言吗?从一个平台移植到另一个平台吗?能准确估计自己翻译和移植的过程需要多少时间吗?能准确估计翻译和移植之后性能是会有提升还是会有所下降吗?

系统编程能力体现在把已有的代码拿来并变成更好的代码,体现在把没用的代码拿来并变成有用的代码,体现在把一个做好的轮子拿来能画出来轮子的设计蓝图,并用道理解释出设计蓝图中哪些地方是关键的,哪些地方是次要的,哪些地方是不容触碰的,哪些地方是还可以改进的。

如果你一点不懂理论,还是应该学点的。对于系统性能的设计上,算法和数据结构就像在自己手头的钱一样,它们不是万能的,但不懂是万万不行的。

怎么提高系统编程能力呢?

土办法:多造轮子。就像学画画要画鸡蛋一样,不是这世界上没有人会画鸡蛋,但画鸡蛋能驯服手指,感受阴影线条和笔触。所以,自己多写点东西吧。写个编译器?渲染器?操作系统?web服务器?web浏览器?部件都一个个换成自己手写的,然后和已有的现成部件比一比,看看谁的性能好,谁的易用性好?好在哪儿?差在哪儿?为什么?

更聪明一点的办法:多拆轮子

多研究别人的代码是怎么写的。然而这个实践起来经常很难。原因:大部分工业上用的轮子可能设计上的思想和技术是好的,都设计和制造过程都很烂,里面乱成一团,让人乍一看毫无头绪,导致其对新手来说非常难拆。这种状况其实非常糟糕。所以,此办法一般只对比较简单的轮子好使,对于复杂的轮子,请量力而行。

轮子不好拆,其实是一个非常严重的问题。重复发明轮子固然是时间的浪费,但当轮子复杂而又不好拆的时候,尤其是原来造轮子的人已经不在场的时候,重新发明和建造轮子往往会成为无奈之下最好的选择。这是为什么工业界在明知道重复发明/制造轮子非常不好的情况下还在不断重复发明/制造轮子的根本原因。

程序本质是逻辑演绎的形式化表达,记载的是人类对这个世界的数字化理解。不能拆的轮子就像那一篇篇丢了曲谱的宋词一样,能读,却不能唱。

鄙人不才,正在自己研究怎么设计建造一种既好用又好拆的轮子。您没那么幸运,恐怕是等不到鄙人的技术做出来并发扬光大了。在那之前,多造轮子,多拆好拆的小轮子,应该是提高编程能力最好的办法了。

知乎作者:ze ran

懂得取舍。

在有限的时间内,几乎没有系统可以做到完美。要快,要安全,高并发,易扩展,效率高,容易读,高内聚,低耦合...

大到一个网站,小到几个class,工程师都要清楚,要取什么,舍什么,这并不是那么容易的事。我们都有自己的性格,有的求新,有的求稳,有的求快,但具体到一个项目时,知道如何取舍对这个项目最好,很重要。

学校里的作业,没人在意你是不是写在一个大的main()里面,能跑就行。但做项目的时候,太多的东西要考虑,有时候,宁可简单易读,也不用快那么一点点;有时候,要做太多看不到的工作,却丝毫马虎不得;有时候,写了不如不写,留白也是一个学问。

曾经接手个项目,里面几乎所有的class,每个都有interface,各种继承,各种实现,理由是灵活性高,易扩展。真的易扩展吗?

我不知道。没多久,客户的需求就改了,各种拎不清的继承实现都化为乌有,一大半要重写。

问题在哪里?

不是编程不好,而是取舍的不好。在那个阶段,为30%的需求,花200%的努力,追求设计的滴水不漏,却舍弃快速实现,取得反馈的时机,这就是失误。需求总会变,客户看到越早,修改越早,影响越小。

很聪明的人,也可能做出很难用的系统,不一定是编程不好,可能是不愿,或不屑于取舍。不同的阶段,不同的项目,要取舍的东西也不同。编程只是手段,目的是解决问题,能力高不高,要看问题解决的好不好。不在于使用了什么高端算法,或是复杂的框架。

懂得如何取舍并不容易,需要对问题的深刻理解,对技术的胸有成竹,和身后无数个踩过的坑。但重要的是有取舍的意识,主动思考取舍什么,这样学的才会快。

知乎作者:家飞猫

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。

编程能力是一种运用机器解决问题的能力。首先是要判断问题在什么程度上可被机器解决,比如理论计算机科学会告诉我们什么可做、什么理论上不可做、什么理论上可做实践上不可做。然后是让机器更好地理解问题,比如计算机都是(图灵-冯诺依曼模型)等价,但不同的问题可能会适用不同的编程语言。再后是让机器能更高效率地解决问题,比如同样的问题可能会有效率差别巨大的算法。

编程能力是一种抽象问题的能力。借用轮子是很好的办法,省力省时间。今天任何软件工程师都会有意无意地使用很多轮子,从操作系统编译器数据库网络到算法数据结构。想高效地借用轮子,就需要将问题分解再分解,抽象再抽象。任何一个实用的系统(不包括教科书上的示例程序和简单的脚本程序)都需要进行大量的分拆和组合。所以系统设计是编程能力里的高级技能,加合理的假设简化问题尤其有难度,此处不展开讨论。高手和新手的区别在于新手往往不知道轮子的适用范围,而高手的手上轮子数量多且熟知各种轮子的差异,所以对不同的问题可以轻松地找到合适的轮子,当实在找不到合适的轮子时可以自己动手改造现有的轮子。平时有时间拆装和改造已有的轮子会对水平提升有较大帮助。当然能知道怎样快速在搜索引擎里搜出轮子也是一种能力。

编程能力是一种需要考虑扩展性的能力。算法竞赛中的很多算法考虑的是单机的内存算法,计算模型经过高度抽象,在实践中机器的模型更为复杂。比如单机的多级结构带来的各种时间空间复杂度的取舍平衡,多机网络中如何能在提高单机性能外进一步优化整体性能。除了在机器端的扩展,在程序员一端的扩展也很重要。复杂的问题和工程往往意味着团队协同以及更长时间的开发维护,团队分工和设计沟通这里暂且不论。举个容易被忽视的例子,程序中的注释。高手会更在意完整且表达清楚的注释,因为这是写给现在和未来的团队(包括自己和其他成员)看的,直接影响到长期的整体开发维护效率。

编程能力是一种取舍的能力。局部的最优解未必是全局的最优解。如果一个美妙的解决方案需要将完工时间向后推迟一两个月,需要考虑是否先使用平凡方案解决问题,之后再进行优化。当你的工作延后会阻碍别人的工作时尤其如此。发现一个绝妙的优化方案时先想想这个优化是否真的有价值,如果只是系统中很小的部分,那么不要为了追求心理满足而花很多时间放一个漂亮的轮子上去(参考Amdahl定律)。

编程能力是一种预见未来的能力。目前的方案有哪些假设和局限性,在何种情形下会遇到问题甚至崩溃。在未来出现问题时问题是否需要重新定义,系统是否需要重新设计,代码是否需要重构或优化等等都需要未雨绸缪。

编程能力是一种工程能力。无它,唯手熟尔。

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。

编程能力是一种解决问题的能力。如果问题没能被很好地解决,知道再多也没用。

(重要的事情说三遍,重要的事情说三遍,重要的事情说三遍)

版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

关注我的微信公众号,回复“加群”按规则加入技术交流群。
点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

​什么才算是真正的编程能力?相关推荐

  1. 什么才算是“真正的”编程能力?不提升这些能力,你何时能拿高薪!

    真正的编程能力,两个词概括: 建模+实现   建模能力如何提高?关键在于分析问题 理解越深,预测能力越强,自己的智慧才越好发挥.这就是学习软件编程最快的方式之一 "造轮子" --造 ...

  2. 蓝桥杯 算法提高 编程求解根号3 进行数学运算是计算机的主要能力,利用计算机的重复计算能力可以帮助人们求解一些十分复杂的数学运算,比如高次方程、求根,求平方等。根号运算是数学的基本运算,对于无理数

    问题描述 进行数学运算是计算机的主要能力,利用计算机的重复计算能力可以帮助人们求解一些十分复杂的数学运算,比如高次方程.求根,求平方等.根号运算是数学的基本运算,对于无理数的求解,我们可以使用两边取值 ...

  3. 编程能力如何突飞猛进?

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自:深度学习与计算机视觉 学编程的小伙伴最大的愿望估计是有一 ...

  4. 总结-软件工程师 ( 编程能力 )

    总结-软件工程师 ( 编程能力 ) 软件工程师编程能力前言 /* 编码现状 */ 程序猿现状: 现项目不是白做的,的确知道怎么写代码,怎么做出一个界面,怎么发起一个网络请求... 仅此而已了.不知道如 ...

  5. 程序员的编程能力层次模型

    编程技能层次 编程技能层次,指的程序员设计和编写程序的能力.这是程序员的根本. 0段-非程序员: 初学编程者,遇到问题,完全是懵懵懂懂,不知道该怎么编程解决问题.也就是说,还是门外汉,还不能称之为&q ...

  6. 程序员编程能力7个能力提升阶段分析

    前言 程序员的编程技能随着经验的积累,会逐步提高.我认为编程能力可以分为一些层次. 百牛信息技术bainiu.ltd整理发布于博客园 下面通过两个维度展开编程能力层次模型的讨论. 一个维度是编程技能层 ...

  7. 我的编程能力从什么时候开始突飞猛进

    点击上方"大鱼机器人",选择"置顶/星标公众号" 福利干货,第一时间送达! 本文源于知乎回答,文末点击阅读原文,即可查看原问题,以下为原文. -正文- 在啃掉一 ...

  8. 让你编程能力秃飞猛进的好习惯

    分享自己写代码时的好习惯,让你的编程能力突飞猛进! 大家好,我是鱼皮,上回说到,很多同学在学编程时不注重代码质量,养成坏习惯的同时,失去了提升自己编程能力的机会. 还没读上篇文章的同学,请先阅读:劳资 ...

  9. 怎样才算是好程序员?关于好程序员与好代码的杂谈

    ​ 怎样才算是好程序员?​ · 具有优秀的技术技能,能写出干净整洁的代码. · 具有扎实的开发技术知识和解决问题的专业技术. · 了解编程的最佳实践以及何时使用它们. · 对编程有着持久的热情,并积极 ...

最新文章

  1. 解决流程自动化“最后一公里问题”,达观数据发布智能 RPA
  2. 13张图彻底搞懂分布式系统服务注册与发现原理
  3. 课堂练习----二维数组
  4. 剑网3 最新服务器,《剑网3》各服务器IP及所在地
  5. Java Web之会话管理二:Session
  6. 介绍10款常用的JAVA测试工具
  7. 一打开excel表,总提示有4.0版的宏
  8. 比较有深度的博客收藏
  9. 半自动化运维之服务器信息维护
  10. hbase常用命令及操作
  11. 任务管理器已被管理员禁用win10
  12. 你还没掌握超表「视图」, 难怪觉得数据繁杂得要命!
  13. 计算机启动太慢的原因是,电脑启动慢的原因分析
  14. Android 如何在关于手机界面添加个图片
  15. [转载]使用 Apache OpenJPA 开发 EJB 3.0 应用,第 4 部分: 实体关联
  16. Notepad++查看二进制文件——HexEditor插件
  17. 湍流系数计算器_粘性流体在圆管内湍流时传热系数计算公式与在线计算器_三贝计算网_23bei.com...
  18. 春招进行时,当代大学生求职行为大赏
  19. MATLAB学习笔记:非齐次线性方程组的求解
  20. 软件验证(Verification)和确认(Validation)的区别

热门文章

  1. Druid sql injection violation, part alway false condition not allow
  2. UVa 1586 -- Molar mass
  3. URL不受支持的解决
  4. UCOSII系统时间管理
  5. 浏览器[包含360浏览器]输入框自动填充问题
  6. BIM 360 Glue API: 用cURL或PostMan实现登陆和获取项目列表的功能
  7. 在国内和国外读设计的差异有哪些?
  8. 前端开发人员转行的职业推荐:13个就业方向
  9. (建议收藏)计算机网络:Ip组播与IPv6协议习题详解与拓展
  10. T7314 yyy的巧克力(钟)