面试题整理

string和Stringbuffer、StringBulider的区别
String的底层是一个被final修饰的char数组,可以理解为一个常量,线程安全
StringBulider和StringBuffer都继承自abstartStringBulider,底层是没有被final修饰的char数组,
性能方面,单线程下少量数据使用String,大量数据使用Stringbulider。因为Stringbuffer的方法都被synchronized修饰,线程安全性能较差,多线程下大量数据使用Stringbuffer

被final修饰的的方法类和参数都有啥区别
被final修饰的类不能被继承,方法不能被重写,变量只能赋值一次

hashmap和hashtable的区别
HashMap的key或者value不能为null,HashTable可以
HashMap不是线程安全的,在put方法中有个count++的操作,而HashTable的方法都被synchronized修饰,是线程安全的
HashTable继承自Dictionary,HashTable继承自AbstractMap接口

Arraylist和hashmap的原理
HashMap:先通过key的HashCode计算出元素的下标,判断他的存储位置,存储时,如果key的Hash值相等,
有两种情况 1、如果key相等,则直接覆盖,2、如果key不相等,则把当前的键值对放入链表中,链表超过8转换成红黑树
为什么链表长度超过8转换成红黑树?

如何通过反射获取对象
类名.getClass/Class.forname/类.Class

深克隆和浅克隆的区别
浅克隆赋值对象的同时,会赋值对象的值,两个对象公用一个内存地址,改变一个另一个会发生改变。浅克隆相反

创建对象的方法有哪几种
反射、new、克隆

线程池的执行流程
任务到达线程池,如果当前没有线程,就新建线程执行任务,直到当前线程数核心线程数,之后的任务会放到队列里面等待执行,如果队列满了,就会请求最大线程数,
直到当前线程
最大线程数,之后的线程都会根据策略拒绝,当任务执行完成,并且线程空闲时间==线程存活时间,线程会被销毁

线程池了解吗?核心参数说下
corepoolsize:核心线程数
maxpoolsize:最大线程数
queue:阻塞队列
keepalvetime:线程存活时间
ThreadFactory:线程工厂,用来创建线程
Hander:根据拒绝策略处理被拒绝的任务

java的队列了解吗
java.util.concurrent 包下都有哪些常用类
TimeUnit
Callable,类似Runnable,可以和future合作能够获取到返回值
BlockQueue阻塞队列
ReentLock可重入锁
ConcurrentHashMap:
ConcurrentHashMap如和保证线程安全
ConcurrentHashMap是把Hash表分为16个桶,每个桶都类似于一个HashTable,并且在每个桶上都进行了lock操作,比table的加锁更细,并发效果更好,

线程中start和run的区别
start可以改表线程的状态由new–》runnable,,然后在通过run运行线程,并且不能多次调用,run方法只是一个普通的方法,可以多次调用
start() 可以启动一个新线程,run()不能
start()不能被重复调用,run()可以
start()中的run代码可以不执行完就继续执行下面的代码,即进行了线程切换。直接调用run方法必须等待其代码全部执行完才能继续执行下面的代码。
start() 实现了多线程,run()没有实现多线程。

wait和sleep的区别
wait数据object方法,sleep数据Thread方法
wait必须被唤醒才能继续接下来的操作,sleep可以自动唤醒
wait是Object的方法,而sleep是Thread的方法。
sleep方法不会释放锁,可以定义时间,时间过后会自动唤醒。wait方法会释放锁。
sleep不会释放资源,wait进入线程等待池等待,出让系统资源,其它线程可以占用CPU。一般wait不会加时间限制,这是因为如果wait线程运行的资源不够,再出来也没用,要等待其它线程调用notify或notifyAll唤醒等待池中所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒,如果时间不到,只能用interrupt()强行打断。
wait、notify、notifyAll只能在同步控制方法或同步控制块中使用,而sleep可以任何地方使用。
sleep必须捕获异常,wait、notify、notifyAll则不用。

runnable和callable的区别
runnable的底层方法是一个没有被普通的run方法,没有返回值,不能抛出异常。而Callable的底层call方法,可以抛出异常,有一个泛型v的返回值,可以和future合作获取到线程状态,返回结果等数据

jvm的内存结构
主要分为5个部分:堆、方法去、虚拟机栈、程序计数器、本地方法栈
其中线程共享的有堆和方法区,其余都是线程私有的
堆主要存储一些对象
方法区主要存储常量量变量一类的
JVM内存模型:是一组规范、规则
原子性:就是说一个操作不能被打断,要么执行完要么不执行,也就是说在并发访问时是线程非安全的,要想保证原子性就得对访问该数据的地方进行同步操作,譬如 synchronized 等。
可见性:就是说当一个线程对共享变量做了修改后其他线程可以立即感知到该共享变量的改变,synchronized、Lock、final 都可以保证变量的可见性。
有序性:就是说 Java 内存模型中的指令重排不会影响单线程的执行顺序,但是会影响多线程并发执行的正确性

