7 年 Java 开发经验,面试 20 多家公司,砍下 16 个 Offer
- mysql 优化,什么时候不会用到索引 
- select *,可能会导致不走索引 
- where 后面有函数运算,导致不走索引 
- 索引不适用于隐式转换的情况,比如你的 SELECT * FROM T WHERE Y = 5 在 Y 上面有一个索引,但是 Y 列是 VARCHAR2 的,那么 Oracle 会将上面的 5 进行一个隐式的转换,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,这个时候也是有可能用不到索引的。 
- like 查询使用通配符开头不会用到索引 
但是这些好像不是他想要的答案,我也猜不透。。
- 接受长期出差吗 
做互联网金融的,公司总部在北京,我面试的时候是在成都的新网银行公司,看这个模式应该就是驻场开发了,但是公司本身不是外包。
- springboot 和 spring 的不同 
- springboot 特性,自动装配怎么实现的 
- spring 用到哪些组件,具体场景 
- spring 默认是单例还是多例,全局变量会有什么问题 
- spring 事务传播行为、隔离级别 
- aop 实现方式,jdk 动态代理和 cglib 动态代理区别 
- jdk lambda 表达式几种使用方式,取最大和最小值,list 转 map,list 中有重复的怎么办 
线程池 有哪些参数,各个参数的意义
- ioc 容器有什么优点 
- jvm 堆栈,区别,线程共享还是线程私有的 
- springcloud 组件、用途,负载均衡的几种算法 
- 分布式事务怎么做的 
- mybatis 一对多,多对多怎么做 
- jpa 和 mybatis 区别 
- vmstat 命令干嘛的 
- redis 查看内存占用命令 
- mysql 导入大量数据怎么优化 
- mysql 有一条数据死锁了,怎么排查问题,mysql 表死锁,怎么排查 
- nginx 反向代理是什么,正向代理呢 
这次面试回答得挺好的,hr 也打了好几次电话说面试官对我挺有意向的,就是一顿操作猛如虎,一问工资 0.9。而且我当时还是在职,要求我一周到岗,我就没去。
朋友内推的,听他说是稳了,去面就能过,结果还是翻车了。
- java 特点描述一下,继承封装多态分别是什么意思 
- synchronized 和 lock 区别 
- ConcurrentHashMap 线程安全怎么实现的 
- 创建线程的几种方式,创建线程池几个参数的含义,线程饱和策略 
- sleep 和 wait 区别 
- spring 是单例还是多例,多线程并发会出现什么问题 
- SpringBoot 如何解决跨域,具体怎么配置 
- 全局异常捕获怎么做的 
- SpringSecurity 的前后端分离,登录怎么做的 
我:拦截登录的 url,然后获取到用户名和密码,把这个用户名和密码交给 manager,manager 会交给具体的 provider 处理,provider 会调用 UserDetailsService 的方法完成验证。
这里是我失误了,他说用户名和密码是通过 getattribute 获取到的吗,我说是的。
- 怎么设计一个安全的对外接口 
- 单线程的 redis 为什么这么快 
- redis 持久化方式 
- 什么是聚簇索引,什么是非聚簇索引 
- mysql 事务隔离级别 
- 你觉得你能承担独立开发的任务吗 
其他问题回答得挺好的,自我感觉不错,本来以为能收到 offer 的,但是朋友说那个面试官觉得我不行,不能承担独立开发系统的任务,估计是第 8 个问题回答失误了吧,其他我觉得我回答没有问题。
面试的人比较多,所以是群面,一个面试官对应多个面试者。虽然我回答得比另外一个面试者好很多,但是没有收到 offer,很迷,真的很迷。
- 介绍项目,然后基本上就围绕着项目的业务说 
- 对金额的计算用什么类型,数据库中用什么类型存储 
- SpringBoot 怎么自定义注解 
- mysql 优化,like 查询的时候,数据量很大,如果 like 查询以 %开头,不会走索引,怎么优化。多表关联查询,怎么优化 
- 代码优化怎么做的,平时重构从哪方面考虑 
如果各位以后有机会面试别人的话,希望对面试者多一些尊重吧。
- 根据简历提前准备好,针对不同的 level 提不同的问题 
- 不要问一些偏门的怪题 
- 问题都是和面试职位相关的 
以下是一些翻车面试,有些公司真的把我心态搞崩了,导致后面的面试都没有发挥好。
公司很小,面试官架子不小,面试全程非常不愉快,经常在我说到一半打断我,挺会嘲讽人的。面试的时候没有空间了,然后在外面靠近电梯的走廊面试的。
- 因为我的项目是做人脸识别相机相关的,然后他问我图片处理到算法识别经历了什么过程,我是直接调算法,最多把 jpg 格式的图片转成 bgr 格式,或者图片有旋转的,通过 exif 修正旋转。但是我的回答好像不是他要的,然后就直接打断我,说我不知道就直接说不知道 
- rabbitmq 用了哪些设计模式。发布订阅模式,还有其他的吗,我不知道,有知道的朋友可以告诉我一下 
- tcp/ip 协议 
- 让你设计 eureka,你怎么设计 
- 乐观锁,悲观锁介绍一下 
我:乐观锁实际上没有加锁
然后他就直接打断我了,发出一声嘲笑,问我:那你觉得什么是锁。
- jvm 参数调优怎么做的 
我回答的是用的微服务部署,有的微服务访问很频繁的,就多给他设置一些内存,比如网关,一些不怎么用到的,可以设置稍微小一点。然后他说:你们这就是全凭感觉瞎设置呗
哎,面完之后心情低落了很多,难受了一下午,开始质疑我自己。
Boos 直聘上标榜的上市公司,我去面试的时候顶多就看见 5 个人在公司,办公区域很空旷很安静。
- 项目介绍 
- 挑出你在项目里做的一个模块,谈谈这个模块的整个设计 
这个我真不知道怎么回答,你说整个项目怎么设计的我还能画个架构图啥的给你瞅瞅,但是你这说到具体的模块设计,我不知道怎么说,最多给你说说数据库怎么设计的
- 项目并发情况 
你这公司规模还问我这个,不合适吧
- 听你说对 linux 比较熟,环境搭建过吗(tomcat 之类的),有没有遇到什么问题 
大环境都成为一个技术点来问了嘛,反正我现在用 docker 了。
- nginx 你们一般做什么,正向代理一般用来干啥 
你会前端啊,说说 vue 用 history 打包之后,部署到服务器,nginx 需要配置什么
- 说说你的优点 
- 假如你最近加班很累(你已经很累了,要猝死了),但是项目比较急,你想请假怎么跟领导沟通。 
第一次见到这样问问题的兄弟,挺有新鲜感的,其他公司翻来覆去的就是那几个问题。就是浪费了我的简历,打印一次一块钱,你还在我的简历上涂涂改改,我都不好意思要回简历了。
- java 的序列化和反序列化什么含义 生成的 serialVersionUID 有什么用 
- yml 文件里有一些属性,怎么获取这些属性 
- 有一个枚举类,有很多 value 和 code,然后 yml 中的一个属性对应这个 code 的值,怎么通过 code 的值获取到这个对应 value 
- 我想说循环判断,但是觉得没这么简单,所以沉默了半天。。。。 
然后他说枚举类里面有一个方法 valueOf
啊这,是他没表达清楚还是我理解错了?
- final 干嘛的,如果有一个 final Stirng a = “123”,后面还可以改变吗 
- 一般 io 操作会捕获异常,然后在 catch 中释放资源,有更简单的办法吗。 
- 有一个 list,给它按照类里的一个属性排序 
- 有个 string 数组,里面有些空的值,我想去除空的,怎么做 
- 线上有个接口速度慢,但是本地测试环境和线上环境是一样的,数据量也是一样,接口速度却很快。怎么排查 
=======================================================================
我觉得这不是一个中级开发工程师甚至高级开发工程师能做的出来的,但是面试就是要问。死记硬背考记忆力呗,只要记住其中几个常用的配置就行了。
堆大小设置
- -Xms:初始堆大小 
- -Xmx:最大堆大小 
- -XX:NewSize=n:设置年轻代大小 
- -XX:NewRatio=n:设置年轻代和年老代的比值。如:为 3,表示年轻代与年老代比值为 1:3,年轻代占整个年轻代年老代和的 1/4 
- -XX:SurvivorRatio=n:年轻代中 Eden 区与两个 Survivor 区的比值。注意 Survivor 区有两个。如:3,表示 Eden:Survivor=3:2,一个 Survivor 区占整个年轻代的 1/5 
收集器设置
- -XX:+UseSerialGC:设置串行收集器 
- -XX:+UseParallelGC:设置并行收集器 
- -XX:+UseParalledlOldGC:设置并行年老代收集器 
- -XX:+UseConcMarkSweepGC:设置并发收集器 
调优总结
年轻代选择
响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时,减少到达年老代的对象。 吞吐量优先的应用:尽可能的设置大,可能到达 Gbit 的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合 8CPU 以上的应用。
年老代选择
响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可以会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式;如果堆大了,则需要较长的收集时间。
分为三个维度来谈,可以稍微拓展一下:
- 整体框架的优化,根据模块(类)的职责做一些划分,尽量做到每个模块的接口清晰。然后就是善用六大设计原则和 24 种设计模式。 
- 功能逻辑的优化,把内聚的逻辑独立成一个个函数,函数依赖的数据都通过参数传递,这样做到函数可重用,当上层结构做出改变的时候,修改的代码量不会太多。 
- 性能优化,如果性能不敏感,代码也不是那么糟糕,那这个优化可以不用关注。 
六大设计原则
- 单一职责原则 
接口的单一职责,一个职责一个接口,我们对外公布的是接口,而不是实现类,所以不需要过度关心实现类是否遵循单一职责,生搬硬套单一职责会引起类的剧增,给维护带来非常多的麻烦
- 里式替换原则 
只要父类能出现的地方我子类就可以出现,而且调用子类还不产生任何的错误或异常,调用者可能根本就不需要知道是父类还是子类。但是反过来就不成了,有子类出现的地方,父类未必就能适应。里式替换原则包含了四层意思:
- 子类必须完全的实现父类的方法。我们经常写 service 会定义一个接口或者抽象类,然后编写实现,调用类则直接传入接口或抽象类,其实这里已经使用了里氏替换法则。 
- 子类可以有自己的个性。子类当然可以有自己的行为和外观了,也就是方法和属性,在子类出现的地方,父类未必就可以胜任。父类向下转型可能会出现类型转换异常 
- 覆盖或实现父类的方法时输入参数可以被放大。 
- 覆盖或实现父类的方法是输出结果可以被缩小。 
- 依赖倒置原则 
依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。我们在项目中使用这个原则要遵循下面的规则:
每个类尽量都有接口或者抽象类,或者抽象类和接口两都具备
变量的表面类型尽量是接口或者抽象类
任何类都不应该从具体类派生
尽量不要覆写基类的方法
- 接口隔离原则 
客户端不应该依赖它不需要的接口,客户端需要什么接口就提供什么接口,把不需要的接口剔除掉,对接口进行细化,保证其纯洁性。通俗的讲就是:建立单一接口,不要建立臃肿庞大的接口。
- 迪米特法则 
一个对象应该对其他对象有最少的了解,通俗的讲,一个类对自己需要耦合/调用的类应该知道的最少,这个类内部是怎么复杂、怎么纠缠不清都和我没关系。尽量不要对外公布太多 public 方法和非静态的 public 变量,尽量内敛,多使用 private、package-private、protected 等访问权限
- 开闭原则 
类、方法对于扩展是开放的,对于修改是关闭的,在程序需要进行拓展的时候,不能去修改原来的代码。
单例模式
工厂模式
建造者模式
观察者模式
有观察者和被观察者,被观察者接口:增加观察者、删除观察者,通知观察者更新 观察者:被观察者发送消息了,我自己也要做些什么
责任链模式
适配器模式
十家公司有九家会问,这个必须要记住。基本上只要记住我写的这些,面试基本上稳了:
- 数据库表设计优化 
- 所有表必须使用 Innodb 存储引擎 
- 字符集统一使用 utf-8 
- 字段加注释 
- 控制单表数据量的大小,建议控制在 500w 内 
- 冷热数据分离,减小表宽度 
- 禁止存储图片,文件等二进制数据 











 
    
评论