开头瞎扯几句:都说金九银十,其实大厂九月份就差不多结束了,十月份都在耍猴。秋招给我最大的感受就是提前批不敢冲的都凉了,所以劝学弟学妹们准备的越早越好,提前批真的不难冲就完事了。现在十月中旬了,过了一个国庆完全没学习,以至于现在看题都进不了状态,干脆发个帖子把自己整理的和面试被问到的面试题发出来,顺便自己也对这问题叙述一遍(一点点发...)。
ps:说一下面试感受,其实面经千千万,大家都差不多,现在但凡叫得出名字的公司都不会问原题了。面试要么是细节,要么是深挖,这二者单靠面经是不行的,纯背面经,一问就胯。
pps:我这里只是一点面经整理,其实还有一大把书籍,blog的笔记,应该会陆陆续续发出来的吧,其实都放github上了..但是乱的一批还没整理。
ppps: 下面的以及以后可能发的所有东西都不是纯原创,借鉴以及抄了一大堆书籍,blog,公众号,我会努力在参考书目里面写上的(半年那么多资料很多记不住了...),看到此贴的可以直接去原作者那里看原文
网络
- 简述TCP/IP 模型 和 OSI 的七层协议模型
- tcp 和 udp 的区别
- TCP和UDP的报文结构
- TCP 校验和的目的
- TCP 怎么保证可靠传输
- 三次握手,四次挥手(TCP连接异常分析)
- 为什么会出现 timewait 过多?TCP 协议的 TIME_WAIT 状态详解
- TCP 拥塞控制
- TCP 流量控制
- HTTP报文结构
- HTTP 方法/协议状态码
- HTTP 幂等性及 GET、POST、PUT、DELETE 的区别和有无幂等性
- HTTP 缓存机制
- 既然 HTTP 是无状态的,那服务器怎么记住上次请求的用户? Session、Cookie、Token,文章很好
- HTTP 1.0/1.1/2.0/3.0 的区别
- http 安全问题/HTTPS 握手过程
- 老套路题了URL输入浏览器的过程
- DNS 实现的机制
- 幂等性设计:《大型网站技术构架》 P78
- restful
面试应该有的水平:可以全部联系在一起讲,并且大多数问题都可以流畅扯3-5min。
参考书目:
★★★★★:《图解HTTP》《小林coding图解网络》 极力推荐,先看第一个再看第二个,基本网络面试可以comb了...非常感谢小林老哥写的公众号他给我网络的大坑中补了不少土,上面所有问题小林的网络都可以解决,我上面的问题远远不够,请去看小林的网络...大爱
★★★:《计算机网络自顶向下方法》
Java 基础
- 集合类遍历时是否可以修改---
如果我非要修改呢
- [StringBuilder 是怎么扩容的(默认 16,2x+2)]
- ArrayList 和 LinkedList 的区别
- Java 泛型
泛型就是参数化类型,他相当于一个守门员,来控制什么可以放入集合,什么不可以放入,以来增加安全性,而来避免了强制类型转换。 泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉(编译结束之后),所以java也被称之为伪泛型。 好处: 代码更加简洁【不用强制转换】 程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常】 可读性和稳定性【在编写集合的时候,就限定了类型】 之前泛型类中的类型参数部分如果没有指定上限,如 < T > 则会被转译成普通的 Object 类型,如果指定了上限如 < T extends String> 则类型参数就被替换成类型上限。 上界<? extends T>不能往里存,只能往外取。是编译器只知道容器内是Fruit或者它的派生类,但具体是什么类型不知道。 List<? extends Integer> l1 =new LinkedList<>(Arrays.asList(1,2,3)); 下界<? super T>不影响往里存,但往外取只能放在Object对象里。因为下界规定了元素的最小粒度的下限,实际上是放松了容器元素的类型控制。 List<? super Integer> l2 = new LinkedList<>();
泛型的类型擦除是指把某个具体的泛型引用在编译期完成类型检查后,擦除成了Object而丢失了它运行时所赋予的类型信息。 对于反射获得的泛型,必须是类本身的类型信息(实际上这里的泛型是被硬编译到字节码中的),对于传入的泛型参数是没有办法的。 在类加载阶段,JVM就将字节码中写死的泛型信息保存了下来。 对于类泛型引用来说,它们的泛型信息不来自于自身的class,在编译完成通过类型检查后,类型系统中它们就等同于Object,这种泛型是无法通过反射获取的,也就是说这类类型信息被擦除了
在没有泛型之前,从集合读取到的每一个对象都必须进行转换。如果有人不小心插入了类型错误的对象,在运行时的转换处理就会出错。有了泛型之后,可以告诉编译器每个集合中接受哪些对象类型。编译器自动地为你的插入进行转化,并在编译时告知是否插入了类型错误的对象。这样可以使程序既更安全,也更清楚。
- HashMap 什么对象能做为 key?
- 如何实现 hashmap 的只读不可写,不采用其他工具
- this 关键字--super 与 this 异同,我觉得这问题贼蠢
- main 方法中 String[] args 为什么要使用 String?main 方法的返回值为什么是 void
- 四类八种基础数据类型及其包装类
- 讲一下装箱拆箱-
从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是 Integer 的 valueOf(int)方法。而在拆箱的时候自动调用的是 Integer 的 intValue 方法。
- 详细论述Integer 的缓存机制
- Object 的方法
- Java Collection-容器---
容器的一个接口路线,从iterator往下,两个,一个map,一个Collection,map下面的hashmap,treemap,Collection下面的list,Set。list下面的ArrayList和LinkedList,Set下面的hashSet和TreeSet等,吹一下迭代器的快速失败和安全失败
- HashMap 源码级别的原理,rehash 是什么---
Hashmap的缩容,扩容机制
---位运算的好处
---hashmap和hashtable区别,模运算比较
---为什么使用红黑树
- 说一下 concrrentHashMap
- treemap 底层数据结构,扩容,插入删除效率
- 链表什么时候转成红黑树,以及为什么转成红黑树;
- 异常你了解吗?有哪些
- 面向对象三大特征---
主要是多态
- 多态的底层原理?(JVM)
- 抽象类和接口
- Java 成员变量(类变量,实例变量)---类方法和常量属性,成员属性,局部变量。
- ==StringBuilder 和 StringBuffer//String== 为什么设计成 final 不可变? 是怎么实现不可变的
- static 用法
- 内部类和静态内部类的区别
从字面上看,一个被称为静态嵌套类,一个被称为内部类。 从字面的角度解释是这样的:嵌套就是我跟你没关系,自己可以完全独立存在,但是我就想借你的壳用一下,来隐藏一下我自己。 1. 一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类。 2. 静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。 3. 静态内部类不需要持有外部类的引用 什么是内部?内部就是我是你的一部分,我了解你,我知道你的全部,没有你就没有我。(所以内部类对象是以外部类对象存在为前提的) 1. 内部类可以访问其所在类的属性(包括所在类的私有属性),内部类创建自身对象需要先创建其所在类的对象。 2. 可以定义内部接口,且可以定义另外一个内部类实现这个内部接口。 3. 内部类不能定义static元素。
- Java 内部类为什么能够访问外部成员变量--内部类能否引用外部类的 private 成员(被 private 修饰的内部类只能在它所属的外部类中访问)
- Java 的继承有什么缺点
- equals 和 hashcode 为什么要一起重写。一个类,如果重写了 Equals(),不重写 HashCode(),会有什么问题(==重写 hashcode(),主要是针对映射相关的操作(Map 接口,依靠具体值生成 hashcode)==,仅仅重载 equals 方法可能会导致实际业务逻辑失败,确保 equals 相同 hashcode 也相同,即保证相同对象的 hashcode 一定相同
- 反射机制( 920 P104)
- 反射的应用场景,为什么需要反射?
.Class, Class.forName, .getClass()
的区别- 注解是什么
注解本质是一个继承了 Annotation 的特殊接口,会在Java 运行时生成的动态代理类。 我们通过反射获取注解时,返回的是运行时生成的动态代理对象。 通过代理对象调用AnnotationInvocationHandler的invoke方法。 该方***从 memberValues 这个 Map 中索引出对应的值。而 memberValues的来源是 Java 常量池。
- 静态代理、动态代理和 CGLib 的区别:
代理模式:不改变原目标对象的前提下,通过代理对象来实现功能增强的办法。 静态代理:这种代理方式需要代理对象和目标对象实现一样的接口。由于前者,如果要代理多个对象,就会产生多个代理类。 动态代理:动态代理利用了JDK API,动态地在内存中构建代理对象,从而实现对目标对象的代理功能。 优点:动态代理对象不需要实现接口,只要求目标对象必须实现InvocationHandler,通过反射代理方法,比较消耗系统性能。 静态代理与动态代理的区别主要在: 静态代理需要自己写代理类-->代理类需要实现与目标对象相同的接口 动态代理不需要自己编写代理类--->(是通过反射动态生成的),动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中。 CGlib:cglib代理无需实现接口,通过生成类字节码实现代理,比反射稍快,不存在性能问题,但cglib会继承目标对象,需要重写方法,所以目标对象不能为final类。
- Java 中的 NIO
- IPC 方式进程间通信方式
只包含最基础的部分,没有并发和jvm
参考书目:
★★★★★:《thinking in java》,牛客,百度,google...
JVM 重点
Java 内存区域模型
java 中变量在内存区域中存储的位置
四种引用类型
详细论述 JVM 的垃圾垃圾回收机制
GC 算法
gcroot 对象有哪些
常见的垃圾回收器及他们之间区别,垃圾回收发生在哪里
新生代老年代大小如何划分
JVM 调优命令
怎么避免产生浮动垃圾(等于为什么 G1 没有浮动垃圾)?
synchronized 的用法,类锁和对象锁的区别
synchronized 膨胀过程和细节
lock 和 synchronized 区别
volitile 关键字的理解
synchronized 和 volitile 的区别
详细论述类加载器
双亲委派模型 本质/用处
如何破坏双亲委派机制(1.自定义 ClassLoader 并重写父类方法)2. SPI 就是经典的打破
JVM 虚拟机启动是单线程的还是单进程的?
画一下 Java 的内存模型(Java 内存模型来屏蔽掉各种硬件和操作系统的内存访问差)
Java 原子性指令-8 个指令
先行原则
Java 内存泄漏如何排查排查
类初始化时机:1. new/2.反射/3.子类初始化,父类也初始化/4.Java 虚拟机启动时被标名为启动类的类(Main)
1.8 开始方法区到底被拆分成啥玩意了:
- 首先确定的一点,各种分区只是《虚拟机规范》的一种逻辑概念,不同的虚拟机有不同的实现方式。林我改方法区从 8 开始不再是那么明确的区域而是逻辑。
- 符号引用转移到到了 native heap(直接内存);字面量转移到了 java heap;类的静态变量转移到了 java heap 中
- Metaspace 存储的事类的元数据信息
- 元空间的本质和永久代类似,都是堆 JVM 规范中的方法区的实现。不过原空间不在虚拟机中,而是使用本地内存。
- ==替换的好处:==
- 字符串存在永久代中,容易内存溢出。
什么情况下会内存溢出,内存泄漏?
对象是可达的,但是对象不会被引用 public static void main(String[] args) { Set set = new HashSet(); for (int i = 0; i < 10; i++) { Object object = new Object(); set.add(object); // 设置为空,这对象我不再用了 object = null; } // 但是set集合中还维护这obj的引用,gc不会回收object对象 System.out.println(set); }
内存溢出的原因:
- 内存泄露导致堆栈内存不断增大,从而引发内存溢出。
- 大量的 jar,class 文件加载,装载类的空间不够,溢出
- 操作大量的对象导致堆内存空间已经用满了,溢出
- nio 直接操作内存,内存过大导致溢出
解决: - 查看程序是否存在内存泄漏的问题
- 设置参数加大空间
- 代码中是否存在死循环或循环产生过多重复的对象实体、
- 查看是否使用了 nio 直接操作内存。
说说虚拟机栈
每个 Java 线程都有自己的独立 JVM 栈,当方法调用的时候会生成一个栈帧,保存了方法的局部变量表,操作数栈等。线程运行过程中只有一个栈帧是活跃的,即栈顶。JVM 频繁 FullGC,如何排查
当统计得到的 Minor GC 晋升到旧生代的平均大小大于老年代的剩余空间,则会触发 full gc==(这就可以从多个角度上看了)==- 是不是频繁创建了大对象(也有可能 eden 区设置过小)(大对象直接分配在老年代中,导致老年代空间不足--->从而频繁 gc)
- 是不是老年代的空间设置过小了(Minor GC 几个对象就大于老年代的剩余空间了)
类实例顺序:1. 父类静态成员+静态初始化块。2.子类静态成员+静态初始化块 3.父类实例成员和实例初始化块。4.父类构造方法。5.子类实例成员和实例初始化块。6.子类构造方法。
JVM 参数
这里不全,日后再补。
ps:我觉得jvm相关知识是最能吹的....
参考书目:
★★★★★:《深入理解JVM》(重点章节 2,3,7,12,13)经典..没啥好说的。大部分面试知识都够了,偶尔碰到某些深一点的知识点就得自己搜了。
★★★★:《深入理解Java内存模型》
数据库《建议直接拉到最后看参考书目》
- 谈谈 MySQL 的读写锁
- ==MySQL 的锁机制==---悲观锁和乐观锁呢?悲观和乐观锁的具体实现原理呢?
- MySQL 的隔离机制
- mysql 的三级封锁协议
- 数据库三大范式
- 如何查询并解决数据库死锁
- 数据库如何避免死锁
- 什么是事务?介绍一下 ACID
- MVCC 机制的实现原理
- 谈谈 InnoDB 和 MySIAM 的区别,了解 Memory 么
- SQL 查询执行流程是什么/生命周期
- 数据库的视图
- 数据库的存储过程
- 触发器 (出发某个事件时,自动执行这些代码)-做某个表的字段监控。
- 什么是游标
- MySQL 外键删除策略(外键列全部设置为 null,或者直接删除)
- SQL 语句 exist 和 in 的区别
- 组合索引吗?怎么实现的?
- 自增 ID 的好处和实现
基本类型
- VARCHAR 和 CHAR 的区别?
- DATETIME 和 TIMESTAMP 的区别?
- 数据类型有哪些优化策略?(更小的通常更好/尽可能简单/尽量避免 NULL,null 不会使索引,索引统计和值比较都更复杂)
索引
- 索引有那些?
- 索引有什么作用?
- 以 B tree 和 B+ tree 的区别来分析 mysql 索引实现
- 了解 hash 索引么?
- 什么是自适应哈希索引?
- 什么是空间索引?(MySIMA 支持,存储地理数据。MySQL 支持不完善)
- 什么是全文索引?(MySIAM 的基于相似度的查询,非精确比较)
- 聚簇索引和非聚簇索引
- 什么是覆盖索引?以及为什么要使用索引(除了加快速度)
- 那些索引使用原则?(1.建立索引 2.对于比较长的列,使用前缀索引缺点是不能做分组和排序和覆盖索引 3. 合适的索引顺序 4.删除我用索引)
- 索引失效有那些?(1. 隐式类型转换 2. OR 3.LIKE 4.多个范围条件查询,第一个范围列之后的其他索引无法使用,等值查询没有限制 5. 优化器认为全局扫描比索引更快)
- 除开使用 B+ 树实现的索引,还了解其他数据结构实现的索引吗--为什么不使用 AVL/红黑树(920P64)
优化
- 如何定位低效 SQL?(1. 慢查询日志定位已经执行完毕的 SQL。2.使用 show processlist 查询当前正在执行的线程的低效 sql。 找到 sql 通过 show profile、explain 或 trace 继续优化)
- show profile 的作用。(分析 sql 性能消耗,例如执行多少时间,显示 cpu 内存使用率,花费时间等)
- trace 的作用?(通过 trace 文件进一步获取优化器是如何选择执行计划的,需要手动打开设置,然后执行一次 sql,最后查看 information_schema.optimizer_trace 表的内容。)
- Explain 有什么用,字段有哪些,代表什么意思
- 有哪些优化 SQL 策略?
- 大表优化
- 怎么优化 mysql,mysql 性能分析工具---
mysql的查询优化,用explain查询是否用到了索引
- 慢查询日志以及配合 explain 及逆行慢查询优化和分析
- mysql cpu 过高怎么排查呀(不会,面试官说可以用 error log 看下)
- 关心过业务系统里面的 sql 耗时吗?统计过慢查询吗?对慢查询都怎么优化过?
- 如果要存储用户的密码散列,应该使用什么字段进行存储?
密码散列,盐,用户身份证号等固定长度的字符串应该使用 char 而不是 varchar 来存储,这样可以节省空间且提高检索效率。
主从
- redolog 和 binlog 是什么?
- 事务的二段提交
- 主从复制是什么?
- 主从复制的作用?
- 数据库的热备份和冷备份?
SQL
- 姓名、科目、成绩,写 sql 语句统计总分前三的学生姓名,如果有并列的怎么办?统计这个班的学生选了哪些科目
JDBC 和 Mybatis
- 介绍下 JDBC 的过程 /JDBC 的 Statement 对象有哪几类
- jdbc 的使用,什么是 sql 注入 mysql 防注入
- JDBC 连接 mysql 的几个步骤、为什么要加载驱动呢,原理是什么、PreparedStatement 和 Statement 区别、返回结果如何查询
- Mybatis 底层实现
#和\$的区别
- 缓存机制,一级、二级原理和作用
参考书目:
PS:数据库我搜罗以及面试上没碰到很难的题目,但是实际上我在数据库上花时间是最多的。我的学习过程其实完全来源于书本和部分知识点的blog,书看完基本大部分知识点就get了。以下书籍按顺序看
★★★★★:《MySQL必知必会》-->《从根上理解MySQL》-->《InnoDB技术内幕》-->《高性能MySQL》(这本可以挑着随便扫扫)
Redis(重点)
Redis 持久化方式
如何保证缓存和数据库双写时的数据一致性?(920 P83)
Redis 的缓存淘汰策略有哪些
-
- MySQL 自建锁表
- memcache 实现分布式锁
- redis 实现分布式锁。
- zookeeper 实现分布式锁。
Redis 的跳表--为什么使用跳表不使用 B+树做索引
怎么保证 Redis 的高可用---redis 怎么处理高并发,几种思路= Redis 一主多从的实现?如果主服务器挂了怎么办?能锁住吗
问 Redis 为什么快(920 P84)
更喜欢这个答案(https://blog.csdn.net/diweikang/article/details/90264993)list 如何实现的异步消息队列?
集群是如何判断是否有某个节点挂掉/集群进入 fail 状态的必要条件: 920 p92
redis 的长尾效应--- 冷热分区,小而热的数据,内存,大而冷的数据-磁盘,大而热的数据-SSD 或者,对于长尾访问的数据、大多数数据访问频率都很高的场景、缓存空间足够都可以考虑不过期缓存,比如用户、分类、商品、价格、订单等,当缓存满了可以考虑 LRU 机制驱逐老的缓存数据。
redis key 和 value 的大小限制---redis 的 key 和 string 类型 value 限制均为 512MB。
为什么用 redis(一开始我们使用 redis 做一个消息队列,发布订阅模式广播..)
Redis 如何实现延时队列?使用 sortedset,使用时间戳做 score, 消息内容作为 key,调用 zadd 来生产消息,消费者使用 zrangbyscore 获取 n 秒之前的数据做轮询处理。
参考书籍
★★★★★:《Redis深度历险》,《Redis设计与实现》,两本都是极好的书,前者新不过较浅后者比较深入但是老
Java 框架
- 请求 servlet 的过程
- servlet 的生命周期
- IOC/DI
- AOP 有哪几种实现---
单实例无状态
- MVC 是什么-
springmvc里session和cookie/区别/联系?
- Springboot和spring的启动区别
- springboot 与 springMVC 有什么区别
- SpringBoot 的自动配置流程
- springMVC 执行过程---SpringMVC 中用到了哪个核心的 Servlet ?
- spring bean 的生命周期
- Spring 注入的方式有哪些?---Spring 的 scope 里面有哪几个属性?bean 成员变量的参数注入有哪种方式?
- 除了@ResponseBody,controller 层如何标准返回给前端所要的数据类型?
- @Autowired 和@Resource 的区别?
- Spring 事务以及传播机制
PS:spring之流的框架题其实也不多,都是老三样,但是现在问的越来越难。其他的就靠自己debug一遍搞清楚整个容器初始化加载和销毁流程...
参考书籍
没书推荐,我都不喜欢,spring技术内幕和spring源码解析都不好..极度讨厌。
推荐 一个公众号《程序员DMZ》,培训班的子路和狂神
全部评论
(0) 回帖