前言
已经记不清有多少读者问过:
博主,你是怎么学习的?像我这样的情况有啥好的建议嘛?
也不知道啥时候我居然成人生导师了。当然我不排斥这些问题,和大家交流都是学习的过程。
因此也许诺会准备一篇关于学习方面的文章;所以本文其实准备了很久,篇幅较长,大家耐心看完希望能有收获。
以下内容仅代表我从业以来所积累的相关经验,我会从硬技能、软实力这些方面尽量阐述我所认为的 “不那么差的程序员”
应当做到哪些技能。
技能树
作为一名码代码的技术工人,怎么说干的还是技术活。
既然是技术活那专业实力就得过硬,下面我会按照相关类别谈谈我们应该掌握哪些。
计算机基础
一名和电脑打交道的工种,计算机是我们赖以生存的工具。所以一些基础技能是我们应该和必须掌握的。
比如网络相关的知识。
其中就包含了 TCP 协议,它和 UDP 的差异。需要理解 TCP 三次握手的含义,拆、粘包等问题。
当然上层最常见的 HTTP 也需要了解,甚至是熟悉。
这块推荐《图解 HTTP》一书。
接着是操作系统相关知识。
由于工作后你写的大部分代码都是运行在 Linux 服务器上,所以对于这个看它脸色行事主你也得熟悉才行。
比如进程、线程、内存等概念;服务器常见的命令使用,这个没啥窍门就是得平时多敲敲多总结。
我也是之前兼职了半年运维才算是对这一块比较熟悉。
Linux 这个自然是推荐业界非常出名的《鸟哥的 Linux 私房菜》。
当作为一个初学者学习这些东西时肯定会觉得枯燥乏味,大学一般在讲专业课之前都会有这些基础学科。我相信大部分同学应该都没怎么仔细听讲,因为确实这些东西就算是学会了记熟了也没有太多直接的激励。
但当你工作几年之后会发现,只要你还在做计算机相关的工作,这些都是绕不开的,当哪天这些知识不经意的帮助到你时你会庆幸当初正确的选择。
数据结构与算法
接下来会谈到另一门枯燥的课程:数据结构。
这块当初在大学时也是最不受待见的一门课程,也是我唯一挂过的科目。
记得当时每次上课老师就让大家用 C 语言练习书上的习题,看着一个个拆开都认识的字母组合在一起就六亲不认我果断选择了放弃。
这也造成现在的我每隔一段时间就要看二叉树、红黑树、栈、队列等知识,加深印象。
算法这个东西我确实没有啥发言权,之前坚持刷了部分 LeetCode 的题目也大多停留在初中级。
但像基本的查找、排序算法我觉得还是要会的,不一定要手写出来但要理解其思路。
所以强烈建议还在大学同学们积极参与一些 ACM 比赛,绝对是今后的加分利器。
这一块内容可能会在应届生校招时发挥较大作用,在工作中如果你的本职工作是 Java Web
开发的话,这一块涉猎的几率还是比较低。
不过一旦你接触到了模型设计、中间件、高效存储、查询等内容这些也是绕不过的坎。
这块内容和上面的计算机基础差不多,对于我们 Java 开发来说我觉得平时除了多刷刷 LeetCode 加深印象之外,在日常开发中每选择一个容器存放数据时想想为什么选它?有没有更好的存储方式?写入、查询效率如何?
同样的坚持下去,今后肯定收货颇丰。
同时推荐《算法(第4版)》
Java 基础
这里大部分的读者都是 Java 相关,所以这个强相关的技能非常重要。
Java 基础则是走向 Java 高级的必经之路。
这里抛开基本语法不谈,重点讨论实际工作中高频次的东西。
- 基本容器,如:HashMap、ArrayList、HashSet、LinkedList 等,不但要会用还得了解其中的原理。这样才能在不同的场景选择最优的设计。
- IO、NIO 也是需要掌握。日常开发中大部分是在和磁盘、网络(写日志、数据库、Redis)打交道,这些都是 IO 的过程。
- 常见的设计模式如:代理、工厂、回调、构建者模式,这对开发灵活、扩展性强的应用有很大帮助。
- Java 多线程是非常重要的特性,日常开发很多。能理解线程模型、多线程优缺点、以及如何避免。
- 良好的单测习惯,很多人觉得写单测浪费时间没有意义。但正是有了单测可以提前暴露出许多问题,减少测试返工几率,提高代码质量。
- 良好的编程规范,这个可以参考《阿里巴巴 Java 开发手册》以及在它基础上优化的《唯品会 Java 手册》
《Java核心技术·卷 I》值得推荐。
多线程应用
有了扎实的基础之后来谈谈多线程、并发相关的内容。
想让自己的 title 里加上“高级”两字肯定得经过并发的洗礼。
这里谈论的并发主要是指单应用里的场景,多应用的可以看后文的分布式内容。
多线程的出现主要是为了提高 CPU 的利用率、任务的执行效率。但并不是用了多线程就一定能达到这样的效果,因为它同时也带来了一些问题:
- 上下文切换
- 共享资源
- 可见性、原子性、有序性等。
一旦使用了多线程那肯定会比单线程的程序要变得复杂和不可控,甚至使用不当还会比单线程慢。所以要考虑清楚是否真的需要多线程。
会用了之后也要考虑为啥多线程会出现那样的问题,这时就需要理解内存模型、可见性之类的知识点。
同样的解决方式又有哪些?各自的优缺点也需要掌握。
谈到多线程就不得不提并发包下面的内容 java.util.concurrent
。
最常用及需要掌握的有:
- 原子类:用于并发场景的原子操作。
- 队列。常用于解耦,需要了解其实现原理。
- 并发工具,如 ConcurrentHashMap、CountDownLatch 之类的工具使用以及原理。
- 线程池使用,以及相关原理。
- 锁相关内容:synchronized、ReentrantLock 的使用及原理。
这一块的内容可以然我们知道写 JDK 大牛处理并发的思路,对我们自己编写高质量的多线程程序也有很多帮助。
推荐《Java 并发编程的艺术》很好的并发入门书籍。
JVM 虚拟机
想要深入 Java ,JVM 是不可或缺的。对于大部分工作 1~3 年的开发者来说直接接触这一些内容是比较少的。
到了 3~5 年这个阶段就必须得了解了,以下内容我觉得是必须要掌握的:
- JVM 内存划分,知道哪块内存存放哪些内容;线程安全与否;内存不够怎么处理等。
- 不同情况的内存溢出、栈溢出,以及定位解决方案。
- 分代的垃圾回收策略。
- 线上问题定位及相关解决方案。
- 一个类的加载、创建对象、垃圾回收、类卸载的整个过程。
掌握这些内容真的对实际分析问题起到巨大帮助。
对此强力推荐《深入理解Java虚拟机》,这本书反反复复看过好几遍,每个阶段阅读都有不同的收获。
数据库
做 WEB 应用开发的同学肯定要和数据库打不少交道,而且通常来说一个系统最先出现瓶颈往往都是数据库,说数据库是压到系统的最后一根稻草一点也不为过。
所以对数据库的掌握也是非常有必要。拿互联网用的较多的 MySQL 数据库为例,一些必须掌握的知识点:
- 索引的数据结构及原理、哪些字段应当创建索引。
- 针对于一个慢 SQL 的优化思路。
- 数据库水平垂直拆分的方案,需要了解业界常用的 MyCAT、sharding-sphere 等中间件。
常规使用可以参考《阿里巴巴 Java 开发手册》中的数据库章节,想要深入了解 MySQL 那肯定得推荐经典的《高性能 MySQL》一书了。
分布式技术
随着互联网的发展,传统的单体应用越来越不适合现有场景。
因此分布式技术出现了,这块涵盖的内容太多了,经验有限只能列举我日常使用到的一些内容:
- 首先是一些基础理论如:CAP 定理,知道分布式系统会带来的一些问题以及各个应用权衡的方式。
- 了解近些年大热的微服务相关定义、来源以及对比,有条件的可以阅读
martin fowler
的原文 Microservices,或者也可以搜索相关的国内翻译。 - 对 Dubbo、SpringCloud 等分布式框架的使用,最好是要了解原理。
- 接着要对分布式带来的问题提出解决方案。如分布式锁、分布式限流、分布式事务、分布式缓存、分布式 ID、消息中间件等。
- 也要了解一些分布式中的负载算法:权重、Hash、一致性 Hash、故障转移、LRU 等。
- 最好能做一个实践如:[秒杀架构实践
](https://crossoverjie.top/%2F2...
之前有开源一个分布式相关解决组件:
https://github.com/crossoverJie/distributed-redis-tool
同时推荐一本入门科普《大型网站技术架构》,出版时间有点早,从中可以学习一些思路。
懂点架构
相信大家都有一个架构师的梦想。
架构师给人的感觉就是画画图纸,搭好架子,下面的人员来添砖加瓦最终产出。
但其实需要的内功也要非常深厚,就上面列举的样样需要掌握,底层到操作系统、算法;上层到应用、框架都需要非常精通。(PPT 架构师除外)
我自身参与架构经验也不多,所以只能提供有限的建议。
首先分布式肯定得掌握,毕竟现在大部分的架构都是基于分布式的。
这其中就得根据 CAP 理论结合项目情况来选择一致性还是可用性,同时如何做好适合现有团队的技术选型。
这里推荐下开涛老师的《亿级流量网站架构核心技术》,列举了很多架构实例,不过网上褒贬不一,但对于刚入门架构的能科普不少知识。
如何学习
谈完了技能树,现在来聊聊如何学习,这也是被问的最多的一个话题。
而关于学习讨论的最多的也是看视频还是看书?
视频
不得不承认视频是获取知识最便捷的来源,毕竟包含了图、文、声。
大学几年时间其实我也没好好上专业课,我记得真正入门 Java 还是一个暑假花了两个月的时间天天在家里看 ”马士兵“ 老师的视频教程,当时的资源也很老了,记得好像是 07 年出的视频(用的还是 Google )。
那段时间早起晚睡,每天学到东西之后马上实践,心里也很有成就感。后来开学之后一度成为同学们眼中的”学霸“人物。
现在打开我 12 年的电脑,硬盘里还躺着好几十 G 的教学视频。
看书
工作后时间真的很宝贵,完全没有了学生生涯的想学就学的自由。所以现在我主要知识来源还是书籍。
这些是我最近看的书:
看书又会涉及到电子书和纸质书的区别,我个人比较喜欢纸质书。毕竟我可以方便的记笔记以及可以随时切换章节。最主要的还是从小养成的闻书香的习惯。
知识付费
近几年知识付费越来越流行,许多大佬也加入了这个行列,人们也逐渐在习惯为知识去付费。
说实话写一好篇文章出一份视频都非常不容易,能有正向的激励,作者才能持续输出更好的内容。
这块我觉得国内做的比较好我也为之付费的有极客时间、大佬的知识星球等。
这三点没有绝对的好坏之分,其实可以看出我刚入门的时候看视频,工作之后看书及知识付费内容。
视频的好处是可以跟着里面老师的思路一步一步往下走,比较有音视频代入感强,就像学校老师讲课一样。
但由于内容较长使读者没法知晓其中的重点,甚至都不敢快进生怕错过了哪个重要知识,现在由于 IT 越来越火,网上的视频也很多导致质量参差不齐也不成体系。
而看书可以选择性的浏览自己感兴趣的章节,费解的内容也方便反复阅读
所以建议刚入门的同学可以看看视频跟着学,参与工作一段时间后可以尝试多看看书。
当然这不是绝对的,找到适合自己的学习方式就好。但不管是视频还是看书都要多做多实践。
打造个人品牌
个人品牌看似很程序员这个职业不怎么沾边,但在现今的互联网时代对于每个人来说都很重要。
以往我们在写简历或是评估他人简历的时候往往不会想到去网络搜索他的个人信息,但在这个信息爆炸的时代你在网上留下的一点印记都能被发现。
博客
因此我们需要维护好自己的名片,比如先搭建自己的个人博客。
博客的好处我也谈过几次了,前期关注人少没关系,重要的是坚持,当你写到 50、100篇文章后你会发现自己在这过程中一定是的到了提高。
GitHub
第二点就和技术人比较相关了:参与维护好自己的 GitHub。
由于 GitHub 的特殊属性,维护好后可以更好的打造个人品牌。
Talk is cheap. Show me the code
可不是随便说说的。
想要维护好可以从几个方面着手:
- 参与他人的项目,不管是代码库还是知识库都可以,先融入进社区。
- 发起自己的开源项目,不管是平时开发过程中的小痛点,还是精心整理的知识点都可以。
但这过程中有几点还是要注意:
- 我们需要遵守 GitHub 的社交礼仪。能用英文尽量就用英文,特别是在国外厂库中。
- 尽量少 push 一些与代码工作无关的内容,我认为这并不能提高自己的品牌。
别去刷 star
。这也是近期才流行起来,不知道为什么总有一些人会钻这种空子,刷起来的热度对自己并没有任何提高。
这里有一篇国外大佬写的 How to build your personal brand as a new developer
:
https://medium.freecodecamp.org/building-your-personal-brand-as-a-new-web-developer-f6d4150fd217
English 挺重要
再来谈谈英语的重要性,我记得刚上大学时老师以及一些培训机构都会说:
别怕自己英语差就学不了编程,真正常用的就那些词语。
这句话虽没错,但英语在对 IT 这行来说还是有着极大的加分能力。
拿常见的 JDK 里的源码注释也是纯英文的,如果英语还不错的话,一些 Spring 的东西完全可以自学,直接去 Spring 官网就可以查看,甚至后面出的 SpringCloud,官方资料就是最好的教程。
再有就是平时查资料时,有条件的可以尝试用 Google + 英文
搜索,你会发现新的世界。
不然也不会有面向 Google/Stack Overflow
编程。
对于英语好的同学自然不怕,那不怎么好的咋办呢?
比如我,但我在坚持以下几点:
- 所有的手机、电脑系统统统换成英语语言,养成习惯(不过也有尴尬的连菜单都找不到的情况)。
- 订阅一些英语周刊,比如 ”湾区日报“。
- 定期去类似于 https://medium.com/ 这样具有影响力的国外社区阅读文章。
虽然现在我也谈不上多好,但目前我也在努力,希望大家也一起坚持。
推荐一本近期在看的书《程序员的英语》。
保持竞争力
技术这个行业发展迅速、变化太快,每年也都有无数相关行业毕业生加入竞争,稍不留神就会被赶上甚至超越。
所以我们无时无刻都得保持竞争力。
多的谈不上,我只能谈下目前我在做的事情:
- 打好基础。不是学了之后就忘了,需要不停的去看,巩固,基础是万变不离其宗的。
- 多看源码,了解原理,不要停留在调参侠的境界。
- 关注行业发展、新技术、新动态至少不能落伍了。
- 争取每周产出一篇技术相关文章。
- 积极参与开源项目。