联系我

《程序员练级攻略》读书总结

2020.05.18

本书内容对于刚入门的程序员来说可能具有很好的指引作用,对于有些开发经验的程序员来说同样有不错的梳理导引作用,刚开始看到这个书名的时候,给我的直观感觉是--这是不是又是一个人称“大神级”的普通程序员写的一些“人生感悟”什么的,个人对于这种论调的书籍或者材料比较反感,但看了看作者简介和书页以后,觉得这本书写的很不错(真香?),下面就我所阅读感悟的一些点作个简单的总结反思。

导引

每个行业都有自己的一套运作规则,程序员(狭隘的定义不必深究)这个行业同样有着自己的一套完备的体系和规则,随着这些年的产业快速发展,技术也迭代的非常快速,很多人直呼--“I can not follow any more!”,是的,这是不争的事实。

要进入这个行业,首先需要在这个行业当中找到相应的定位和成就感,这个成就感有了,也就顺带激发了兴趣,这是个大前提。如何去获得成就感呢,我们可以先从简单的程序语言(语法糖比较多的)去入手,去慢慢写一些小程序,完成一些“自动化”的工作,然后学会使用很多工具,去构建,去搜索,去实现我们想实现的小功能。

如何成为优秀的程序员?要有程序员的“自我修养”,有修养的程序员才可能成为真正的工程师和架构师,而没有修养的程序员只能沦为码农,这是码农和工程师的关键区分点

一个有修养的程序员应该具备哪些关键的能力?

  • 英文能力
  • 问问题的能力
  • 写代码的修养
  • 安全防范意识
  • 软件工程和
  • 编程规范

专业基础?

  • 编程语言:推荐学习C,C++,Java这三个工业级的编程语言
  • 理论学科:需要学习算法、数据结构、网络模型、计算机原理等内容
  • 系统知识:Unix/Linux,TCP/IP

从业方向?

  • 如果你对操作系统,文件系统,数据库,网络等比较感兴趣,那么可以考虑从事底层方面的工作
  • 如果对分布式架构,微服务,DevOPS,Cloud Native等比较感兴趣,可以从事架构方面的工作
  • 如果对大数据、机器学习、人工智能等比较关注,那么数据领域可以成为你一展身手的地方
  • 如果对用户体验或者交互比较感兴趣,那么前端工程师是个不错的选择
  • 此外,安全开发,运维开发,嵌入式开发等也提供了丰富多彩的发展空间

两个观点:各种技术不是鱼和熊掌,是可以兼得的;很多技术是相通的,关键是你学在表面还是深入本质

软件设计是工程师非常重要的能力,这是从工程师通往架构师的必备技能。


给你再一次做选择的机会,平凡还是卓越?自在悠闲,还是猛啃书本,不破楼兰终不还?遵循你内心的选择,偷偷告诉你,我选的是后者。

有了选择,方向就有了,剩下的你需要做的就是朝着这个方向努力就行。

需要解决几个问题:

  • 理论和现实的差距 --学习学的到底有多少用?
  • 技术能力的瓶颈 --老是写业务,好像没看到有多少成长?
  • 技术太多学不过来

需要明确几点端正一下态度:

  • 并不是理论和现实的差距大,而是你还没有找到对应的场景,来感受那些学院派知识的强大。算法与数据结构、操作系统原理、编译原理、数据库原理、......这些原理上的东西,是你想要成为一个专家必须要学的东西,这就是工人和工程师的区别,是建筑工人和建筑架构师的区别。如果你觉得这些理论上的东西无用,那么只能说明,你只不过是在从事工人的工作,而不是工程师的工作。
  • 技术能力的瓶颈,以及技术太多学不过来,只不过是你为自己的能力不足和懒惰找的理由罢了。
  • 一切成果需要自己持续的努力和付出

学习建议

  • 一定要坚持,要保持长时间学习,甚至终生学习的态度
  • 一定要动手,不管例子多么简单,建议至少自己敲一遍看看是否理解了里面的细枝末节
  • 一定要学会思考,思考为什么要这样,而不是那样。还要举一反三的思考
  • 不要乱买书,不要乱追技术名词,基础的东西经过很长时间的积累,会在未来至少10年时间内通用
  • 回顾一下历史,看看历史线上的技术发展,你才会明白明天可能会怎样

进击之路

资料书籍:

像 Python 和 JavaScript 这样的动态语言用着是很爽,但是,只有像 C、C++ 和 Java 这样的静态语言才可以让你真正地进阶。

到这里,估计你最少也要花 1-2 年左右的时间,已经是一个 " 全栈工程师 " 的样子了,相信你可以找到至少年薪

20 万以上的工作了,而且你的知识面算是有不错的广度了,但是深度还不够,这个时候,是一个比较关键点了。

