Better

Ethan的博客,欢迎访问交流

读《程序员的呐喊》有感

很难想象这本书我坚持读下来了,因为此书无关技术,可以说是作者的一些吐槽,但是越读到后面,感触是越来越深。

前言

旱鸭子会和水保持距离,司机会绕开泥泞的路段,而程序员会都在舒适区里,搭建围栏把自己保护起来,然后祈祷世界和平。

我非常赞同文化相对论,尽量不去对那些和我意见不同的人下结论。

编程语言

C语言

C语言是必修课,因为就实际用途来说,这个世界上你遇到的每一台电脑都是冯诺依曼结构,而C以精悍的语法展现了冯诺依曼的能力。

计算机体系结构的标准:一个CPU、RAM、一个磁盘、一套总线

C++

可以说是地球上最糟糕的语言。

作为一门面向对象语言,一定要有运行时反射和获取类型的能力,而C++不具备这种能力。

漂亮的C++代码还是可以写出来的,这样的代码大部分都是C,外加一些C++的特性,而且用的优雅有节制,C++是个巨大无比的坑,越是了解他,优越感就越强,最后一定会忍不住要用上各种特性。

只有在掌握更优秀的语言的前提下,才回懂得怎么批判自己最熟悉的那门语言。

Java

Java可以说是过去10年来,计算机行业出现的最好也是最坏的事物。

不管什么语言,不合格的程序员写出来的都是烂代码。

无论出发点有多好,我的周围肯定会出现不会写代码的家伙,而Java能让他们的危害小一点。

差不多每15年左右,就会出现更优秀的语言。C++取代了C,现在C++逐渐被Java取代。

Python

Python本来是有机会一统江湖的,但是他有俩个致命的缺陷,一个是空白符,一个是死脑筋。

保守派 VS 自由派

软件工程有自己的政治轴心,一端是保守派,一端是自由派。

自由主义主要是为了以最快的速度开发出新功能,同时又能保证系统的灵活性,这样开发过程就不会被拖慢或是受阻。

保守派也是以此为目标的,灵活性和生产力仍然是动机,但是不再是主要动机,安全才是最重要的考量,性能常常也是软件保守主义者眼里非常重要的东西。

我觉得一只和谐的团队最好有单一人群组成,要么全是自由派,要么全是保守派,免得对方不停地发生理念上的冲突。

静态类型毫无疑问是软件政治观点的分水岭,更是保守派的世界观特征。

all-warnings-are-errors vs all-errors-are-warnings

学习是一件很困难的事情,要是你觉得很简单,那么你肯定是在摸鱼,不去挑战自己做一些过去做不到的新事物,你是不可能提高自己的。

交叉训练在运动学里是有理论基础的,只打篮球是不可能成为篮球大师的,你还要训练强化自己的力量、敏捷和耐力。程序员也要掌握各种特点不同的语言后,才能做出正确的设计。

荒废时间更让人痛苦

如果你想要上进的话,唯一要做的就是持之以恒。只要脚踏实地,就能循序渐进。

重构

所谓重构,就是通过迭代,将恶心的代码变成优质代码的艺术和科学,是能妆点代码却不会在操作过程中产生破坏的算法,而且正确性都是能证明的。

记住代码永远都在变,永远永远都在变,一旦你要在N的修改相同的代码,而N大于1的时候,你就知道什么叫做痛苦了。

程序员的数学

懂数学对程序员来说是如虎添翼

数学知识是可以在空闲时间里慢慢累积起来的

概率论、离散数学、统计、代数和线性代数……

学习数学的正确方式:广度优先才是学习数学的正确方法,深度优先是不行的,先打开眼界,了解各种名称,搞清楚什么是什么。

每天学一点数学,我当初这个决定是在是太棒了。

编译原理

不懂编译器原理的人,也不懂计算机的原理。编译原理是计算机科学本科里第二重要的课程。

编译原理是一门重要的计算机科学课程的首要原因就是,它非常切实的将你之前学过的几乎所有的东西都捏合在了一起。

你难道从来没有碰到需要写程序处理自己代码库的时候?

大多数程序员喜欢的那些课程可以归结为计算机科学里的橄榄花园:笨蛋程序员向聪明程序员学习的地方。

如果你不选修编译原理,那就要冒着永远混迹于二流程序员行列的风险。

编译器在逻辑上可以分为三个阶段

  1. 第一个大阶段就是解析,经历预处理,词法分析,语法分析和中间代码生成这几个步骤。词法分析通常是有正则表达式完成,语法分析则是根据语法完成。
  2. 第二个大阶段就是类型检查
  3. 第三个大结算就是代码生成

应聘Google

热身:可以分成长期和短期,两样都不能忽略

最佳长期热身方式

  1. 好好读一本讲数据结构和算法的书(《算法设计手册》《算法导论》)
  2. 找个朋友来面你

短期准备就是尽可能使自己保持警醒,充分热身。

心理准备

  • 保持谦逊、开明、专注的态度
  • 要是觉得卡住了,不要害怕问问题

