2021年的学习目标

前言

今年就是我找工作的一年了,看五月的仓颉大佬的文章有感而发,记录一下我2021年的Java学习目标。

转载:http://www.cnblogs.com/xrq730/p/5260294.html | https://www.cnblogs.com/xrq730/p/9159586.html

关于项目经验

LZ在网上经常看到一些别的朋友有提出项目经验的问题,依照LZ面试的感觉来说,面试主要看几点:项目经验+基本技术+个人潜力(也就是值不值得培养)。

关于项目经验,我认为并发编程网的创始人方腾飞老师讲的一段话非常好:

介绍产品时面试官会考察应聘者的沟通能力和思考能力,我们大部分情况都是做产品的一个功能或一个模块,但是即使是这样,自己有没有把整个系统架构或产品搞清楚,并能介绍清楚,为什么做这个系统?这个系统的价值是什么?这个系统有哪些功能?优缺点有哪些?如果让你重新设计这个系统你会如何设计?

我觉得这就已经足以概括了。也许你仅仅工作一年,也许你做的是项目中微不足道的模块,当然这些一定是你的劣势且无法改变,但是如何弥补这个劣势,从方老师的话中我总结几点:

  1. 明确你的项目到底是做什么的,有哪些功能
  2. 明确你的项目的整体架构,在面试的时候能够清楚地画给面试官看并且清楚地指出从哪里调用到哪里、使用什么方式调用
  3. 明确你的模块在整个项目中所处的位置及作用
  4. 明确你的模块用到了哪些技术,更好一些的可以再了解一下整个项目用到了哪些技术

在你无法改变自己的工作年限、自己的不那么有说服力的项目经验的情况下(这一定是扣分项),可以通过这种方式来一定程度上地弥补并且增进面试官对你的好感度。

补充一点,在面试中聊你的项目的时候,有一个问题90%是绕不过的:谈一下你在项目中解决过的比较复杂的问题。这需要在工作中不断去发现和探索,不需要多,在你自己目前的项目中只要你找到一两个能说的问题就行。一个小技巧是,即使问题不是你解决的而是别人解决的,但是你把这个问题弄懂、搞透了,在面试的时候你一样可以把这个问题当作是你自己解决的来说—-毕竟,谁来管这个问题当时到底是不是你解决的呢?

关于专业技能

写完项目接着写写一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、拿到的薪水势必也越高。

基本语法

这包括static、final、transient等关键字的作用,foreach循环的原理等等。今天面试我问你static关键字有哪些作用,如果你答出static修饰变量、修饰方法我会认为你合格,答出静态块,我会认为你不错,答出静态内部类我会认为你很好,答出静态导包我会对你很满意,因为能看出你非常热衷研究技术。

最深入的一次,LZ记得面试官直接问到了我volatile关键字的底层实现原理(顺便插一句,面试和被面试本身就是相对的,面试官能问这个问题同时也让面试者感觉到面试官也是一个喜爱研究技术的人,增加了面试者对公司的好感,LZ最终选择的就是问了这个问题的公司),不要觉得这太吹毛求疵了—-越简单的问题越能看出一个人的水平,别人对你技术的考量绝大多数都是以深度优先、广度次之为标准的,切记。

集合

非常重要,也是必问的内容。基本上就是List、Map、Set,问的是各种实现类的底层实现原理,实现类的优缺点。

集合要掌握的是ArrayList、LinkedList、Hashtable、HashMap、ConcurrentHashMap、HashSet的实现原理,能流利作答,当然能掌握CopyOnWrite容器和Queue是再好不过的了。另外多说一句,ConcurrentHashMap的问题在面试中问得特别多,大概是因为这个类可以衍生出非常多的问题,关于ConcurrentHashMap,我给网友朋友们提供三点回答或者是研究方向:

(1)ConcurrentHashMap的锁分段技术

(2)ConcurrentHashMap的读是否要加锁,为什么

(3)ConcurrentHashMap的迭代器是强一致性的迭代器还是弱一致性的迭代器

设计模式

本来以为蛮重要的一块内容,结果只在阿里巴巴B2B事业部面试的时候被问了一次,当时问的是装饰器模式。

当然咱们不能这么功利,为了面试而学习,设计模式在工作中还是非常重要、非常有用的,23种设计模式中重点研究常用的十来种就可以了,面试中关于设计模式的问答主要是三个方向:

