【Java后端面试题整理】

Java基础

1.String类为什么是不可变的?为什么是final的?

什么是不可变:定义一个字符串对象,再新建一个对象赋值给这个字符串,这个赋值过程不是修改原地址的数据,而是指向一个新的对象,这就叫不可变。如下图:

JDK源码里,String类被final修饰,String类有一个属性是char类型的数组,说明String类本质上是一个数组,这个数组也被final修饰,所以String类不可变。好处有:

  1. 线程安全--String对象不可变,不能被写入,所以在多线程中修改字符串的值,其他的引用指向的还是原来的对象,不会被改变。
  2. 用于实现StringPool--栈里面的多个引用可以指向StringPool里的同一个字符串,节省了很多堆空间,如果String是可变的,那StringPool就没有意义了。
  3. 便于计算哈希值--  因为String类不可变,所以字符串很适合被hash。String类有一个hashCode()方法用于计算哈希值,在创建字符串的时候哈希值就计算出来并被缓存了,不需要重新计算。这就使得字符串很适合作为Map中的键,处理速度要快过其它的键对象。

补充:

  • String类中有个私有实例字段hash,表示该字符串的哈希值。
  • hash值的计算过程,是依据被hash的值的特征计算的,这要求被hash的值必须固定,因此被hash的值必须不可变。
2.HashMap的源码分析,实现原理,底层结构?
  • 底层结构:

HashMap是由数组+链表+红黑树组成的。数组是主体,存放的是Entry对象(Entry有四个属性:key、value、hash、next),向数组的某个位置插入一个entry对象的时候,如果发生哈希冲突,就把那个位置的entry对象作为头结点,指向要插入的entry对象,形成一个单向链表。但是链表不擅长查询,所以链表越少,HashMap的性能越好。在JDK1.8里引入了红黑树,当链表长度超过8的时候,就转换成红黑树来存储元素,提高HashMap的性能。

实现原理:

先用key通过哈希函数计算出一个数组索引,如果索引位置没有元素就直接放进去,如果有元素,若key相同就直接替换,若key不相同就遍历索引位置的链表,把元素插入链表。如果链表长度大于8,就转换成红黑树来存储元素。

源码分析:

补充:https://www.cnblogs.com/chengxiao/p/6059914.html

3.反射中,Class.forName(String name)和ClassLoader的区别?

反射:动态地获取类的内容,并映射成一个Java对象。

Java中Class.forName(String name)和ClassLoader都可用来对类进行加载,获得字节码文件。

  • Class.forName(String name)将类的字节码文件加载到JVM中,内部调用的forName()方法里有一个参数是控制初始化的,是true,所以会初始化,会加载静态代码块。
  • ClassLoader只是将字节码文件加载到JVM中,不会加载静态代码块。只有在用newInstance创建对象的时候才会加载静态代码块。

数据库加载驱动使用Class.forName(String name),是因为DriverManager驱动类有静态代码块。

4.session和cookie的区别和联系,session的生命周期,多个服务部署时session管理。

Cookie:数据存储在客户端,安全性不好,客户端可以删除cookie。如果不设置持久化时间,cookie会存储在浏览器的内存中,浏览器关闭,cookie信息销毁,如果设置持久化时间,cookie会被持久化到磁盘文件里。

Session:数据存储在服务器端,安全性较好,但当session太多时会占用部分服务器资源,session需要借助cookie来存储JSESSIONID。session默认30分钟过期,也可以通过配置更改这个时间。

SOA架构中,单点登录系统,专门使用一台服务器来保存session信息,用redis模拟session,用uuid模拟JSESSIONID。

补充:

https://my.oschina.net/u/3943244/blog/1929801

https://my.oschina.net/u/3943244/blog/2992047#h4_9

5.Java中的队列都有哪些,有什么区别。

  • 双端队列Deque:队列两端都可以进行入队出队操作
  • 阻塞队列BlockingQueue:如果BlockQueue是空的,这时如果有线程要从这个BlockingQueue取元素,将会被阻塞进入等待状态,直到别的线程在BlockingQueue中添加进了元素,被阻塞的线程才会被唤醒。同样,如果BlockingQueue是满的,试图往队列中存放元素的线程也会被阻塞进入等待状态,直到BlockingQueue里的元素被别的线程拿走才会被唤醒继续操作
  • 非阻塞队列AbstractQueue:多个线程存取元素时,直接返回结果,不具有阻塞的特点。

补充:

https://zhuanlan.zhihu.com/p/53076263

6.Java的内存模型以及GC算法

线程共享:Java堆,方法区

线程私有:程序计数器,Java虚拟机栈,本地方法栈

现代虚拟机中的GC(垃圾收集)算法:

  • 标记-清除算法
    标记:遍历所有的节点,然后将所有可以到达GC Root的对象标记为存活的对象。
    清除:遍历堆中所有的对象,将没有标记的对象全部清除掉。
    效率低,清理出来的内存是不连续的,适合大量对象存活的情况
  • 复制算法
    将内存按照容量分为大小相等的两块,每次只使用其中一块,当这一块内存用完了,把还在存活的对象复制到另一块内存上,清空当前使用的内存块,去使用另一块。(商业应用中,8:1)
    空间利用率低,存活对象多的时候效率低,适合少量对象存活的情况。
  • 标记-整理算法
    从GC Root开始遍历所有节点,对所有存活的对象做一次标记,之后,将所有的存活对象压缩到内存的一端,然后清理其他所有的空间。
    从效率上来说,标记-整理算法要低于复制算法(不仅要标记所有存活对象,还要整理所有存活对象的引用地址).
    适合存活对象较多的情况。
  • 分代收集算法
    将Java堆分为老年代和新生代,根据对象的存活时间不同,将内存划分为几块,分别采用针对性的GC算法,提高效率。

    新生代:少量对象存活,使用复制算法。

    老年代:大量对象存活,适合用标记-清除/标记-整理算法

