java面试答题话术:
对于一个java问题,我们该如何去回答呢?
1.概述
2.详细描述
3.应用场景
request:一次服务跳转有效
response
session:一个用户有效
pagecontext
application:属性作用域
out
config
page:一个页面有效
exeception
单例模式:一个类只有一个实例,主要分为饿汉和懒汉模式,懒汉模式在调用自己的时候实现,饿汉是在初始化的时候实现
简单工厂:一个工厂方法创建不同类型的对象。
工厂方法模式:定义一个接口,具体的功能实现由子类来实例化。
抽象工厂模式:抽象工厂是生成工厂的工厂,相当于生产的工厂其实是我们的产品。
建造者模式:建造者就是如何一步一步构建多个组件的对象,相同的构建过程可以创建不同的产品。
模板类:对于重复不变的东西我们可以加final,子类需要重写的加abstract就行。
适配器模式:把一个接口转换成顾客希望的另一个接口,该模式让原本不兼容的类可以一起工作。
外观模式:为一组接口定义一个一致的页面,类似实现的功能就像电脑开机一样,内部实现需要,启动cpu,启动内存,启动硬盘,加载数据等
观察者模式:对象之间一对多的依赖关系,当一个对象的状态发生改变,所有依赖于他的对象都会得到通知并自动更新。
装饰器模式:在不修改原有类的情况下进行,但是这个东西如果太多了,就像剥洋葱一样,一层层的。
代理模式:和装饰器模式非常类似,都是实现原有接口,然后增加某些行为,不同点:装饰器模式是在原有基础上进行装饰,代理模式是在原有基础上增加控制
中介模式:避免多个互相协作的对象直接引用,它们之间的交互通过一个中介对象进行,从而使得它们耦合松散,能够易于应对变化。
常见的异常:
算术异常,索引越界异常,类型转换异常,空指针异常,io异常,FileNotFoundException,SecurityException
synchronized与Lock的区别
1.synchronized是关键字,而Lock是一个接口
2.synchronized会自动释放锁,而Lock必须手动释放锁
3.synchronized是不可中断的,Lock可以中断也可以不中断
4.通过Lock可以知道线程有没有拿到锁,而synchronized不能
5.synchronized能锁住方法和代码块,而Lock只能锁住代码块
6.Lock可以使用读锁提高多线程读效率
7.synchronized是非公平锁,ReentrantLock可以控制是否是公平锁
java应付面试宝典,java应届生面试宝典
synchronized和volatile的区别
volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized 则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
volatile 仅能使用在变量级别;synchronized 则可以使用在变量、方法、和类级别
volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性
volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。
volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化
hashset:
底层是哈希表,无序,唯一。唯一保证是hashcode和equals
linkedhashset:底层是链表和哈希表,插入有序唯一
由链表保证元素有序,哈希表保证唯一
treeset:
底层是红黑树,有序唯一,自然排序保证有序,根据返回的值是否为0来保证是否唯一
ArrayList 和 Vector 的区别是什么?
线程安全:Vector 使用了 Synchronized 来实现线程同步,是线程安全的,而 ArrayList 是非线程安全的。
性能:ArrayList 在性能方面要优于 Vector。
扩容:ArrayList 和 Vector 都会根据实际的需要动态的调整容量,只不过在 Vector 扩容每次会增加 1 倍,而 ArrayList 只会增加 50%。
反射 Class.forName 和 classLoader有什么区别
第一:Class.forName(“className”);
其实这种方法调运的是:Class.forName(className,true,ClassLoader.getCallerClassLoader())方法
参数一:className,需要加载的类的名称。
参数二:true,是否对class进行初始化(需要initialize)
参数三:classLoader,对应的类加载器
第二:ClassLoader.laodClass(“className”);
其实这种方法调运的是:ClassLoader.loadClass(name,false)方法
参数一:name,需要加载的类的名称
参数二:false,这个类加载以后是否需要去连接(不需要linking)
第三:区别
可见Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
而classloader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。
java应付面试宝典,java应届生面试宝典
线程池:
newCacheThreadPool 可缓存线程池
newFixedThreadPool 定长线程池
newSingleThreadExecutor 单线程池
newScheduledThreadPool 周期线程池
sleep 和 wait 的区别
sleep 方法是 Thread 类中的静态方法,wait 是 Object 类中的方法
sleep 并不会释放同步锁,而 wait 会释放同步锁
sleep 可以在任何地方使用,而 wait 只能在同步方法或者同步代码块中使用
sleep 中必须传入时间,而 wait 可以传,也可以不传,不传时间的话只有 notify 或者 notifyAll – 才能唤醒,传时间的话在时间之后会自动唤醒
ArrayList是否线程安全?会报出现什么异常?导致原因?怎么解决?
不安全;java.util.ConcurrentModificationException
1、使用new Vectore<>(),
2、Collections.synchronizedList(new ArrayList<>())
3、使用CopyOnWriteArrayList()
如何解决哈希冲突
1.通过链地址法,如果hashcode值相同,都存在一个哈希桶里面,格式是数组加链表的格式
2.二次扰动
3.引入红黑树,jdk1.7之前复杂度是o(n),1.8是o(logn)
HashMap为什么线程不安全
1.在JDK1.7中,当并发执行扩容操作时会造成环形链和数据丢失的情况。
2.在JDK1.8中,在并发执行put操作时会发生数据覆盖的情况。
产生死锁的四个条件
1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
类加载的过程
加载:将类的信息从文件中获取并且载入到JVM内存中
验证:检查读入的结构是否符合JVM规范的描述
准备:分配一个结构用来存储类信息
解析:把这个类的常量池的所有符号引用改变成直接引用
初始化:执行静态初始化程序、类构造器方法的过程
Servlet的生命周期,并说出Servlet和CGI的区别
Servlet被服务器实例化后,容器运行其init方法,请求到达时运行其service方法,service方法自动派遣运行与请求对应的doXXX方法(doGet,doPost)等,当服务器决定将实例销毁的时候调用其destroy方法。
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。
springmvc执行流程
DispacherServlet:前端控制器
HandlerMapping:处理器映射器
HandlerAdapter:处理器适配器
ViewResolver:视图解析器
执行流程: 用大白总结的 面试这个讲可以,一般是11被步骤 不好记太罗嗦
1:用户发出请求到前端控制器
2.前端控制器去处理器映射器寻找对应的Controller返回给前端控制器
3.前端控制器调用处理器适配器调用对应的Controller返回逻辑视图给前端控制器
4.前端控制器调用视图解析器通过逻辑视图寻找物理视图返回给前端控制器
5.前端控制器放回渲染的view视图给用户
mybatis有哪些执行器?
简单执行器:每次执行异常select或者update就会开启一个statement,结束后关闭statement。
重复执行器:每次执行异常select或者update就会开启一个statement,用完不会立刻关闭,可以重复使用
批量执行器:缓存多个statement
如何避免死锁?
尽量使用并发类,不使用手动锁
尽量减少同步代码块和同步方法的使用
设置死锁时间,超出自动退出
spring作用域
singleton:bean在springioc容器中只有一个实例
prototype:一个bean可以有多个实例。
request:每一次http请求都会创建一个bean,作用域:基于web的Spring ApplicationContext下有效。
session:在一个http session 中 创建一个bean的实例,作用域:基于web的Spring ApplicationContext下有效。
global -session 在一个全局的http session 中 创建一个bean的实例,作用域:基于web的Spring ApplicationContext下有效。
BIO,NIO,AIO 有什么区别?
BIO是一个连接一个线程。
NIO是一个请求一个线程。
AIO是一个有效请求一个线程。
BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。
NIO:同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。
AIO:异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。
springboot常用注解
@SpringbootBootApplication 启动类
@ResponseBody 主要作用于控制层的类上,主要用于返回json数据。
@AutoWired 自动依赖
@RestController:主要作用于Controller的类上,它是@Controller和@ResponseBody的组合注解,主要用于返回json数据。
@RequestMapping:主要作用于Controller类及方法上,主要作用是请求地址的映射,当然,其中还有method属性等,method属性主要是请求类型,比如post、get等,value = RequestMethod.GET。
mybatis是怎么分页的?
mybatis的id是否可以重复?
是可以重复的,如果配置了namespace,没有配置是不可以重复的。
sql语句执行慢
偶尔很慢:1.死锁。2.内存问题
一直很慢:
jdk和cgilb?
jdk动态代理是基于反射,只能对实现了接口的类生成代理;cglib动态代理是基于继承的,针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
产生死锁的原因:
1.系统资源不足
2.进程推进的顺序不合适
3.资源分配不当
产生死锁的四个必要条件
1.互斥条件
2.请求与保持条件
3.不可剥夺条件
4.循环等待
处理死锁的方法
第一种就是预防死锁,预先才去一些限制,破坏死锁产生的四个必要条件。
破坏请求和保持条件:一次申请到所有需要的资源
破坏不可抢占条件:如果申请不到,则释放自己占有的资源
破坏循环等待条件:将资源按照一定的顺序排序,所有进程只可以申请比自己以占有资源序列号大资源,如果申请了比自己序号晓得资源,则释放当前占有的资源,从序号晓得资源重新申请
第二种就是避免死锁,在资源分配的过程中,防止系统进入不安全的状态,比如银行家算法
第三种就是死锁的检测和解除,如果检测出死锁,就采用相关算法去终结进程,让损失最小。
银行家算法:每次进程请求一定数量的资源时,都会去判断当前系统的资源量是否满足资源需求量,如果满足,会进行安全监测,判断如果将资源分配给该进程,剩下的资源数会不会导致对该资源进行申请的进程组进入不安全状态(安全状态:进程对资源的申请顺序不会导致发生死锁,不安全状态则相反)
三次握手建立连接阐述:
第一次握手:客户端要和服务端进行通信,首先要告知服务端一声,遂发出一个SYN=1的连接请求信号,”服务端哥哥,我想给你说说话”。
第二次握手:当服务端接收到客户端的连接请求,此时要给客户端一个确认信息,”我知道了(ACK),我这边已经准备好了,你现在能连吗(SYN)”。
第三次握手:当客户端收到了服务端的确认连接信息后,要礼貌的告知一下服务端,“好的,咱们开始联通吧(ACK)”。
到此整个建立连接的过程已经结束,接下来就是双方你一句我一句甚至同时交流传递信息的过程了。
四次挥手断开连接阐述:
第一次挥手:双方交流的差不多了,此时客户端也已经结尾了,接下来要断开通信连接,所以告诉服务端“我说完了(FIN)”,此时自身形成等待结束连接的状态。
第二次挥手:服务端知道客户端已经没话说了,服务端此时还有两句心里话要给客户端说,“我知道你说完了(ACK),我再给你说两句,&*……%¥”。
第三次挥手:此时客户端洗耳恭听继续处于等待结束的状态,服务器端也说完了,自身此时处于等待关闭连接的状态,并对告诉客户端,“我说完了,咱们断了吧(FIN)”。
第四次挥手:客户端收知道服务端也说完了,也要告诉服务端一声(ACK),因为连接和断开要双方都按下关闭操作才能断开,客户端同时又为自己定义一个定时器,因为不知道刚才说的这句话能不能准确到达服务端(网络不稳定或者其他因素引起的网络原因),默认时间定为两个通信的最大时间之和,超出这个时间就默认服务器端已经接收到了自己的确认信息,此时客户端就关闭自身连接,服务器端一旦接收到客户端发来的确定通知就立刻关闭服务器端的连接。
到此为止双方整个通信过程就此终结。这里要声明一下:断开链接不一定就是客户端,谁都可以先发起断开指令,另外客户端和服务端是没有固定标准的,谁先发起请求谁就是客户端。
Ajax请求是否可以实现同步?
sync默认是true也就是异步的方式,改成false就变成了同步
springboot注解有哪些?
常用linux命令?
评论0