建议:

选择一个方向开始深入。因为你并不知道你未来会有多大的可能性,也不知道你会成为什么样的人,所以为什么不再更努力一把呢?

程序员的自我修养:

  • Bad architecture causes more problems than bad code.
  • You will spend more time thinking than coding.
  • The best programmers are always building things.
  • There's always a better way.
  • Code reviews by your peers will make all of you better.
  • Fewer features for better code is always the right answer in the end.
  • If it's not tested, it doesn't work.
  • Don't reinvent the wheel, library code is there to help.
  • Code that's hard to understand is hard to maintain.
  • Code that's hard to maintain is next to useless.
  • Always know how your business makes money, that determines who gets paid what.
  • If you want to feel important as a software developer, work at a tech company.

《97 Things Every Programmer Should Know》

程序员的自我修养更多的决定了这条路你到底能走多远

Java书籍推荐

《Java 核心技术:卷 1 基础知识》,这本书本来是 Sun 公司的官方用书,是一本 Java 的入门参考书。对于 Java 初学者来说,是一本非常不错的值得时常翻阅的技术手册。书中有较多地方进行 Java 与 C++ 的比较,因为当时 Java 面世的时候,又被叫作 "C++ Killer"。而我在看这本书的时候,发现书中有很多 C++ 的东西,于是又去学习了 C++。学习 C++ 的时候,发现有很多 C 的东西不懂,又顺着去学习了 C。然后,C -> C++ -> Java 整条线融汇贯通,这对我未来的技术成长有非常大的帮助。


有了上述的入门后,Java 的 Spring 框架是你玩 Java 所无法回避的东西,所以接下来是两本Spring 相关的书,《Spring 实战》和《Spring Boot 实战》。前者是传统的 Spring,后者是新式的微服务的 Spring。如果你只想看一本的话,那么就看后者吧。


接下来,你需要了解了一下如何编写高效的代码,于是必需看一下《Effective Java》(注意,这里我给的引用是第三版的,也是 2017 年末出版的书),这本书是模仿 Scott Meyers的经典图书《Effective C++》的。Effective 这种书基本上都是各种经验之谈,所以,这是一本非常不错的书,你一定要读。


《Java 并发编程实战》,是一本完美的 Java 并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容。最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。


了解如何编写出并发的程序,你还需要了解一下如何优化 Java 的性能。我推荐《Java 性能权威指南》。通过学习这本书,你可以比较大程度地提升性能测试的效果。其中包括:使用JDK 中自带的工具收集 Java 应用的性能数据,理解 JIT 编译器的优缺点,调优 JVM 垃圾收集器以减少对程序的影响,学习管理堆内存和 JVM 原生内存的方法,了解如何最大程度地优化 Java 线程及同步的性能,等等。看完这本书后,如果你还有余力,想了解更多的底层细节,那么,你有必要去读一下《深入理解 Java 虚拟机》


《Java 编程思想》,真是一本透着编程思想的书。上面的书让你从微观角度了解 Java,而这本书则可以让你从一个宏观角度了解 Java。这本书和 Java 核心技术的厚度差不多,但这本书的信息密度比较大。所以,读起来是非常耗大脑的,因为它会让你不断地思考。对于想学好 Java 的程序员来说,这是一本必读的书。


《精通 Spring 4.x》,也是一本很不错的书,就是有点厚,一共有 800 多页,都是干货。我认为其中最不错的是在分析原理,尤其是针对前面提到的 Spring 技术,应用与原理都讲得很透彻,IOC 和 AOP 也分析得很棒,娓娓道来。其对任何一个技术都分析得很细致和全面,不足之处就是内容太多了,所以导致很厚,但这并不影响它是一本不错的工具书。


当然,学 Java 你一定要学面向对象的设计模式,这里就只有一本经典的书《设计模式》。如果你觉得有点儿难度了,那么可以看一下《Head First 设计模式》。

学习设计模式的时候,不要迷失在那23个设计模式当中,明白两个原则:

  • Program to an 'interface', not an 'implementation'
  • Favor 'object composition' over 'class inheritance'
    • 继承需要给子类暴露一些父类的设计和实现细节。
    • 父类实现的改变会造成子类也需要改变。
    • 我们以为继承主要是为了代码重用,但实际上在子类中需要重新实现很多父类的方法。
    • 继承更多的应该是为了多态。

有了以上的铺垫,你已经是一个高级Java程序员了,可以进到一线公司,是高级程序员或者初级架构师的水平。

其他语言及参考书籍资料:

C 语言太原始了,C++ 太复杂了,Go 语言是不二之选

理论学科