准备技术面试的建议

  • 算法复杂度,大O是一定要懂的
  • 排序,不要写冒泡排序,至少了解一个复杂度为n*log(n)的排序算法的细节,能记住两个更好(比如快速排序和归并排序),归并排序在那些快速排序不好用的情况下通常都很有用,所以也应该了解一下
  • 哈希表,哈希表可以说是人类一直的最重要的数据结构,所以一定要弄明白他的原理,要做到能够在一场面试里,用自己最熟悉的语言,只用数组实现它
  • 树,必须弄懂,这是基础,至少应该熟悉二叉树,n叉树,trie树,树应该是长期热身里最好的练习题资源了
    • 至少要熟悉一种平衡二叉树,可以是红黑树,伸展树,AVL树,必须掌握实现细节
    • 树的遍历算法你也要知道,BFS和DFS,还要了解前序、中序、后序遍历的区别
    • 可能你树用的很少,但那是因为你在回避他
  • 图,非常非常重要
    • 在内存里图的表示基本上有3种(对象和指针、矩阵、邻接表),每种表示都要熟悉,并且知道他们的优缺点
    • 了解基本的图遍历算法:广度优先搜索和深度优先搜索,知道计算复杂度、优缺点、以及具体实现的代码
    • 更高级的算法,如Dijkstra算法和A*算法
    • 每次遇到问题,首先应当考虑的就是图算法,它们是任何关系最基本、最灵活的表示方法。任何有点意思的设计问题可以说有一般的机会会涉及图算法。只有在你百分之百确定没办法用图算法来解的时候,才能去考虑其他方法
  • 其他数据结构
    • NP完全问题是什么意思
    • 注明NP问题
  • 数学
    • 离散数学、计数问题、概率问题
  • 操作系统
    • 进程、线程、并发
    • 锁的概念、互斥锁,信号量,管理机制的工作方式
    • 死锁,活锁,怎么避免
    • 进程需要那些资源,线程需要那些资源,上下文切换怎么进行,操作系统和底层硬件是怎么触发上下文切换的
    • 调度
    • 并发结构
    • 《Java并发编程》
  • 编程:至少熟练掌握一门编程语言,一定要对那门语言有相当程度的了解

敏捷开发

营销骗局、没有银弹

任务列成卡片,每张卡片还有一个时间估算,当客户要加什么东西的时候,咨询师会指着墙壁说:“没问题,伙计,你打算换掉上面哪张卡片”。

软件工程师的生产力本来就很难衡量。

反正试试看也没有坏处啊?可是真的没有坏处么

对于你想要反驳的东西,要想产生正确的影响,一定要同时另指一条明路。

Google开发流程

  • 经理也至少有一半时间在写代码,所以他们更像是技术主管
  • 工程师可以在任何时候换组,或者换项目,不会有人质疑你
  • Goole的理念是不去告诉工程师要做什么
  • 鼓励工程师花20%的时间去做任何想做的事情,而不是工作
  • 很少开会
  • 安静的环境
  • 没有甘特图,或者日期-任务-负责人的表格,或是任何看得到的项目管理工具
  • 真的碰到项目吃紧的时候,大家还是会去吃午饭和晚饭

Google通过利益来驱动行为,通常做比较重要的项目所得到的奖励比作不那么重要的项目要来的高

每个季度雷打不动的集会,向大家展示每一个发布的项目,Google对产品发布非常认真,我觉得做出了了不起的东西并且得到认可是这个公司里最强大的驱动力。

每周都会有新花样,新福利,新变化,新的调研。来问我们怎么才能让大家在Google过得更舒服。

以奖励为本的文化确实是一个很重要的因素,但它只能驱动工程师去做正确的事,却无法做到高效。那他们是如何做项目的呢?

Google所采用的项目管理的技术更像是润滑剂而非汽油,他们是为了让项目进行的更顺利,而不是迫使项目向前进

Google是一家非常有纪律性的公司,对待单元测试,设计文档,代码审查的态度,超过了我所知的任何一家公司。如此一来,整个代码库看起来整齐划一,如出自一人之手,所以换组和代码共享也要比其他地方容易的多。

工程师需要称手的工具,所以Google会聘请最好的人才来打造自己的工具。

所有的估算都是带着过于乐观的有色眼镜进行的,好了伤疤,谁还记得痛。

Google通常不事先公开自己的产品,他们真的明白软件开发这种事情就和烹饪、生孩子一样是急不来的。

Google为你提供了大量的培训,每周都会有来自内部和外部的讲师做技术演讲,这些演讲都会永久存档,任何时候都可以去看。

业余时钟:就是那些在主要工作之外你想完成的事情,这通常是一些重要的清理工作,或是其他一些最终能改善整个团队生产力的事情。坏的敏捷只把注意力放在眼前的目标上,这对创新是有害的。毕竟要是你只是机械的照章办事的话,怎么会想到去做别的事情呢?

吐槽Google平台

打造基础设施平台,应用都是建立在平台之上的

缺少平台支持的产品肯定会被有平台支持的同等产品取代

你不能自己吃人吃的东西,却让开发者吃狗吃的东西,这样只是拿长期的平台价值来换取短期的成功而已,平台是需要长远眼光的。

个人总结

以上是我摘录的一些我看完之后还记得的东西,现在回想起来真是境界,眼界什么的都比不过,不过这也正常。

我常在思考,如何才能成为一个优秀的程序员,尤其是现在从事的前端工作,新技术真是层出不穷,如果才能有所突破,不身陷囹圄呢,这些都是需要好好思考的。



留言