《程序员练级攻略》 阅读总结
前言
陈皓叔叔的这个专栏之前就有所耳闻并大致过了一遍,如今重新精读本专栏,认真学习,对整体的学习方向进行把握,并且进行总结。
如何入门?
学习Python,JavaScript,学习使用操作系统Linux,编程工具VS Code,Web开发等,这些更容易获得编程的成就感。
如何成为专业的程序员?
拥有程序员的自我修养。这是反映出程序员的工程师特质和价值观,决定了这条路你到底能走多远。有修养的程序员才可能成长为真正的工程师和架构师,没有修养的程序员智能沦为码农,这是码农和工程师的关键区分点。
- 英文能力
- 提问的能力
- 写代码的修养
- 重构:改善既有代码的设计
- 代码整洁之道
- 程序员的职业素养
- Code Review
- 对自我成长非常有帮助
- 不做Code Review的公司没有必要呆
- Unit Test
- 安全防范意识
- 代码安全
- 防御性编程
- 软件工程和上线规范
- 编程规范
专业基础包括哪些?
- 编程语言:推荐C、C++、Java这三个工业级的编程语言。
- 理论学科:数据结构和算法,计算机网络,计算机组成原理,操作系统,编译原理
从业方向?
- 如果你对操作系统、文件系统、数据库、网络等比较感兴趣,那么可以考虑从事底层方面的工作。
- 如果对分布式系统架构、微服务、DevOps、Cloud Native 等有热情,那么可以从事架构方面的工作。
- 如果是对大数据、机器学习、人工智能等比较关注,那么数据领域可以成为你一展身手的地方。
- 如果你对用户体验或者交互等更感兴趣,那么前端工程师也是个不错的选择。
- 此外,安全开发、运维开发、嵌入式开发等几大方向中,也为你提供了丰富多彩的发展空间。
两个观点:
- 各种技术方向不是鱼和熊掌,是可以兼得的。
- 很多技术都是相通的,关键是要学的深入本质。
几个问题:
- 理论和现实的差距:学院派的知识是成为专家的必经之路,这就是“工人”和“工程师”的差别,是“建筑工人”和“建筑架构师”的差别。
- 技术太多学不过来/技术能力的瓶颈:自己懒惰的借口,以绝大多数人努力的程度,和为自己不努力找借口的程度为参考,只要你坚持正常的学习就可以超过大多数人了。
学习建议?
- 一定要坚持,要保持长时间学习,甚至终身学习的态度。
- 一定要动手,不管例子多么简单,建议至少自己动手敲一遍看看是否理解了里面的细枝末节。
- 一定要学会思考,思考为什么会这样,要学会举一反三。
- 不要乱买书,不要乱追新技术新名词,基础的东西经过很长时间积累,会在未来至少十年通用。
编程入门
- 入门语言Python
- 入门语言JavaScript
- 操作系统LInux
- 编程工具VS Code
- Web入门
正式入门
- 编程技能
- 编程技巧
- 编程语言
- Java
- 操作系统
- 网络协议
- 系统了解HTTP协议
- 数据库设计
- 基本的设计知识
- MySQL必知必会
- 前端
- Vue
- 字符编码方面
为什么转成Java语言?
- Java语言的综合实力最强,是一个工业级的编程语言。
- 像 Python 和 JavaScript 这样的动态语言用着是很爽,但是,只有像 C、C++ 和 Java 这样的静态语言才可以让你真正地进阶。
- 对于一个合格的程序员,掌握几门语言是非常正常的事情。
编程工具
- IDE
- 版本管理工具
- 前端调试
- 数据库设计工具
编程语言
Java
这本书本来是 Sun 公司的官方用书,是一本 Java的入门参考书。对于 Java 初学者来说,是一本非常不错的值得时常翻阅的技术手册。书中有较多地方进行 Java 与 C++ 的比较,因为当时 Java 面世的时候,又被叫作 “C++ Killer”。而我在看这本书的时候,发现书中有很多 C++ 的东西,于是又去学习了C++。学习 C++ 的时候,发现有很多 C 的东西不懂,又顺着去学习了 C。然后,C ->C++ -> Java 整条线融汇贯通,这对我未来的技术成长有非常大的帮助。
这本书是模仿 Scott Meyers 的经典图书《Effective C++》的。Effective 这种书基本上都是各种经验之谈,所以,这是一本非常不错的书,你一定要读。这里需要推荐一下 Google Guava 库 ,这个库不但是 JDK 的升级库,其中有如:集合(collections)、缓存(caching)、原生类型支持(primitives support)、并发库(concurrency libraries)、通用注解(common annotations)、字符串处理(string processing)、I/O 等库,其还是Effective Java 这本书中的那些经验的实践代表。
是一本完美的 Java 并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容。最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。
通过学习这本书,你可以比较大程度地提升性能测试的效果。其中包括:使用 JDK 中自带的工具收集 Java 应用的性能数据,理解 JIT 编译器的优缺点,调优JVM 垃圾收集器以减少对程序的影响,学习管理堆内存和 JVM 原生内存的方法,了解如何最大程度地优化 Java 线程及同步的性能,等等。看完这本书后,如果你还有余力,想了解更多的底层细节,那么,你有必要去读一下《深入理解 Java 虚拟机》。
真是一本透着编程思想的书。上面的书让你从微观角度了解 Java,而这本书则可以让你从一个宏观角度了解 Java。这本书和 Java 核心技术的厚度差不多,但这本书的信息密度比较大。所以,读起来是非常耗大脑的,因为它会让你不断地思考。对于想学好 Java 的程序员来说,这是一本必读的书。
学Java一定要学面向对象的设计模式,两本书:
学习设计模式,不能迷失在23个设计模式种,一定要明白两个原则:
Program to an ‘interface’, not an ‘implementation’
- 使用者不需要知道数据类型,结构,算法等细节。
- 使用者不需要知道实现细节,只需要知道提供的接口。
- 利用封装,抽象,动态绑定,多态等符合面向对象的特质和理念。
Favor ‘object composition’ over ‘class inheritance’
- 继承需要给子类暴露一些父类的设计和实现细节。
- 父类实现的改变会造成子类也需要改变。
- 我们以为继承主要是为了代码重用,实际上在子类中需要重新实现很多父类的方法。继承更多的应该是为了多态。
Java字节码相关
- 相关教程和工具
JVM相关
- The Java Virtual Machine Specification Java SE 8 Edition
- JSR-133
- 垃圾回收机制
- 垃圾回收调优
上面的这些知识融会贯通,已经是高级的Java程序员了。
C/C++语言
Go
理论学科
数据结构和算法
无论是做业务还是做底层系统,经常需要使用算法处理各种问题,例如:业务上需要算法比较两个数组中差异的布隆过滤器,或者是在监控系统实时计算过去一分钟的P99统计时的蓄水池算法,或者是数据库的B+树索引,还是Linux内核中的
epoll
或者TreeMap
中的红黑树。还有做任务调度的背包问题等都会用到数据结构和算法。
书籍:
- 《深入理解计算机系统》
- 《Unix高级环境编程》
- 《Unix网络编程》
- 《TCP/IP详解 卷I协议》
- 《Linux C编程一站式学习》
- 《TCP/IP网络编程》
- 《图解TCP/IP》
- 《Wireshark数据包分析实战》
软件设计
一些软件设计的相关原则:
- Don’t repeat yourself
- KISS principle
- Program to an interface, not an implementation:设计模式中最根本的哲学,注重接口,而不是实现,依赖接口,而不是实现。
- You aren’t gonna need it
- Law of Demeter
- 面向对象的SOLID原则
- Hollywood principle
- 高内聚低耦合
- CoC(Convention over Configuration)- 惯例优于配置原则
- SoC (Separation of Concerns) - 关注点分离,实现关注点分离的方法主要有两种,一种是标准化,另一种是抽象与包装
- DbC(Design by Contract):契约式设计
- ADP(Acyclic Dependencies Principle):无环依赖原则
一些软件设计的读物:
- 领域驱动设计
- UNIX编程技术
- Clean Architecture
Linux系统
内存
计算机网络
- 基础知识
- 网络调优
- 网络协议
I/O模型
- 阻塞I/O
- 非阻塞I/O
- I/O的多路复用(select、poll)
- 信号驱动的I/O(SIGIO)
- 异步I/O(POSIX的aio_functions)
Lock-Free编程相关
如果想开发出一个高性能的程序,你就非常有必要学习Lock-Free
的编程方式。
- 相关的概念
- 论文
- 博客
- 现有的实现,C++/Java类库
其它
- 64位系统编程
- 提高OpenSSL的执行性能
- 压缩
- SSD硬盘性能测试
数据库
- 关系型数据库
- MySQL官方手册
- 高性能MySQL
- MySQL技术内幕:InnoDB存储引擎
- 数据库的索引设计与优化
- 非关系型数据库
- 各类论文
分布式架构
- 服务调度
- 涉及服务发现、配置管理、弹性伸缩、故障恢复等。
- 资源调度
- 涉及对底层资源的调度使用、如计算资源、网络资源和存储资源等。
- 流量调度
- 涉及路由、负载均衡、流量控制、熔断等。
- 数据调度
- 涉及数据副本、数据一致性、分布式事务、分库分表等。
- 容错处理
- 涉及隔离、幂等、重试、业务补偿、异步、降级等。
- 自动化运维
- 涉及持续集成、持续部署、全栈监控、调用链跟踪等。
几个注意点:
- 分布式系统之所以复杂,就是因为它太容易出错了。这意味着,你要把处理错误的代码当成正常功能的代码来处理。
- 开发一个健壮的分布式系统的成本是单体系统的几百倍甚至几万倍。这意味着,我们要自己开发一个,需要能力很强的开发人员。
- 非常健壮的开源的分布式系统并不多,或者说基本没有。这意味着,如果你要用开源的,那么你需要 hold 得住其源码。
- 管理或是协调多个服务或机器是非常难的。这意味着,我们要去读很多很多的分布式系统的论文。
- 在分布式环境下,出了问题是很难 debug 的。这意味着,我们需要非常好的监控和跟踪系统,还需要经常做演练和测试。
- 在分布式环境下,你需要更科学地分析和统计。这意味着,我们要用 P90 这样的统计指标,而不是平均值,我们还需要做容量计划和评估。
- 在分布式环境下,需要应用服务化。这意味着,我们需要一个服务开发框架,比如 SOA或微服务。
- 在分布式环境下,故障不可怕,可怕的是影响面过大,时间过长。这意味着,我们需要花时间来开发我们的自动化运维平台。
分布式架构入门
- 分布式理论
- 各种理论算法
- 论文
- 一致性问题
- 分布式事务
- Paxos一致性算法
- Raft一致性算法
- Gossip一致性算法
- 分布式存储和数据库
- 分布式信息系统
- 日志和数据
- 分布式监控和跟踪
- 数据分析
分布式架构工程设计
- 论文
- 分布式设计模式
- 可用性
- 数据管理
- 设计和实现
- 消息
- 管理和监控
- 性能和扩展
- 系统弹力
- 安全
- 设计与工程实践
- 分布式系统的故障测试
- 弹性伸缩
- 一致性哈希
- 数据库分布式
- 缓存
- 消息队列
- 日志方面
- 性能方面
- 搜索方面
- 公司的架构实践
容器化和自动化运维
Docker
- 基础知识
- 实践
- 底层技术细节
Kubernetes
Kubernetes 是 Google 开源的容器集群管理系统,是 Google 多年大规模容器管理技术
Borg 的开源版本,也是 CNCF 最重要的项目之一,主要功能包括:
- 基于容器的应用部署、维护和滚动升级;
- 负载均衡和服务发现;
- 跨机器和跨地区的集群调度;
- 自动伸缩;
- 无状态服务和有状态服务;
- 广泛的 Volume 支持;
- 插件机制保证扩展性。
如何学习?
- Kubernetes handbook
- Kubernetes指南