算法书籍资料:

  • 《算法》
  • 《算法图解》
  • 《算法导论》
  • 《编程珠玑》
  • leetcode
  • 《数据结构与算法分析》
  • 《数据库系统概念》
  • 《现代操作系统》
  • 《计算机网络》
  • 《计算机程序的构造和解释》
  • 《编译原理》

系统知识

  • 《深入理解计算机系统》
  • 《Unix高级环境编程》
  • 《Unix网络编程》
  • 《TCP/IP详解 卷I协议》
  • 《Linux C编程一站式学习》
  • 《TCP/IP网络编程》
  • 《图解TCP/IP》
  • 《Wireshark数据包分析实战》

软件设计

学习软件设计的方法、理念、范式和模式,是让你从一个程序员通向工程师的必备技能。

有品位的程序员和没有品位的程序员所写出来的代码,所做出来的软件,差距非常大,而且价值也差别很大。

软件设计这个事,并不是一朝一夕就能学会的,也不是别人能把你教会的,很多东西需要你自己用实践、用时间、用错误、用教训、用痛苦才能真正体会其中的精髓的。所以,除了学习理论知识外,你还需要大量的工程实践。

软件设计的相关原则:

  • DRY(don't repeat yourself),要做到这点,我们需要做很多的抽象和泛型设计
  • KISS原则

宜家(IKEA)简约、高效的家居设计和生产思路;微软(Microsoft)“所见即所得”的理念;谷歌(Google)简约、直接的商业风格,无一例外地遵循了“KISS”原则。也正是“KISS”原则,成就了这些看似神奇的商业经典。而苹果公司的 iPhone 和 iPad 将这个原则实践到了极至。

  • Program to an interface, not an implementation,这是设计模式当中最根本的哲学,接口是抽象是稳定的,实现则是多种多样的。还有一条原则叫 Composition over inheritance(喜欢组合而不是继承),这两条是那 23 个经典设计模式中的设计原则。

  • You Ain't Gonna Need It (YAGNI),这个原则简而言之为——只考虑和设计必须的功能,避免过度设计。软件开发是一场 trade-off 的博弈。

  • Law of Demeter,迪米特法则 (Law of Demeter),又称“最少知识原则”(Principle ofLeast Knowledge)

  • 面向对象的SOLID原则

    • SRP(Single Responsibility Principle)- 职责单一原则,单一职责,通常意味着单一的功能,因此不要为一个模块实现过多的功能点,以保证实体只有一个引起它变化的原因。

    • OCP(Open/Closed Principle)- 开闭原则,其核心的思想是:模块是可扩展的,而不可修改的。

    • LSP(Liskov substitution principle)- 里氏代换原则,简化为一句话:Subtypes must besubstitutable for their base types,里氏替换原则 LSP是使代码符合开闭原则的一个重要保证。正是由于子类型的可替换性才使得父类型的模块在无需修改的情况下就可以扩展。

    • ISP(Interface Segregation Principle )- 接口隔离原则。接口隔离原则的意思是把功能实现在接口中,而不是类中,使用多个专门的接口比使用单一的总接口要好。举个例子,我们对电脑有不同的使用方式,比如:写作、通讯、看电影、打游戏、上网、编程、计算和数据存储等。

      如果我们把这些功能都声明在电脑的抽象类里面,那么,我们的上网本、PC 机、服务器和笔记本的实现类都要实现所有的这些接口,这就显得太复杂了。所以,我们可以把这些功能接口隔离开来,如工作学习接口、编程开发接口、上网娱乐接口、计算和数据服务接口,这样,我们的不同功能的电脑就可以有所选择地继承这些接口。

    • DIP(Dependency Inversion Principle)- 依赖倒置原则,高层模块不应该依赖于低层模块的实现,而是依赖于高层抽象

  • CCP——当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里。

  • 好莱坞原则,好莱坞原则就是一句话——“don't call us, we'll call you.”,所有的组件都是被动的,所有的组件初始化和调用都由容器负责,这也就是所谓“控制反转”的概念所在:1) 不创建对象,而是描述创建对象的方式。2)在代码中,对象与服务没有直接联系,而是容器负责将这些联系在一起。控制权由应用代码中转到了外部容器,控制权的转移,是所谓反转。好莱坞原则就是IoC(Inversion of Control) 或DI(Dependency Injection)的基础原则。

  • 高内聚、低耦合——内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身

  • CoC(Convention over Configuration)- 惯例优于配置原则 ,简单点说,就是将一些公认的配置方式和信息作为内部缺省的规则来使用。当你执行 mvn -compile 命令的时候,不需要指定源文件放在什么地方,而编译以后的 class 文件放置在什么地方也没有指定,这就是 CoC 原则。

  • SoC (Separation of Concerns) - 关注点分离,实现关注点分离的方法主要有两种,一种是标准化,另一种是抽象与包装

  • ADP——无环依赖原则