(1)你的项目中用到了哪些设计模式,如何使用

(2)知道常用设计模式的优缺点

(3)能画出常用设计模式的UML图

多线程

这也是必问的一块了。因为三年工作经验,所以基本上不会再问你怎么实现多线程了,会问得深入一些比如说Thread和Runnable的区别和联系、多次start一个线程会怎么样、线程有哪些状态。当然这只是最基本的,出乎意料地,几次面试几乎都被同时问到了一个问题,问法不尽相同,总结起来是这么一个意思:

假如有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

聪明的网友们对这个问题是否有答案呢?不难,java.util.concurrent下就有现成的类可以使用。

另外,线程池也是比较常问的一块,常用的线程池有几种?这几种线程池之间有什么区别和联系?线程池的实现原理是怎么样的?实际一些的,会给你一些具体的场景,让你回答这种场景该使用什么样的线程池比较合适。

最后,虽然这次面试问得不多,但是多线程同步、锁这块也是重点。synchronized和ReentrantLock的区别、synchronized锁普通方法和锁静态方法、死锁的原理及排查方法等等,关于多线程,我在之前有些过文章总结过多线程的40个问题,可以参看40个Java多线程问题总结

IO

再次补充IO的内容,之前忘了写了。

IO分为File IO和Socket IO,File IO基本上是不会问的,问也问不出什么来,平时会用就好了,另外记得File IO都是阻塞IO。

Socket IO是比较重要的一块,要搞懂的是阻塞/非阻塞的区别、同步/异步的区别,借此理解阻塞IO、非阻塞IO、多路复用IO、异步IO这四种IO模型,Socket IO如何和这四种模型相关联。这是基本一些的,深入一些的话,就会问NIO的原理、NIO属于哪种IO模型、NIO的三大组成等等,这有些难,当时我也是研究了很久才搞懂NIO。提一句,NIO并不是严格意义上的非阻塞IO而应该属于多路复用IO,面试回答的时候要注意这个细节,讲到NIO会阻塞在Selector的select方法上会增加面试官对你的好感。

如果用过Netty,可能会问一些Netty的东西,毕竟这个框架基本属于当前最好的NIO框架了(Mina其实也不错,不过总体来说还是比不上Netty的),大多数互联网公司也都在用Netty。

JDK源码

要想拿高工资,JDK源码不可不读。上面的内容可能还和具体场景联系起来,JDK源码就是实打实地看你平时是不是爱钻研了。LZ面试过程中被问了不少JDK源码的问题,其中最刁钻的一个问了LZ,String的hashCode()方法是怎么实现的,幸好LZ平时String源代码看得多,答了个大概。JDK源码其实没什么好总结的,纯粹看个人,总结一下比较重要的源码:

(1)List、Map、Set实现类的源代码

(2)ReentrantLock、AQS的源代码

(3)AtomicInteger的实现原理,主要能说清楚CAS机制并且AtomicInteger是如何利用CAS机制实现的

(4)线程池的实现原理

(5)Object类中的方法以及每个方法的作用

这些其实要求蛮高的,LZ去年一整年基本把JDK中重要类的源代码研究了个遍,真的花费时间、花费精力,当然回头看,是值得的—-不仅仅是为了应付面试。

框架

老生常谈,面试必问的东西。一般来说会问你一下你们项目中使用的框架,然后给你一些场景问你用框架怎么做,比如我想要在Spring初始化bean的时候做一些事情该怎么做、想要在bean销毁的时候做一些事情该怎么做、MyBatis中$和#的区别等等,这些都比较实际了,平时积累得好、有多学习框架的使用细节自然都不成问题。

如果上面你的问题答得好,面试官往往会深入地问一些框架的实现原理。问得最多的就是Spring AOP的实现原理,当然这个很简单啦,两句话就搞定的的事儿,即使你不会准备一下就好了。LZ遇到的最变态的是让LZ画一下Spring的Bean工厂实现的UML图,当然面对这样一个有深度的问题,LZ是绝对答不出来的/(ㄒoㄒ)/~~

数据库

数据库十有八九也都会问到。一些基本的像union和union all的区别、left join、几种索引及其区别就不谈了,比较重要的就是数据库性能的优化,如果对于数据库的性能优化一窍不通,那么有时间,还是建议你在面试前花一两天专门把SQL基础和SQL优化的内容准备一下。

