为什么要学编译原理?

这个问题很有意思,我想提这个问题的大概率应该是一名计算机专业的大学生,编译原理这门课确实枯燥,因为编译原理中讲述的知识本身就是高度抽象的概念,所以这里我不赞成枯燥是因为讲述者本身只会照本宣科才导致它枯燥乏味的观点,我觉得枯燥的主要原因就是因为它很难!这也是很多数学家和计算机科学家穷尽一生研究过的领域。你不得不承认人和人的智商是有差距的,对知识的敏感度和理解能力也就不一样。

那编译原理这门知识有用吗?先说结论:数据结构、编译原理、计算机体系结构、操作系统这些号称屠龙之术(听上去很高大上但没有实用价值的技术)都有很大价值,无数的计算机科学家不是吃饱了没事干耗费自己的天资去研究他们琢磨出这些东西就为了让大家听着牛逼,但是对于普通的IT从业者来说,大家做得更多的是使用一门语言去解决一些特定的业务问题,重复的编写各种业务逻辑,那这些知识可能听上去确实没有什么用处,因为它们隐藏得太深了,你用了一门成熟的语言,优秀的编译器,以及各种功能对应的优秀类库,所以你只是站在了无数牛人的肩膀上看世界而已。

在我上这门课程的时候经历过一场让我印象很深的小插曲:一位同学在编译原理的课程上看《Java程序设计》被老师发现,然后老师语重心长的说:同学,你不要觉得这门课程没用,等你工作后就会明白他的重要性,结果被这位同学当场顶撞说:你们都说数据结构有用,可是JDK已经各种Map、List、Tree都封装好了,我直接用就得了,干嘛费那功夫还要自己去实现?至于编译原理,哪家公司还需要自己去实现一个编译器么?这位同学在我们年级还比较有名,属于动手能力很强,读书期间已经接过很多建站类型的外包项目,能够熟练使用一些后端开发的组件,在学校论坛的活跃度很高,所以我想当时应该有不少同学是抱着这种态度去学习计算机这些基础课程的。

废话说了这么多,这里步入正题,从我工作的经历来说几点编译原理的用处,我相信大多数从事后台开发工作的同学都绕不开要使用数据库或者类似的数据存储系统,那你就离不开要接触SQL这门关系型语言,这就跟编译原理的知识息息相关了,在分布式存储系统刚刚大热的时候NoSQL概念成为漫天论调,但是到现在你还能看到这种论调吗?因为在实际的生产开发中大家发现API真的太难用了,没有标准的接口定义,这对业务开发同学很不友好,学习成本也高,程序版本升级维护也十分痛苦,所以慢慢的这个领域的专家们提出了NewSQL概念。

在一家对数据管理规范的公司里,都离不开要对各种技术人员对各种数据集的权限管理,如果你刚好是从事运维开发工作,那你可能需要开发一套系统来区分各种技术人员对各种库各种表甚至某些敏感数据的读写权限,这个时候数据库提供的权限控制可能就不够用了,那你不得不去开发一套系统例如阿里的idb系统,需要解析SQL,分析它的行为,你需要写一个语法解析器,或者说你一个业务之前是运行在MySQL上的,现在因为需求问题,要搬到PG上,业务SQL要做一定修改,你是人肉去修改么?多大的工作量?这时候你也需要写一个解析器去做两个库之间的SQL转换,当然你可以选择一款开源的语法解析器,这样省事省力,但是你至少要知道如何写BNF范式,了解各种文法,它们实用的场景,才能选择一款适合你的开源语法解析器。

上面提到的只是后台管理工具,你不用关心语法分析器对性能的影响,但如果你是从事中间件开发的工作,你一样需要做权限控制,需要做SQL路由,这个时候你可能需要考虑解析的性能了,因为是用在生产线上的东西,你还得考虑状态机的实现,开源框架里有没有写得很糟糕的烂代码,例如开发druid,zdal这类组件。曾经就有某个团队因为使用了一个推荐算法的java库,没有review它的实现,在双11当天,因为一个特定的高并发操作,这个开源库实现得比较暴力,导致资源消耗严重,从而引发了很大的线上故障。

再往下,如果你是从事数据库内核开发工作,这个时候你可能就不是使用开源框架那么简单,你需要考虑每一个函数对性能的影响!这个时候不光是要了解词法分析,语法分析,DFA这些的原理,还得考虑状态机实现是否高效,在去年,OB针对某个业务场景做性能优化的过程中,我们对SQL执行,事务,读写操作做了大量优化后最后发现性能消耗最大的居然是SQL的词法分析上,原因是因为我们使用的YACC生成的SQL解析器,它的词法分析状态机依赖大量的状态转换表,而这个查表过程对CPU的cache和流水线的分支预测都是非常不友好的,最后我们基于了生成的状态机做了特殊的改造,将一些常用词法路径硬编码到状态机中来减少词法分析的开销,这也是为什么像主流的数据库词法分析基本都是自己写的原因。除此之外,你还得考虑一些常用路径的编译优化问题,你的程序设计是不是抽象得越完美越好?编译器能对你的抽象做哪些局部优化和全局优化?你要基于它的短板写出最容易让它理解的代码才能把服务器的性能榨干到极致,将商业软件的性价比做到极致。要实现这个目标就不再是编译原理这一个范畴了,你还得在数据结构的选择上,操作系统的资源调度上,计算机体系结构的理解上下功夫,这是一个程序员综合内力的一种考量,当你去思考这些问题的时候,才能发现程序设计的各种权衡的艺术。

所以我觉得既然你选择了计算机这个专业,你要耗费至少四年的青春,那最宝贵的时间去了解一个领域,那就要在学习计算机这些基础课程的时候认真对待,它们是构建大厦的地基,夯实了这层基础,以后你才能把楼建得更高更牢固。

浏览器:最复杂的解释器

大型程序(软件)都有配置文件,可能需要自己编写,(部分情况下)需要自己写配置文件处理器(解释器)

字幕文件:字幕处理器,很简单的解释器

系统命令:命令解释器(解释执行特定结构的字符串)

    例如:计算5+2,使用f(x,y){return x+y}不如使用f(string s){解释执行字符串s},可扩展性更强

结论:编译原理不只是做编译器的,同时可以做解释器,解释器很常见

猜你喜欢

转载自blog.csdn.net/weixin_42305039/article/details/100704621