订阅
绝地求生 http://www.xthdc.com/news_6/23.html 转自:编程指北 昨天晚上回家后突然在朋友圈发了个问卷,看下国内大学第一门语言到底有多少是用的C语言。 结果也是很符合预期,使用C语言做第一门编程语言课的大学达到了90%以上。 之前在知乎看见一个问题,问为什么还有985高校给大一上C语言课,如下: 不过这个提问方式未免有引战嫌疑,所以被知乎管理员编辑为如下问题: 这样显然中立很多了,是在摆事实提问题。 接下来我们就聊聊985大学为什么还是给大一上C语言课。 一、为什么要学C语言? 首先,我们学的是ComputerScience,而不是ProgrammingLanguage,语言真的真的真的不是重点。 语言只是工具,工具没有优劣,只有各自适用的场景不同。 所以,以下所有讨论皆不涉及语言优劣,一切论述以怎样才是有利于学好ComputerScience为原则(求生欲满满 大学教育,尤其是985、211这种国内最顶尖的一批高校,应该注重通识教育而不是专项教育,在专业上更要注重基础、底层、偏向原理。 只有掌握了最核心的东西,学起那些偏技能的东西才会很快很轻松。 我记得当时大二需要写爬虫,大概看了一天左右的Python教程,会基本的循环、判断、控制流、一些builtin函数和类,然后学了下requests库就直接开干了。 其实像JS、Python、Node、PHP这些东西,科班学生几乎都是自学,哪还用得上单独开一门课呀。 自学是最基本的要求,需要用到的时候自己去看教程、文档,直接就上手写了。 所以这种语言完全没必要开一学期的课来学,倒是非常适合放在计算机导论课程中,成为其中一个章节。 比如Berkeley开设的导论课CS61A就是以Python作为练习语言,但是似乎国内很少有高校开这种导论课。 但是C、C++这种语言,不学个一两个月,连个像样的程序都写出来,这种才是适合开一门课。 先说一下学习C语言的目的,上面我说语言不是重点,这也包括C语言。 但是C语言特殊就特殊在于它可能是唯一最适合用来学习一系列计算机基础课的工具和媒介。 比如操作系统,实验几乎都是用的纯C写的lab; 又比如汇编,学习的时候可以和C语言对应起来,了解if、for、while、数组访问等对应汇编是怎么样的; 又比如学习计网,这里面有很多的网络协议,会有不同的header定义,这些header中很多都是按bit来划分字段的,用C语言的union和struct是最好操作这些字段的,Java和Python等语言虽然也能表示,但是可控性会差很多,以前尝试过用Python去组装IP包头,非常的麻烦也不优雅。 并且C语言本身抽象层次非常低,语法也很简单,没什么语法糖,很贴近操作系统。 而其它很多解释型语言会存在虚拟机这一层,虚拟机对我们算是一个黑盒,不利于透过语言去理解计算机的一些行为。 所以我之前在《如何成为一个计算机知识体系完整的毕业生》中把C语言也列为计算机专业的基础,而且是程序员必学的知识。 二、C语言的优点 C语言已经走过了四十多年的历史,但是在今天,任然常年霸占TIOBE编程语言排行榜前三,甚至榜首,这足以说明它是一门经久不衰的语言。 在日新月异的计算机行业,一个历经四十多年任然流行的技术,才是需要我们去关注和学习的经典。 我在那篇文章中说C语言是最适合用来理解计算机系统底层机制的语言,那今天就详细说说,这些底层机制都有哪些: 内存 一名合格的程序员必须了解内存,学习C语言是了解内存布局最直接、有效的途径,大家可以看到之前讲解指针那篇文章--深入理解内存和指针,全部都是从内存、内存布局出发进行讲解。 堆栈 理解不同的内存分配和管理方式,一种是编译器自动管理,一种是手动管理。 函数调用栈、返回值 理解函数调用的本质,即跳转指令,理解返回值是怎么返回的。 系统调用 比如理解文件描述符,知道文件、socket这些都被抽象成了fd。 指针 指针也是其它语言中引用的基础,深入理解指针对于理解引用也有很大帮助。 就拿文件来说,在C语言中经常会接触到read、write系统函数,清楚操作的打开文件对应的是文件描述符。 而文件描述符是有限的,所以你知道用完fd后要及时关闭。 甚至用到socket网络编程的时候会发现,socket返回的也是fd,网络数据也能通过read、write去读写。 深刻的体会到Unix哲学:一切皆文件。 而在Java、Python、PHP这些语言中,打开一个文件只需要调用File.open或是open,然后就可以拿到一个对象,然后对这个对象去调用读写方法进行操作。 但这时候文件对于我们更像是一个资源,全部的细节都被对象屏蔽了,而老师说资源是有限的,所以用完了要及时释放。 而你也不知道如果不释放这些资源会有什么后果,只是听老师说用完的资源及时释放是个好习惯。 在这里,操作系统的文件系统、进程等很多实现机制就被JVM、Python虚拟机所隐藏了。 而和操作系统等密切相关的底层机制也只有通过学习C语言才能透彻地理解它们。 这里又有个矛盾,上面说的这些内容其实不单单是C语言课所教的,其中还包括《组成原理》、《汇编》、《操作系统》等。 所以就出现了很多同学说的,就算上了C语言课,上面这些很多原理也还是不知道呀。 当然,这些内容是需要在大二、大三上专业课逐渐补齐的,但是先学C语言给学习这些内容打下了一个基础,大一把内存和指针理解透彻就好了,这就是前置条件。 而如果大一不上C语言,那么后续需要用到C语言的时候,自学的难度会高于自学Python、Java等语言。 比如有些学校在操作系统课会引入一些国外的Lab,诸如MIT6.828xv6那样的minios,需要学生动手去完成一些内存管理、多线程实现、文件系统等操作系统核心模块。 比如清华OS课程用的ucore,哈工大OS课程用的linux-0.11,这些都是纯C写的。 如果没C的基础,连实验都没法继续,而这些实验算是操作系统课程的精髓了。 所以这才是我认为大一先上C语言的核心原因: 一是语法简单,更加贴近计算机本质的一些东西,学C也不是简单的学语言本身,而是想透过C语言去理解一些如寄存器、内存、函数调用、跳转等东西。 二是为大二、大三阶段的专业课打下一个基础,当然很多同学说我不学C一样可以学操作系统、计网呀。 当然,这些和C没必然关联,只是很多实验你确实不好继续做,除非你只打算看看概念,背背什么是进程、线程。 三、如何正确的打开C语言? 我认为C语言最为核心的有三块: 指针 内存 系统编程 首先指针和内存是需要在学习C语言过程中就理解、搞定的,推荐两本书: 《C程序设计语言》、《C和指针》 如果你觉得初学看书过于困难,那么可以去中国大学MOOC上浙大翁凯老师的C语言课,可以直接去B站搜。 视频结合书一起看,相信会理解得更加深刻。 然后,学习完了C语言基本语法后,你会发现似乎只能开发在黑窗口里运行的程序,写不出那些漂亮的GUI。 确实,C语言本来就不擅长做这些,C语言擅长的是开发系统组件来支撑上层应用。 但是如果你迫切的想做出一些可视化、有趣的东西,那么可以这样做: 找一些C语言的图形库,比如easyx,借助这些图形库,你完全可以实现一些图形界面的游戏。 继续去学Python、Java这种语言,然后学习Web开发,写写网页。 当然了,如果你对那些可视化的东西没那么大兴趣,甚至还挺喜欢黑窗口的,那么恭喜你,你有成为大佬的潜质。 当你熟悉完C语言基本的语法以后,建议去学习数据结构与算法,用C语言去实现链表、树、二叉树、堆、排序、搜索等等。 推荐看看《算法:C语言实现》这本书。 如果能通过void指针实现一些泛型数据结构就更棒了,比如标准库里的qsort就能支持任意可比较结构体排序。 然后,时间应该很快来到了大二、大三,这时候你应该学习系统编程,什么是系统编程呢,其实就是CSAPP这本书上所讲授的内容。 系统编程其实就是学习如何用C语言编写出真正可用的软件,比如像httpserver、redis这种,会涉及到: 如何在Linux环境下编程 系统级接口(system-levelinterface)究竟是什么 Linux内核和C标准库提供了哪些能力 Linux的系统调用是怎样实现的 都有哪些系统调用,如何使用 其它诸如mutex、signal、select、epoll、ipc、socket、thread、process(fork)等等 当然,还有一些同学会选择继续学习Java这种,比如JVM、多线程、JavaWeb等等,这也是没问题的。 但是,相信我,就算你以后不会用到C去编程,利用大学大把的时间去深入学习一些底层的知识。 也是对深入学习Java有好处的,比如你学Netty、Java的NIO最终都要回到Linux系统的epoll、select上。 系统编程推荐《深入理解计算机系统》、《Unix网络编程》、《Unix高级环境编程》,Windows下的我基本没学过,所以就不推荐了。 这就是Java、Python之下的世界,相信Javaer都学习过JVM的原理,了解过GC、类加载机制、运行时数据区等知识。 但实际上,JVM也只是介于操作系统之间的一个中间层。 很多时候JVM、Python解释器等本身都是需要Native本地方法栈去和OS打交道的,去和系统调用接口交互。 所以Linux系统编程对于深入学习编程一定是绕不开(因为很多服务端程序都是运行在Linux上的,所以忽略了Win/Mac 而这是C语言的世界: 所以C的重要性不需要的多说了吧~ 不少Java、C#、PHP、Python程序员工作几年后会遇到瓶颈,有些会回来学习C语言,重拾底层概念,寻求新的突破。 这里不是在否定其它非C程序员就没技术,实际上我本身也不写C,我只是想表达如果你想学习底层机制、操作系统等,请学习C语言。 编程学到一定的时候,你就需要了解底层系统的机制,否则,知其然不知所以然。 真正的高手往往都是有很强的系统性基础知识的,表面的东西永远是肤浅的。 所以利用大学的时间恰恰是打好这些基础的关键时间,等到工作了,大家都是更倾向于学习快速上手业务的技能。 所以,在大学里先学什么语言不重要,你可以先学Python、Java,但是无论如何,如果你想学好ComputerScience,C语言一定绕不开。 也许以后实际工作中你完全没有机会去写C,但是这并没关系,打好了基础,学其它也会学得很快、很透彻。 对于计算机专业的同学,还是建议学好C语言,与其它课程相结合,多懂一点程序背后的实现原理。 最后上两张图,什么叫真正的技术啊(战术后仰 还教微服务,这种不是玩概念么? 不去公司上手真正的微服务项目,在学校、培训班搭微服务? 这种东西学习下概念和思想就好了,这些东西根本就是应用层的东西,学习起来根本不费劲的好吧。 我敢保证,没有一个985会教微服务这种东西,分布式理论倒是可能会单独开一门课。 不过我相信上面图片里的这个分布式一定不会教CAP、Raft、Paxos这些东西,大概率是用Springboot+Dubbo+Zookeeper在几台机器搭建一个服务。。。 而这是科班的学习路线,先不说这些课程有多少是学过就忘了的,但至少你需要用到的时候知道去哪捡起来,怎么捡。 不过讲道理两张图片,殊途同归,最后都是码农,只不过大概率决定了你在哪里敲代码。 总结一下,BB了这么多,就想表达一个意思,C语言很重要,如果你正在大学学C,一定要掌握好,不要怀疑学C有没有用。 微软于年初推出了自己的Python教程,我们将其汉化提供给大家,欢迎大家收藏关注哦~(已经汉化完成的20集,我们日更1集,未完成部分我们尽快更新) ![]() |
10 人收藏 |
![]() 鲜花 |
![]() 握手 |
![]() 雷人 |
![]() 路过 |
![]() 鸡蛋 |
收藏
邀请