不过数据库倒是不用担心,一家公司往往有很多部门,如果你对数据库不熟悉而基本技术又非常好,九成都是会要你的,估计会先把你放到对数据库使用不是要求非常高的部门锻炼一下。

数据结构和算法分析

数据结构和算法分析,对于一名程序员来说,会比不会好而且在工作中绝对能派上用场。数组、链表是基础,栈和队列深入一些但也不难,树挺重要的,比较重要的树AVL树、红黑树,可以不了解它们的具体实现,但是要知道什么是二叉查找树、什么是平衡树,AVL树和红黑树的区别。记得某次面试,某个面试官和我聊到了数据库的索引,他问我:

你知道索引使用的是哪种数据结构实现吗?

LZ答到用的Hash表吧,答错。他又问,你知道为什么要使用树吗?LZ答到因为Hash表可能会出现比较多的冲突,在千万甚至是上亿级别的数据面前,会大大增加查找的时间复杂度。而树比较稳定,基本保证最多二三十次就能找到想要的数据,对方说不完全对,最后我们还是交流了一下这个问题,我也明白了为什么要使用树,这里不说,网友朋友们觉得索引为什么要使用树来实现呢?

至于算法分析,不会、不想研究就算了,记得某次面试对方问我,Collections.sort方法使用的是哪种排序方法,额,吐血三升。当然为了显示LZ的博学,对算法分析也有一定的研究(⊙﹏⊙)b,LZ还是硬着头皮说了一句可能是冒泡排序吧。当然答案肯定不是,有兴趣的网友朋友们可以去看一下Collections.sort方法的源代码,用的是一种叫做TimSort的排序法,也就是增强型的归并排序法。

Java虚拟机

出乎LZ的意料,Java虚拟机应该是很重要的一块内容,结果在这几家公司中被问到的概率几乎为0。要知道,LZ去年可是花了大量的时间去研究Java虚拟机的,光周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》,LZ就读了不下五遍。

言归正传,虽然Java虚拟机没问到,但我觉得还是有必要研究的,LZ就简单地列一个提纲吧,谈谈Java虚拟机中比较重要的内容:

  1. Java虚拟机的内存布局
  2. GC算法及几种垃圾收集器
  3. 类加载机制,也就是双亲委派模型
  4. Java内存模型
  5. happens-before规则
  6. volatile关键字使用规则

也许面试无用,但在走向大牛的路上,不可不会。

Web方面的一些问题

Java主要面向Web端,因此Web的一些问题也是必问的。LZ碰到过问得最多的两个问题是:

谈谈分布式Session的几种实现方式

常用的四种能答出来自然是让面试官非常满意的,另外一个常问的问题是:

讲一下Session和Cookie的区别和联系以及Session的实现原理

这两个问题之外,web.xml里面的内容是重点,Filter、Servlet、Listener,不说对它们的实现原理一清二楚吧,至少能对它们的使用知根知底。另外,一些细节的方面比如get/post的区别、forward/重定向的区别、HTTPS的实现原理也都可能会被考察到。

噢,想起来了,一致性Hash算法貌似也被问到了几次,这个LZ以前专门深入研究过并且写了两篇博文,因此问到这个问题LZ自然是答得毫不费力。文章是MemCache详细解读和对一致性Hash算法,Java代码实现的深入研究,特别说明,LZ真的不是在为自已以前写的文章打广告啊啊啊啊啊啊。

最后,如果有兴趣有时间,建议学习、研究一下SOA和RPC,面向服务体系,大型分布式架构必备,救命良方、包治百病、屡试不爽。

程序员技能目标

首先,前五年,如果一个程序员大致能做到一下几点(后面还会详谈):

  • 具有扎实的基本功
  • 能快速完成领导交给你的代码开发任务
  • 能在遇到问题的时候有正确的解决思路
  • 能对公司的新人进行一定辅导,包括但不限于技术点分享、代码评审、需求分析、表结构设计等