如何判定一个对象是否可以被回收
GCroot:所有对象都是数据GCroot树下的子节点,通过引用链于对象链接,当某个对象没有办法被GCroot链接到,会被第一个标记,被标记的方法如果有必要执行finalze方法,
就会被放入f-queue中,等待第二次标记,稍后gc会对f-queue中的对象进行二次标记,如果在此期间对象重新与引用链进行链接,就不会被回收,反之会被回收掉
引用计数法:给对象添加一个计数器,对象每被引用就把计数器加一,反之减一,当计数器为0的时候,对象被回收

可以作为GCRoot的有哪些
字符串常量池中的引用
所有被syn修饰的对象

垃圾回收算法了解吗
标记-清除算法
复制算法:把内存区域分成两块,每次使用其中一块,当空间不足时,把存活的对象复制到另一块,然后把不足的清空。
但是98%的对象都是朝夕生死的,所以不需要1:1的比例,分为一块较大的Eden区域和两块较小Suriver区域,当空间不足时,把eden和suriver区域存活下来的对象复制到另一块suriver区域
hotspot默认的比较是8:1,当suriver区域不足时,将会由老年代担保申请内存

eden和survivor比例
8:1

什么是类加载器
ClassLoader用于将class文件加载到JVM中。另外一个作用是确认每个类应该由哪个类加载器加载。

双亲委派模型,使用他有什么好处,不用行吗
当类加载器收到类加载的请求时,他首先不会自己加载这个类,而是把他委托给自己的父类去完成,只有当父类加载器无法完成加载的时候,才会由自己去尝试加载

内存溢出和内存泄漏
程序无法申请到足够的内存
对象占用的内存空间无法被正常释放

springmvc的执行流程
前端发送请求到前端控制器–》前端控制器拿到url到处理器映射器去找对应的方法,找不到报404,找到后告诉控制器
控制器拿到方法后去处理器适配器执行——》出错报500,没出错把结果返回到前端控制器
控制器拿到结果去modeandview去渲染下,返回到控制器在返回到前台

springbean的生命周期
1、实例化一个bean
2、按照spring上下文对bean进行配置
3、设置beanName、applicationContext
4、在初始化之前会执行beanPostprosser的postprosserBeforeInit方法
5、初始化bean
6、初始化之后会执行beanPostProser的postProsserAfter方法
7、当bean不需要的时候会调用destory-method方法进行销毁

对象注入的方法
setter,构造方法,autowire

beanFactory和factoryBean的区别
区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
refresh()方法 用于刷新整个Spring 上下文信息,定义了整个 Spring 上下文加载的流

ApplicationContext和BeanFactory的关系
BeanFactory和ApplicationContext都可以当作spring的容器,生成bean的实例,并且管理容器中的bean
BeanFactory采用延迟加载的形式来注入Bean,只有用到某个Bean的时候,才对Bean进行实例化,只有在使用的时候才会发现问题
ApplicationContext会在容器启动时,一次性创建所有的Bean,在启动时就可以发现Bean存在的问题。因为一起创建所有Bean,所以启动较慢

ioc和aop
ioc和di分别叫做控制反转和依赖注入,是spring的一个核心,最通常的说法就是把对象的控制权交个spring,之前我们需要自己创建的对象,现在可以通过spring来获取到
aop是面向切面编程底层是动态代理,又分为JDK和CGlib动态代理,所谓的动态代理就是说aop框架不会去修改字节码,而是在程序运行期间,在内存中临时生成一个aop对象,
这个对象包含目标类的全部方法,并且在特定的切点做了增强
jdk:要求被代理的方法必须实现接口。JDK动态代理的核心是invocationHanlder接口和proxy.invoke()。当我们调用代理类的
CGLIB:如果目标对象没有实现接口,那么将会选择cglib来代理目标类,cglib是一个类库,可以在运行时动态的生成指定类的一个子类对象,并且覆盖其中特定方法,覆盖方法是可以增强方法
cglib是通过继承方式做动态代理的,如果某个类被标记成final,那么是无法使用cglib做动态代理的

事务的传播行为
1、如果当前有事务就执行当前事务,如果没有,就新建事务。2、如果当前有事务就执行当前事务,没有就抛出异常

动态代理和静态代理的区别
增强时间不同:动态代理是在程序运行期间增强这个类,静态代理是在程序编译期间加强这个类

spring是单例还是多利
默认是单例的,可以通过scope注解改变作用域

spring如何解决跨域问题
crose注解可以解决,或者也可以在web.xml中配置crosefilter

ThradLocal了解吗
可以用来解决多个线程共享变量的问题,比如simpdateformate的问题
也可以用来存储用户的属性 ,比如用户id在整个执行链路中都不会改变

1、脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。
2、不可重复读是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,
由于第二个事务的修改,那么第一个事务两次读到的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
3、幻想读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改
这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值