作者:invalid s
链接:https://www.zhihu.com/question/49294784/answer/116205654
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
尤其是偏底层的系统级编程,更是C一家独大,除了C++别无对手。别以为C只能做底层。真正复杂、高难度、对性能有苛刻要求的、支柱性的大项目,C仍然当仁不让、不可替代——我不知道那些说C不适合做项目的,究竟有没听说过linux,看过几个开源项目。C只不过是太贵、所以不值得拿来做那些不值得花大精力深挖机器潜能、也不值得雇佣高级程序员精雕细刻的、堆积木性质的项目罢了——比如所谓的企业开发、比如开发部署一个网站……不过,说到网站……或许你应该了解下apache/ngnix以及mysql等等都是什么写的 ^_^没错。除了那些不上档次的、最为末端的企业及网站类应用外,其它任何领域,业界最好、最顶级的实现,大部分是C的。这就使得,无论你学什么,很容易就能拿到一大堆的C版本的开源例程;尤其是,若要学习真正能决定你将来能走多远的操作系统、数据库、编译器等基础原理方面的东西,更是几乎只有C一个选择。不仅如此。C实现的任何东西,无论是操作系统还是编译器,全都会以赤裸裸的算法+数据结构的面目展示在你的面前。想知道什么,只要从一个API开始跟,很容易就能搞明白——跟一跟某个硬件相关API,甚至可以帮助你准确理解硬件。彻底学通之后,任何技术、任何架构,都能一目了然。简洁直白、案例众多、学习资源丰富,这是C最为独特的优势。所以,虽然想玩好指针之类危险特性并不算特别容易;但,学基础算法本就不需要你玩这些危险特性;稍微学深一点,和其他知识相比,指针又怎么都谈不到难上。反而是C一旦入了门,根本不假他求,很容易就能把整个计算机系统弄的通通透透——除了C,再没有第二种语言能有这么高的投入产出比。指针就是对内存最初步的掌控;连内存都玩不明白还奢谈什么“懂计算机”。
事实上,除了对面向对象的直接支持以及内置的内存回收机制等东西外,C并不比近年的各种高级语言少多少特性;而且,c写的unix的一切皆文件思想正是最为成功和最为著名的面向对象案例;需要关注其分配/回收的资源种类多如牛毛,并不仅仅内存一种,任何一种资源的泄露甚至只是不合理的占用都可能毁了一个项目:只靠一个内存自动回收哪救得了你。
所以,恰恰和外行想象的相反,真正庞大复杂的项目反而更需要天天和“资源管理”打交道的、有丰富开发经验的程序员(这正是c/c++程序员的强项:做不好资源管理的c/c++程序员还是早死早超生好了);那些温室里的、从未尝试过自己掌控资源生存周期的嫩苗绝干不了这事——懒得管内存所以丢给垃圾回收、和不会管内存所以依赖垃圾回收,两者可绝不是一回事。
那些一说C就酸溜溜的扯汇编的,其实正暴露了他对计算原理的无知。并不局限于资源的管理:专业的软件设计,学的是算法、是如何把一个极难的任务建模、分解、实现的学问:编译原理、操作系统等等,都不过是用于演示“如何庖丁解牛一个超级项目”的实例而已。除了C之外,你到哪里找别的、有丰富的相关开源源码及其分析资料的语言?若学到这等程度了,连计算机原理都不会,还学个什么鬼?连个C指针都觉得难、然而却还挣扎着想入这个门的……简直不可想象。可见,如果你的目标是专业的软件工程师,C就是最佳入门语言,没有之一。相比之下,同样的项目,其它语言因为封装的云山雾罩,哪怕是老鸟,想把人家的核心算法/架构从层峦叠嶂的各种委托、代理等等模式中剥离出来,都不是很容易的事,何况初学者。这反而不利于学习偏底层或者偏核心的知识——甚至很容易给初学者造成“不去看系统实现,因为不可能看懂”的“习得性无助”心理。
说完了编程本身,再来看看计算机体系。我们在了解一个系统的时候,你可以自顶向下了解,也可以自底向上了解。但据观察,绝大多数人都选择了自顶向下,比如了解一个公司,首先了解它的 CEO,然后是 CTO 和 COO,然后是部门经理,然后可能是基层员工。在其它学科中也是同理,比如首先识记各种元素再了解元素周期律,首先识记各种音符再了解乐理,这种顺序符合人类的认知习惯。现代计算机大致可以分为这些层次:硬件、操作系统、中间层(比如服务器、数据库、运行时)、和应用。应用->库->操作系统->硬件的学习路径,是符合人类认知的。这种情况也出现在某一层当中,比如对于硬件而言,我们先了解汇编指令,也就是它的皮,再了解流水线,也就是它的芯。对于操作系统而言,我们先了解 API,再了解调度、文件系统、分页等子模块。对于服务器而言,我们先了解与之对话的各种协议,再了解如何实现它。C 语言还有一些其它的缺陷,比如缺乏三方库和学习资料,应用领域窄,等等,都让人避而远之。反正不管一些人嘴上说什么,实际上还是按照最快或者最容易的路径前进。
c语言的语法其实非常非常简单好学。c的难点也在内存管理&指针,你必须做到心中有数。当你学会了真正的内存管理,你已近算是入门可以自己进修了,c语言能肆意妄为的程度超乎你的想象。
学c建议:
1,不要看国产老套的书籍(对,我说的就是某浩强系列)。
2,新手不要过分追求算法,先学好语言语法,再去学算法。
3,不要过度去研究花式的写法,先打好应有的基础。
4,不要三心二意。
c语言真正的难点就是程序员对内存的控制,一个入门c程序员应该具备的素质就是,知道自己程序什么地方用了或者申请多大内存,又在什么地方释放了,心中完全完全有数。新手甚至中级c/c++码农程序调试出错点90%都是内存异常造成的莫名其妙段错误,从而引起程序崩溃,一个好的代码风格和内存管理流程可以让你少犯错。很多人说,学好c就是学计算机,是的,我非常赞同这个说法。真正学好c语言必须要从头学一遍操作系统(大学几乎都有操作系统课程),我指的可不是会点系统编程api。
因为C语言离计算机体系结构本身比较近,而离应用本身比较远吧。你拿起一本C语言的书(当然,我们就不讲那些误导我们的书了,现在资料这么多,找到一本合适的C语言经典还是可以的。
比如The C Programming Language),你学完这本书了,你还是感觉做不出来东西。无论是操作系统、Web服务器、数据库服务器、GUI界面、游戏引擎,那些离你都那么远。甚至你要一个stack,或者字符串操作,你都要自己写。你拿起一本Python的书,学完之后,pip一下,可以做网站了(flask,web.py,django),可以做爬虫了(requests,urllib,beautifulsoup),可以玩数据分析了(numpy,pandas),可以搞GUI了(PyQT,PyTk),可以玩人工智能了(Pytorch,TensorFlow)。而做这些事情,你所要写的代码行数是很少的。从哪门语言入门,其实都可以,关键是你想来做什么?你要了解计算机体系结构,知道内存模型,堆和栈是什么,计算机蓝屏的时候是什么出了问题,实模式和保护模式,32位和64位的区别,进程、线程这些操作系统概念。你用C语言来作为入门比较合适。
如果你学过很多语言,你会发现c语言是最容易入门的,学会了if-else+for循环就可以开工干活了。
python,代码写多了,你会发现,各种泛型不透明,各处不同风格的库,各种不同的大杂烩五花八门的设计方式,传入的参数不看源码都不知道是啥,没有单元测试都是暗坑,运行起来卡卡的。
java,代码写多了,你会发现,各种xml配置的坑,各种设计模式满天飞,各种反射,各种IOC控制反转,AOP面向切面更是在面向对象的墙上打洞,你并不知道运行时是你调用代码,还是代码调用你。c++,代码写多了,你会发现,可以在代码中嵌入c语言,汇编,需要注意各种不同平台,不同操作系统,不同输入输出编码,不同的指针类型,不同的模板参数调用方式,不同的内存对齐,不同的编译器,不同的链接方式,不同的内存释放方式,不同的数据结构,不同库的技巧,不同的编程风格,不同的cpu发布方式。
js,代码写多了,你会发现,各种概念满天飞,事件回调一层层的像一碗面条,拉一根动全身,需要兼容各种环境,兼容各种不兼容,依赖运行环境,类型各种不透明,各种语言技巧,各种第三方框架,很多隐藏很深的错误需要在运行时真正发现。
作者:find goo
链接:https://www.zhihu.com/question/49294784/answer/599800129
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。