那么,从第五年开始,我认为可以、也应当朝更高的层次进行迈进,前一个层次如果更多是偏重个人,那么这个层次我认为更多应该偏重团队,简单罗列一下大致上应该有:

  • 系统设计能力,或许在之前给一个功能,能从DB设计–>服务端开发–>前端开发一栈把事情都做好,那么之后,在领导给出具体一块大业务,比如想做一个淘宝商场的会员模块,能充分分析出整个功能并把功能拆分成一个一个的点、能对每一个点之间的交互画出交互图、能梳理清楚数据库的ER关系图、能把工作合理分配给同事进行开发
  • 带领团队能力,大致就是把控整体开发节奏,保证在约定时间点前进行交付,不出现延期的情况
  • 大而博不如小而美,会10门技术、每门技术掌握到6分,不如会5门技术、2门技术掌握到8分,我感觉整个行业什么都会一点的人比较多,把一门技术进行深入研究的比较少,毕竟掌握也许只需要1星期,深耕或许需要1个月甚至更久。在五年这个节点,我认为选择一到两个自己感兴趣的方向进行深入研究会是一个比较好的选择

2021年学习目标

为什么之前说针对面试题进行学习和准备作用不大,因为我认为我们关注的不应当是题,而是题背后的一个一个的方向,这也就是我认为的基本功。那从基本功的角度来说,罗列一下我能想到的,包括但不限于以下内容:

  • 工作相关使用到的JDK类及其相关源码、机制
  • 设计模式,设计模式在工作中用到了哪些,具体使用场景
  • 并发类的相关知识,线程安全、锁机制、信号量、闭锁、栅栏、线程池等
  • 框架相关,Spring相关机制、Spring MVC相关机制、MyBatis相关机制、使用的细节点、框架实现原理等
  • JVM,内存布局、垃圾识别算法、垃圾回收算法、垃圾收集器、类加载机制、内存模型、出现内存问题时定位问题的方法等
  • 数据库的基本数据类型、索引机制、各引擎区别、锁机制、慢SQL定位及优化等
  • 缓存机制,这里的机制指的是缓存加载、缓存击穿、缓存雪崩这些机制及其相关应对方案,用过Redis、MemCache的最好理解一下它们的原理或者缓存提供的一些高级功能,集群如何实现
  • 分布式的一些知识,比如CAP理论、数据一致性的几种解决方案、分布式事务如何处理、分库分表怎么做、现有的相关解决方案等
  • NIO的作用,epoll模型是否知道一些,Netty的相关机制、Netty相比原生NIO的优点、半包拆包、断线重连解决方案等
  • Web相关,Get与Post的区别、转发与重定向的区别、跨域问题如何解决、如何保证接口幂等性等
  • 网络层相关,三次握手和四次握手、全连接队列和半连接队列、负载均衡算法等
  • 其他中间件,MQ作用和使用场景、服务化治理框架的作用和使用场景、配置中心的作用和使用场景等
  • 数据结构,数组、链表、栈、队列、树等优缺点,在什么场景下使用什么数据结构
  • Linux相关知识,基本命令的使用,排查日志、定位问题,项目或者第三方组件的基本运维等

坦白讲,以上的这些东西全都掌握也不可能,哪怕面试官肯定也有很多不会的,但这就是基本功,能多掌握一点多掌握一点,技多不压身,至于别人如何评价你,就留给别人去评价吧,做好自己能做好的就行了。我在之前写过的文章中反复强调深度+广度,深度优先、广度次之,有了深度+广度,在开发过程中我们可以尽快完成需求,在遇到问题情况下我们可以第一时间找到应对方案。

在三年的时间点,能掌握上述的知识点我认为已经是非常非常优秀的了,但这两年的经历让我意识到的是,到了五年的时间点,如果只是具备这些硬性技能,还是不够,这两年更多的应当是在项目上进行积累,也就是前面说的项目,大致上应该有:

  • 独立完成复杂业务,或者完成一个已有项目中的大功能点,这就需要有根据业务对功能进行分解、分析的能力
  • 独立排查复杂问题,在项目运行过程中,一定不可能安然无事,除开业务性的问题,CPU 100%是否能独立排查、内存溢出是否能独立排查、应用死锁或者DB死锁能否独立排查、API调用时间长能否独立排查,以上问题排查完毕能否及时解决
  • 带领团队的能力,可能这时候带领的是1~2个人的小团队,即使一个小团队,也能考验带团队、任务合理分配的能力

可能上面的要求有点高,可能工作中未必有这样的机会,但是不要抱怨,机会永远留给有能力、有准备的人,我们首先想的不应该是等待别人交给你一件有挑战性的事情,你在做这件事情的情况下去提升自己,而应当是先提升自己的素质,然后让别人放心把有挑战性的事情交给你来做。


   转载规则


《2021年的学习目标》 锦泉 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录