2020Java面试题及答案

      今年由于疫情的影响,整个大的市场环境不景气,老板也经常把疫情的事情挂在嘴边,说由于疫情的影响,公司业绩不好,所以取消了绩效,还定制的强制性的加班政策,就连出差补贴也从原来的350降到了现在的80,难道真的是疫情影响的吗?说白了对于程序员来说影响并不大,对于互联网行业反而会有一定的需求旺盛的景象出现,影响的是传统行业,但是程序员只要有一台电脑,可以联网就能工作,工作量并没有因为疫情的影响而减少,就拿我来说,当国内疫情最严重的时候,我们公司的开发人员在家办公,每天晚上熬夜到凌晨四五点是长有的事情,就这种情况持续了有办个多月。到最后绩效说没就没,你能说这是疫情影响的吗?所以我离职重新开始找工作了,这么长时间的面试,自己觉的其实外面招人的公司很多,岗位也不少,能给到的薪资也不算低吧。还是自己欠下的计数债太多了,现在的招聘要求已经不像是两三年之前了,不仅要会敲代码,还要懂底层原来,还要了解架构相关的东西。如果你只会敲代码,写个业务处理逻辑,那不管以后去哪面试,都是会受挫的,所以平时得多看多学,需要有一定的技术广度和深度。平时积累到到东西,面试就不会差。下面是我总结的一些面试题和答案,仅供参考,主要是被问到的概率比较大。

String的equals()方法是如何判断字符串是否相等的?

答:string的equals判断字符串是否相等首先会判断两个字符串的地址是否相等,如果地址相等则肯定字符串相等,否则会先去判断字符串的长度是否相等,相等了则进入while循环,判断每一个字符是否相等。

hashmap的底层实现原理

答:jdk1.7使用数组+链表的形式,jdk1.8使用数组+链表+红黑树的形式

map的遍历方式有哪些?

Spring中IOC是什么?AOP是什么?

答:IOC叫控制反转,也叫依赖注入。

dao接口的实现不再是业务逻辑层调用工厂类去获取,而是通过容器(spring)来自动的为我们的业务层设置Dao的实现类,这样整个过程就反过来,以前是我们业务层主动去获取dao,而现在是dao主动被设置到业务逻辑层中来了,这个也就是反转控制的由来。通过IOC,我们就可以在不修改任何代码的情况下,无缝地实现数据库的换库迁移

AOP面向切面编程将程序中的交叉业务逻辑(比如安全,日志,事务),封装成一个切面,然后注入到目标业务逻辑中去。 比如:很多方法都可能会抛异常,你要记录这个异常到日志中去,可以写个拦截器,在这个类中记录日志,在spring.xml中配置一个记录这些日志的方法的拦截器,在这个方法执行后调用这个拦截器,记录日志。这样就不用每次抛异常都要手动记录日志。

IOC是如何创建实例的?

答:1.调用无参构造器 2.调用有参构造器3.工厂创建对象

Spring中的依赖注入有哪几种方式?

答:1.构造方法注入 2.set注入 3.根据注解注入

Spring中的注解都有哪些?分别是干什么的?

1.声明Bean的注解,@Component @Service(表明业务逻辑层) @Respository(表明数据访问层) @Controller(控制器层)

2.注入Bean的注解, @Autowired @Resource

3.配置类的注解, @Configuration (声明当前类为配置类) @ComponentScan(用于对Component进行扫描)

4.AOP的注解,@Before @After @Around @PointCut @Aspect(声明一个切面)

redis的持久化方式?

答:有两种,RDB和AOF

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

什么是联合索引?

答:联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。

Linux的常用命令

1.ps –ef|grep XXX 查看一个程序是否运行

2.kill -9 19979 终止一个线程

3.pwd 查看当前目录

4.ls 查看文件

5.tail -n 行数 文件名。 查看某文件的最后多少行

6.nohup java -jar 启动java项目

mysql的优化

1、在表中建立索引,优先考虑where、group by使用到的字段。

2、尽量避免使用select *,返回无用的字段会降低查询效率。

3、尽量避免使用in 和not in,会导致数据库引擎放弃索引进行全表扫描。可以使用exists和not exists代替

4、尽量避免使用or,会导致数据库引擎放弃索引进行全表扫描。

5、尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描。

6、尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描。

7、尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描。如下:

8、当数据量大时,避免使用where 1=1的条件。通常为了方便拼装查询条件,我们会默认使用该条件,数据库引擎会放弃索引进行全表扫描

事务的隔离级别

隔离级别:1.Read Uncommitted(读未提交):可能出现赃读、不可重复读、幻读等问题

2.Read Committed(读取提交内容):可能出现不可重复读的问题、幻读等问题。大多数数据库等默认隔离机制

3.Repeatable Read(可重复读):可能会出现幻读的问题。mysql的默认隔离级别

4.Serializable(可串行化):最高级别的隔离级别,解决了幻读问题,但可能会出现大量的超时现象和锁竞争

如何防止sql注入

