?求职经验(Java开发)
时间节点
-
对于我们专业的孩子来说,一般可以经历4次校招,分别是:
- 实习(3月份开始)
- 内推/提前批/管培生(6月份开始)
- 秋招(9月份开始)
- 春招(次年3月份开始)
-
不是要大家每个都参加,拿到心怡的offer就可以收手了,重点是注意下时间节点,越往后面的意味着你可能准备的更充分,但同时坑就那么多,越往后面坑越少。需要根据自己的能力和准备的充分程度来选择合适的入场时机,或者说根据自己计划的入场时间提前做准备。
-
同一家公司,参加前面的招聘,理论上或者说官方说明上是不影响下一次招聘的,但这应该不是事实上。事实上每次参加招聘都会在目标公司的招聘系统上留下“案底”,在下一次投递岗位的时候,“案底”会作为评估你的一个依据,好的“案底”就是加分项,太差的“案底”会让对方直接不考虑你了,毕竟招聘也是要花费时间和金钱的,对方也不想浪费时间。几次招聘在难度上没有太大的差异的,尽早参加可以让你提前经历笔试面试,知道面试官会问哪方面的问题,可以拿一些并不是很想去的公司提前练练手。
-
如果你不是大神,提前做准备是非常必要的(事实上大神也会做准备)。笔面试其实和备考差异不大,往年的笔试题、面试经验都是等效于划重点的宝贵材料。我曾经面试的一家公司,面试官拿着一个小册子问我,他说这是公司要求,公司列出了必考察的几个点,然后每个点列出了一些常见的问题供面试官参考,如果能提前熟悉这个小册子不就可以如鱼得水了。
-
当然不是每家公司都有这种小册子,面试前你也无法确定你的面试官,没有固定招数的面试官一般就会问自己熟悉的,不然他也无法确定你回答的正确度。举个例子,对于软件工程师这个岗位,一般投简历的时候Java工程师和C++工程师是两个岗位,细心点的公司面试的时候会让搞Java开发的去面试投递Java岗位的,搞C++的去去面试投递C++岗位的,但并不是所有公司都这样。我校招的时候除了几个算法岗,投的全是Java开发,我遇到的面试官有:
- 搞C++的,然后问我数据结构
- 搞Java的,问Java基础、集合源码、并发、JVM、算法
- 搞网络的,问TCP、HTTP、DNS
- 不会Java的,问数据库
-
总结一下,如果他不会你这门语言,而你投递的又是这个岗位,那他不会在语言与算法上难为你,这一环节就跳过了(算法一般是要你写的,你写了他不一定看得懂,所以就跟着跳过了),那么剩下的就问基础知识和项目经历了,知识面广一点的就问你:
- 数据结构
- 操作系统
- 数据库
- 计算机网络
知识面窄一点的就只问他会的。
-
如何关注每个公司招聘开始的时间节点:
- 可以参考牛客网校招日程
- 关注你心怡公司的招聘公众号,拿到一手官方消息
- 关注校园宣讲会
- 目标公司的熟人内推
- 可以参考牛客网校招日程
笔试
笔试一般就是选择题+编程题,不同的公司会有不同的比重,有些公司只有编程题,而国企可能选择题多一点。
选择题的内容主要涉及:
- 一门编程语言
- 数据结构与算法
- 设计模式
- 操作系统
- 计算机网络
- 数据库
编程题就是要你用代码去求解某个问题
笔试题的练习可以在赛码网或者牛客网 (活跃在牛客上还挺好玩的)
编程题的练习可以在leetcode或者leetcode中国,也可以在赛码网或者牛客网上练习各公司的往年编程题。
建议在练习的时候,每周将做过的题整理一遍,写上注释,放在一个持续更新的Project或者Repository中,就像我的这个Repository。在真正网上笔试的时候,大部分编程题是可以切出来在本地IDE上编程的,如果这道题你做过或者做过类似的,完全可以去翻你曾经的代码,然后直接套用或做简单的修改,比你再码一遍快的太多。
面试
在面试一家公司之前,我觉得至少要做这几项调研:
- 该公司是干什么的。重资产还是轻资产,是卖产品的还是卖服务的
- 你投递的这一岗位可能是干什么的
- 该公司的主要技术结构。比如阿里就是Java,腾讯C++,百度PHP,当然这是主要的技术结构,一家大型公司涉及的开发语言多达十几种,但总有一两个是主要的,而从事该语言开发的员工也是最多的,也就是说,需求这类职位比较多,同时你的面试官从事这个方向的概率比较高。就国内而言,整体来说,搞游戏的大部分是C++,卖嵌入式产品的C和C++,卖嵌入式产品和服务的C、C++和Java,互联网公司Java或者C++再加上前端,卖手机的C++、Java、Android、前端,等等。
- 几轮面试,每轮面什么。就我个人经历来说,一般的邀请到酒店大堂面试的,就两轮,一天搞定,第一轮技术面,过了就第二轮HR面或者第二轮是主管技术面,算是比较轻松的,过或者凉都很快。还有一类公司是一天只面一面,在面试官酒店房间一对一,完了让你回去等二面通知,这类一般3面以上,一面考你编程语言和算法基础,二面考你综合基础知识和项目经历,3面才HR或者主管面。
我将我之前面试准备的一些知识点罗列如下:
- Java基础
- 数据结构
- 队列
- 链表
- 数组
- 栈
- 堆
- 树
- 二叉树
- 完全二叉树
- 平衡二叉树
- 二叉查找树
- 红黑树
- B-,B+,B*树
- LSM树
- Set
- Map
- 算法
- 排序算法
- 选择排序
- 冒泡排序
- 插入排序
- 快速排序
- 归并排序
- 希尔排序
- 堆排序
- 计数排序
- 桶排序
- 基数排序
- 查找算法
- 二分查找
- 字符串比较
- KMP算法
- 布隆过滤器
- 深度优先
- 广度优先
- 贪心算法
- 回溯算法
- 动态规划
- 排序算法
- JVM
- JVM内存划分
- JVM内存溢出
- 垃圾回收
- 如何判断对象已死
- 回收算法
- 垃圾收集器
- 回收过程
- JVM性能优化
- 类加载
- 类的生命周期
- 类加载器
- Java集合源码
- Vector
- ArrayList
- LinkedList
- HashMap
- Hashtable
- HashSet
- TreeMap
- ConcurrentHashMap
- 数据库
- 三大范式
- 索引
- 引擎
- 事务
- 隔离
- 锁
- 数据库性能优化
- 并发
- 并发的优缺点
- 线程
- 创建线程
- 线程状态切换
- 线程的基本操作
- 守护线程
- 什么是线程安全
- 锁
- 公平锁&非公平锁
- 悲观锁&乐观锁
- 可重入锁&不可重入锁
- 互斥锁&共享锁
- 死锁
- 产生死锁的四个必要条件
- 预防和解除
- 构建死锁
- 查看死锁
- 并发理论
- JMM内存模型
- 重排序
- happens-before原则
- 并发关键字
- synchronized
- volatile
- final
- 原子性、可见性、有序性
- Lock体系
- Lock与Synchronized比较
- AQS
- AQS源码解析
- ReentrantLock
- ReentrantReadWriteLock
- Condition机制
- LockSupport
- 并发容器
- ConcurrentHashMap
- CopyOnWriteArrayList
- BlockingQueue
- ConcurrentLinkedQueue
- 线程池
- ThreadPoolExecutor
- ScheduledThreadPoolExecutor
- 原子操作类
- 并发工具
- CountDownLatch
- CyclicBarrier
- Semaphore
- Exchanger
- 并发实战:生产-消费者问题
- wait/notifyAll实现
- await/signalAll实现
- BlockingQueue实现
- 设计模式
- 23种常见的设计模式
- JDK中的设计模式
- Spring中的设计模式
- MyBatis中的设计模式
- Spring
- IOC
- AOP
- 操作系统
- 进程、线程、协程
- Linux命令行
- 网络
- OSI七层模型
- TCP/IP
- HTTP/HTTP2.0/HTTPS
- 长连接、短连接
- 网络模型
- Epoll
- Java NIO
- Netty
我将我之前面试准备的面试题目记录如下:
- 什么是二叉树
- B树与B+树
- TCP三次握手、四次挥手的过程
- 类加载器有哪些
- JVM垃圾回收算法
- 垃圾收集器
- HTTP请求和响应内容
- 线程创建方式
- HashMap和ConcurrentHashMap的实现原理
- TCP/IP协议簇有哪些常见协议
- Java线程池的核心属性以及处理流程
- Java并发包原理
- 线程的生命周期
- JVM类加载机制
- JVM内存模型
- 数据库有哪些索引,索引原理
- JVM内存溢出有哪些
- Java8有哪些新特性
- HTTP请求的GET和POST分别是什么
- Session、Cookie、Token的区别
- HashMap工作原理及代码实现,什么时候用到红黑树
- ConcurrentHashMap工作原理及代码实现,如何统计所有元素个数
- 线程和进有哪些程的概念
- 并行和并发的概念
- 进程间通信方式
- Semaphore原理
- Exchanger原理
- ThreadLocal原理,为什么会出现OOM,出现的深层次原因
- 线程池实现原理
- 线程池的几种实现方式
- 如何保证线程安全
- 重入锁的概念,重入锁为什么可以防止死锁
- 产生死锁的四个条件
- Volatile实现原理
- synchronized实现原理
- synchronized与lock区别
- CAS无锁的概念
- 乐观锁和悲观锁
- 什么是ABA问题
- 偏向锁、轻量级锁、重量级锁、自旋锁的概念
- JVM OOM和SOE的示例及原因,如何排查与解决
- 如何判断对象是否可以回收
- 类加载器、双亲委派模型、类的生命周期、类如何加载到JVM中
- JVM内存模型
- 常见设计模式
- 设计模式六大原则
- 红黑树
- 一致性Hash原理,Hash环问题
- BIO、NIO、AIO的概念
- 长连接与短连接
- HTTP/HTTP2.0/HTTPS的区别
- 从浏览器地址栏输入URL到页面加载之间发生了什么
- DDL/DML/DCL分别指什么
- 数据库事务的ACID
- 事务隔离级别
- InnoDB与MyISAM的区别
- 数据库索引类别
- 什么是自适应哈希
- 聚集索引与非聚集索引的区别
- 为什么使用B+树作为MySQL的索引
- Servlet生命周期
- Spring Bean生命周期
- Spring IOC如何实现
- Spring AOP如何实现
- Spring事务
- Spring MVC
- Tomcat基础架构
- Hash冲突解决办法
- ArrayList和LinkedList的默认空间是多少
- Object的Hashcode
- Collections与Arrays的sort方法默认的排序方法是啥
- 浅拷贝与深拷贝
- Java反射的作用与实现原理
- Java中的回调机制
- synchronized与ReentrantLock哪个是公平锁
- CAS机制会出现什么问题
- 一个线程调用start两次会出现什么情况
- Minor GC与Full GC分别在什么时候发生
- 垃圾收集器各自的特点
- Java在什么时候会出现内存泄露
- 自己写的类被什么类加载器加载,什么时候加载
- 软引用和弱引用
- 数据库四大范式
- 数据库死锁如何解决
- MySQL如何实现并发
- 内存的页面置换算法
- 进程调度算法
- TCP为什么可靠
- List与Set的区别
- List与Map的区别
- ArrayList与LinkedList的区别
- ArrayList与Vector的区别
- HashMap与Hashtable的区别
- HashMap与HashSet的区别
- 多线程情况下HashMap为什么会出现死循环问题
- 线程的状态是如何转移的
- AQS同步队列
- 常见原子操作类有哪些
- 乐观锁的业务场景及实现方式
- 什么是动态代理
- 最大堆与最小堆
- 单例模式的实现方法,Spring中单例的实现原理
- TCP与UDP的区别
- 使用线程池的好处
- Object类有哪些方法
- 数据库简历索引的优缺点
- HashMap如何扩容
- 大量数据去重问题
- 写SQL
参考资源
后记
- 上述提到的知识点没有做详细展开,一是时间有限,二是网上很容易搜到,很多人都比我解释的好,面试题目的答案也是一样。
- 这篇文章是我写给学弟学妹的毕业手册中的求职部分,完整的内容在我的github项目。