补充:

GC Root:对象之间的引用组成了一张图,其中有一个叫做GC Root的根节点,如果一个对象不能到达根节点,说明这个对象已经失效。

标记-清除算法、复制算法、标记-整理算法的总结:三个算法都基于根搜索算法去判断一个对象是否应该被回收。

JVM详解

Field类详解

Native方法详解

GC

GC结构图

7.JDK7、JDK8的新特性

JDK7:

  1. 数值类型字面值可以用‘多个‘_’分隔增加可读性
  2. 可以使用字符串控制switch语句
  3. try语句里声明的资源,可以自动关闭
  4. 多重捕获异常(multi-catch),本来不同的异常是由多个catch语句块来处理,现在可以把多个异常用一个catch语句块来处理,用’|’来表示多个异常,也就是或的意思
  5.  

JDK8:

  1. 接口中可以添加static方法,接口中可以为方法添加默认实现。

原来的接口:接口中的成员变量默认(必须)都是public、static、final类型的,必须被显式初始化;接口中的方法默认(必须)都是public、abstract类型的。

https://blog.csdn.net/zhaojianting/article/details/80338273

8.Java数组和链表两种结构的操作效率,在哪些情况下,哪些操作(查询、插入删除)的效率高?

数组是一组地址连续、长度固定的内存空间,链表是动态分配内存,内存地址可以连续可以不连续,随机查询操作数组效率更高(O(1)),插入和删除操作链表效率更高(O(1))

9.Java内存泄露的问题调查定位:jmap,jstack的使用等等
  •  jps:主要用来输出JVM中运行的进程状态信息
  • jstack:主要用来查看某个Java进程内的线程栈信息
  •  jmap用来查看堆内存使用状况

补充:

https://blog.csdn.net/sinat_29581293/article/details/70214436

http://www.importnew.com/28916.html

Java开发框架

1.spring框架中需要引用哪些jar包,以及这些jar包的用途
  1. spring-core.jar:包含Spring 框架基本的核心工具类,其它组件要都要使用到这个包里的类,依赖Commons Logging(Log4J)。
  2. spring-beans.jar:是所有组件都要用到的,它包含访问配置文件、创建和管理bean 以及进行IOC、DI操作相关的所有类。依赖spring-core(CGLIB)。
  3. spring-aop.jar:包含在应用中使用AOP 特性时所需的类。
  4. spring-aspects.jar:提供对AspectJ的支持,以便可以方便的将面向切面的功能集成进IDE中,比如Eclipse AJDT。
  5. spring-context.jar:为Spring 核心提供了大量扩展。
  6. spring-context-support.jar:包含支持UI模版(Velocity,FreeMarker,JasperReports),邮件服务,脚本服务(JRuby),缓存Cache(EHCache),任务计划Scheduling(uartz)方面的类。外部依赖spring-context
  7. spring-jdbc.jar:包含对Spring 对JDBC 数据访问进行封装的所有类。
  8. spring-test.jar:spring整合JUnit测试的类。
  9. spring-web.jar:包含Web 应用开发时,用到Spring 框架时所需的核心类,包括自动载入Web Application Context 特性的类、Struts 与JSF 集成类、文件上传的支持类、Filter 类和大量工具辅助类。外部依赖spring-context, Servlet API, (JSP API, JSTL, Commons FileUpload, COS)。
  10. spring-webmvc.jar:包含Spring MVC 框架相关的所有类。包括框架的Servlet,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何类。外部依赖spring-web。
  11. spring-jms.jar:提供对JMS 1.0.2/1.1的支持类。外部依赖spring-beans,spring-dao,JMS API

详解:

https://blog.csdn.net/miao1475458272/article/details/61619228

2.srpingMVC的原理架构

5个组件:DispatcherServlet、HandlerMapping、HandlerAdapter、ViewResolver、View。

详解:

https://my.oschina.net/u/3943244/blog/2250217

3.springMVC注解的意思

@Controller、@Resource和@Autowired、@RequestMapping、
@ModelAttribute和@SessionAttributes、@PathVariable和@RequestParam、
@ResponseBody和@RequestBody、

详解:

https://www.cnblogs.com/leskang/p/5445698.html

PathVariable和RequestParam区别

RequestBody和ResponseBody的使用

4.spring中BeanFactory和ApplicationContext的联系和区别

https://youyu4.iteye.com/blog/2346183

https://blog.csdn.net/zh521zh/article/details/77884897

5.spring的DI(依赖注入)的几种方式

IOC:控制反转,把创建对象交给Spring进行配置

DI:依赖注入,向类里面的属性中设置值。

二者关系:DI不能单独存在,要在Ioc基础之上来完成操作,即要先创建对象才能注入属性值。

注入属性的方式:

set注入、构造方法注入、注解注入、复杂类型注入。还有一些不常用的:p名称空间注入,spel注入。

6.springIOC和AOP的原理

https://blog.csdn.net/u012813201/article/details/77074795

7.spring如何实现事务管理的

事务介绍

Spring并不直接管理事务,而是提供了多种事务管理器,spring将事务管理的职责委托给Hibernate或者mybatis等持久层框架来实现。 
Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。

8.spring中循环注入的方式

https://blog.csdn.net/u010644448/article/details/59108799

9.Spring的beanFactory和factoryBean的区别

https://www.jianshu.com/p/05c909c9beb0

 

转载于:https://my.oschina.net/u/3943244/blog/3008169

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值