1.前端表单进行参数格式控制;

2.后台进行参数格式化,过滤所有涉及sql的非法字符;

3.持久层使用参数化的持久化sql,使用预编译语句集,切忌使用拼接字符串;

4.使用参数化sql代替字符串拼接

5.参数化,使用预编译语句,进行批处理更新

如何解决幂等性问题

1.前端解决,用户点击一次按钮后设置按钮在短时间内不可用,防止重复点击

2.后端解决:1.使用唯一索引,2.token+redis , 3.根据乐观锁来解决幂等性。4.select+insert

多线程面试题

  1. Java创建线程对象后,直接调用其start()方法 和run()的区别?

    1.调用 start() 方法是启动新的线程,新的线程运行后,会在新线程上执行 run() 方法 内的代码

    2.而直接调用 run() 方法只能在当前线程运行 run() 方法内的代码,并不会启动新的线 程

  2. threda的sleep方法和object的wait方法有什么区别?

    答:java程序中wait和sleep都会造成某种形式的暂停,它们可以满足不同的需要。

    • wait存在于Object类中;sleep存在于Thread类中。

    • wait会让出CPU资源以及释放锁;sleep只会释放CPU资源。

    • wait只能在同步块中使用;sleep没这限制。

    • wait需要notify(或 notifyAll)唤醒,进入等锁状态;sleep到指定时间便会自动恢复到运行状态。

  3. 多线程的实现方式

    答:有四种:

    1.集成Thread类,重写run方法,调用start方法启动线程

    2.实现runable接口,重写run方法,调用thread的start方法启动线程

    3.实现callable接口,重写call方法,通过FutureTask包装器创建thread线程,调用start方法启动线程

  4. springMVC的原理

    1. 客户端请求提交到DispatcherServlet,DispatcherServlet会在服务器启动时初始化spring容器,生成控制器(Controller)实例。

    2. 由DispatcherServlet根据请求匹配到一个合适的处理映射器(HandlerMapping),由处理映 射器(HandlerMapping)生成一个执行链(HandlerExecutionChain)

    3. 处理适配器(HandlerAdapter)类的职责是调用控制器(Controller)中的方法来真正处理请 求。

    4. 由处理适配器(HandlerAdapter)调用控制器(Controller)中的方法,在控制器方法执行前后 会调用多个拦截器中的前处理和后处理方法

    5. Controller方法执行后,结果会封装为ModelAndView对象。由DispatcherServlet利用视 图解析器(ViewResoler)生成视图(View)对象

    6. 在请求到达视图之前,spring会将模型数据存入request作用域

    7. 视图取出模型数据,渲染为html页面后作为响应返回给客户端

  5. 集合面试题

  6. ArrayList与Vectory的区别?

    答: 1.Vector是线程安全的,源码中有很多的synchronized可以看出,比方说add()方法就是用synchronized进行修饰的,而ArrayList不是。导致Vector效率无法和ArrayList相比;

    2.ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;

    3.Vector可以设置capacityIncrement,而ArrayList不可以,因为Vector比ArrayList多了一个构造方法,设置增长容量参数的方法。

  7. ArrayList的底层实现原理是什么?

    答: 1.ArrayList 通过数组实现,一旦我们实例化 ArrayList 无参数构造函数默认为数组初始化长度为 10,底册是一个Object数组

    2.add 方法底层实现如果增加的元素个数超过了 10 个,那么 ArrayList 底层会新生成一个数组,长度为原数组的 1.5 倍+1,然后将原数组的内容复制到新数组当中,并且后续增加的内容都会放到新数组当中。当新数组无法容纳增加的元素时,重复该过程。是一旦数组超出长度,就开始扩容数组。

    它的特点是:查询快,增删慢,线程不安全,根据下标查询一个数据的时间复杂度为O(1),因为它的底层是数组,所以在新增或者删除元素的时候,需要进行元素的移动,增加了复杂度导致速度慢。

  8. LinkedList底层实现原理是什么?

    答:LinkedList底层的数据结构是基于双向循环链表的,且头节点不存放数据,

    它的特点是:增删快,查询慢,线程不安全,根据下标查询一个数据的时间复杂度为O(n),因为它的底层是双向循环链表,所以在新增或者删除元素的时候,只需要将前目标元素的一个元素和后一个元素的地址改变即可,所以增删速度快。

  9. HashMap底层实现原理是什么?

    答:JDK1.7中,HashMap采用数组+链表 的方式实现,效率低,JDK1.8中,HashMap采用位桶+链表+红黑树实现,效率提升。线程不安全,可以有null的健和值。hashTable线程安全,不能有null的健和值,1.8之后使用CocurrentHashMap代替hashTable,提高的效率

最好自学一下dubbo、springcloud方面的东西。

最后希望大家对自己的职业有个路线规划,这对你后面到职业生涯很重要,要走哪条路得慎重。如果对行业没有要求对话,最好能进入互联网公司,这对你的技术提升太大了,传统行业能学到的只有业务,技术提升太窄

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章