常见面试题(一)

SSM框架

1、Spring是什么?SpringIOC和AOP,说说你的理解?

答:Spring是一个轻量级的开源的容器框架,用来封装javabean,也是一个中间层框架,可以整合SpringMVC MyBatis等框架来提高企业开发效率,Spring框架的两大亮点就是IOC和AOP。

IOC:控制反转,依赖注入。IOC本质上是容器,用于存放对象,在xml中配置bean,或者使用@Component、@Service等等一些注解,当项目启动时会读取配置,根据全限定类名通过反射创建对象放到容器中(扫描到该注解的类通过反射创建对象放到容器中)。在没有引入IOC时,在A中引用B,因此需要在A中new一个B,我们需要自己手动的创建出对象才能用,A对象和B对象产生直接依赖,对象的控制权在我们手上,而引入IOC后,A对象和B对象在程序启动时就已经加载到了容器中,A、B对象之间没有产生依赖,当使用到对象时,IOC会自动注入。

AOP:面向切面编程,一种横切的思想,为解耦而生。就是横向抽取机制,取代传统的纵向继承。AOP的底层原理就是动态代理,来对已有的方法进行增强,比如日志记录、异常处理、事务管理等。

2、使用jdk代理和cjlib的区别?

答:jdk动态代理:接口+实现类来代理目标类,采用拦截器(必须实现InvocationHandler)和反射机制。只能对实现了接口的类生成代理;

cjlib字节码增强:没有接口,只需实现类,动态生成目标类的子类,通过回调方法配置拦截。对目标类生成一个子类,覆盖其中的方法,并覆盖其中的增强方法。

cjlib底层采用ASM字节码生成框架,在1.6之前比jdk代理采用反射的效率要高;1.8之后对JDK已经优化了,只有在大量调用的时候cglib才快

3、SpringBean的生命周期?

单例:容器创建时,对象诞生,容器销毁时,对象销毁

多例:每次请求

构造一个bean实例、注入属性、initializeBean初始化(先调用BeanPostProcessorBeforeInnilization前置方法、调用初始化方法、BeanPostProcessorAfterInitialization方法)、返回、销毁

4、Spring支持的几种bean的作用域?

答:1、singleton:默认为单例,每个容器只有一个bean实例,单利模式由BeanFactory自身维护;2、prototype:多例,为每个bean请求提供一个实例,每次注入时都会创建一个新的对象;3、request:在每个HTTP请求创建一个bean实例;4、session:在session中创建一个实例,session过期后,bean随之销毁;5、application:在servletContext的生命周期中复用一个单例对象

5、默认是单例模式,那原因知道吗?

答:提高性能,因为单例模式容器只会创建一个对象,因此减少新生成实例的消耗,减少JVM垃圾回收,因为不会给每个请求都创建新对象,索引回收的对象少了;可以快速的获取到bean,因为只有第一次是生成的,除此之外都会从缓存中获取。

6、单例模式是线程安全的吗?如果保证线程安全该怎么做?

答:不是安全的,如果保证线程安全

8、Spring中用到了哪些设计模式?

答:1、简单工厂:BeanFactory就是简单工厂,根据传入一个唯一标识获取Bean对象;2、工厂方法:实现了BeanFactory接口的bean,Spring调用getBean()时,会自动调用该bean的getObject()方法;3、单例模式:Spring默认创建对象就是单利模式;4、适配器模式:这需要说到整合的SpringMVC,Spring定义了一个适配器接口,使得每一个controller有对应的适配器实现类,代替controller执行响应方法,用来完成SpringMVC的扩展;5、动态代理模式:AOP中就使用了;6、观察者模式:常用在listener的实现

9、Spring事物的传播机制?

10、SpringBoot的作用?

11、SpringBoot如何做到自动配置?

答:1)、Springboot在启动时,扫描包,在主启动类的包或者子包都会扫描,从类路径下/META-INF/spring.factories获取指定的值;2)、将这些自动配置的类导入容器自动配置类就会生效,进行自动配置;

12、@Component、@Service、@Controller有什么区别,如果在Controller上使用@Service会怎么样?

13、Restful风格是什么?

14、Mybatis中的#和$的区别?

答:#{}:会将sql中的#{}替换为?,占位符,调用预编译赋值,变量替换是在DBMS中,变量替换后,#{}对应的变量自动加上单引号;${}:会将${}替换成变量的值,调用statement赋值,在DBMS外,变量替换后,${}对应的变量不会加上单引号;因此使用#{}可以有效防止sql注入,提高系统的安全性。

15、Mybatis中解析sql是在哪一层?

16、分页怎么实现,除了sql语句的方式?

17、SpringMVC的基本流程?

18、SpringMVC中的控制器是不是单例模式?如果是,如何保证线程安全呢?

答:控制器是单例模式。Spring中保证线程安全的方法:1、将scop设置成非单例的;2、最好的方式是将控制器设置成无状态模式(也就是无属性),在controller中不携带数据,但可以引用无状态的service和dao

MySQL

1、innodb的事物隔离级别?

答:事物的特性:原子性、一致性、隔离性、持久性;脏读:一个事物读到另一个没有提交的事物;不可重复读:一个事物中的两次读取数据不一致;幻读:一个事物读取了几条数据,另一个事物做了插入操作并提交,此时事物读取的记录数出现了之前没有的;

事物隔离级别:读未提交、读已提交、可重复读、串行化

索引的基本原理?

答:索引是一种用来快速查找的数据结构,将无序的数据变成有序的查询。比如哈希索引,数据分散在内存,将数据计算出哈希值根据特定顺序放到哈希表,如果查某条数据,将数据进行哈希算法,在表中找到哈希值,然后根据这个只找到数据的地址,就找到了这条记录。理论上是将创建索引的列内容进行排序,将排序结果生成倒排表,在倒排表内容上拼上数据地址链,在查询的时候先拿到倒排表的内容,再取出数据地址链,从而拿到具体数据。

mysql聚簇索引和非聚簇索引的区别?

答:聚簇索引和非聚簇索引都是B+数的数据结构;    聚簇索引:将数据存储和索引按照一定的顺序放到了一起,找到了索引也就找到了数据,数据的物理存放顺序和索引顺序是一致的。   非聚簇索引:数据和索引各自分开,叶子节点不存储数据,存储的是数据行地址。

2、索引是越多越好吗?为什么?

答:不是得 比如表的数据量很少  就不必建索引  因为索引也需要开销,这就反而降低了查询速度。而且索引也需要空间进行管理。

3、索引是如何实现的?

5、为什么不用Btree而用B+Tree呢?

6、索引失效、索引覆盖都是什么意思?

答:索引失效:创建的索引没有用到,比如使用like %xxx 这会导致索引失效

7、联合索引该如何使用?

答:1、最佳左前缀法则;2、不能使用范围条件右边的列;3、索引列上不做计算、函数等操作,会造成索引失效;4、尽量使用覆盖索引,减少select *;5、like以通配符开头,索引失效;6、不等值或or索引会失效。        
口诀:全值匹配我最爱,最左前缀要遵守;带头大哥不能死,中间兄弟不能断;索引列上少计算,范围之后全失效;LIKE百分写最右,覆盖索引不写星;不等空值还有or,索引失效要少用;VAR引号不可丢,SQL高级也不难;

8、MySql查询时如何根据索引查找?

9、执行计划有用过吗?其中哪些字段需要注意?

答:
id字段:id相同,从上往下执行,id不同,id越大优先级越高
select_type:执行表的类型,SIMPLE(简单查询)、PRIMARY(最外层主查询)、SUBQUERY(子查询)、DERIVED(临时表)
type字段:system>const>eq_ref>ref>range>index>all
possible_keys:可能使用到的索引
key:实际上使用到的索引
key_len:索引用到的字节,同样的sql,key_len越小越好
ref:显示索引的那一列呗使用了,如果可能的话,是一个常数。哪些列上的值或常数被索引上的值用到
rows:根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数,越小越好
Extra:Using filesort(使用了文件排序,效率很低)、Using temporary(使用了临时表保存了中间结果,常见order by,group by)、Using index(使用了索引,非常好)、Using where(使用了where过滤)

10、优化sql的流程?

11、刚才提到创建索引,你如何考虑索引的创建的?
答:索引应该建立在经常查询的字段上,频繁修改的字段不建立索引;如果数据的重复性特别高的字段上也不建立索引,要建立在值比较唯一的字段上;where和join中出现的列需要加索引;

12、mysql中的索引有哪些?

java线程

1、什么是进程?什么是线程?线程和进程有什么区别?
答:进程:是正在运行的程序,每个进程都有自己的内存空间和系统资源。        线程:每个进程运行多个任务,每个任务是一个线程,线程是进程的执行单元        单线程:程序有一条执行路径        多线程:程序有多条执行路径        多进程:提高CPU的使用率        多线程:提高应用程序的使用率;

2、如何实现多线程?
答:继承Thread类,重写run()方法; 实现Runnable接口,并实现run()方法。

3、线程的生命周期、线程的几种状态?
答:线程的几种状态:创建、就绪、运行、阻塞、死亡;        阻塞分为:等待阻塞、同步阻塞、其他阻塞        等待阻塞:运行的线程执行wait()方法,线程进入等待池,进入该状态时不能自动唤醒,须依靠其它线程调用notify()或notifyAll()方法才能被唤醒,wait方法是Object类的方法;        同步阻塞:运行的线程获取同步锁时,若该同步锁被其他线程占用,则JVM会把该线程放入锁池中,当前面的线程释放同步锁后,锁池中的线程竞争同步锁,持有同步锁的线程等待CPU的资源分配;        其他阻塞:运行的线程执行sleep方法或join方法,或者发出了I/O请求时,JVM会将该线程置为阻塞,当状态超时,join等待线程终止或者超时时、或者I/O请求处理完成时,线程重新转入就绪队列。Sleep方法是Thread类的静态本地方法。

4、run()方法和start()方法有什么区别?
答:start()方法是启动一个线程,使该线程进入就绪状态,而非运行状态。由JVM通过调用线程类的run()方法完成实际操作,当run()方法结束后,线程终止。直接调用run()方法,就相当于调用普通方法,而不是启动一个线程。

5、sleep()方法和wait()方法有什么区别?
答:1)、锁池:所有需要竞争同步锁的线程程都会放到锁池中,比如当前对象的锁已经被其中一个线程得到,那么其他线程需要在这个锁池中等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程竞争到锁后,进入就绪队列,等待CPU资源分配。        2)、等待池:当调用wait()方法后,线程会放到等待池,等待池中的线程是不会竞争同步锁,只有调用了notify()或notifyAll()方法后等待池的线程才回去竞争同步锁,notify()方法是随机从等待池中选中一个线程放入锁池,而notifyAll是将等待池中的所有线程都放入到锁池中。        
sleep()方法是Thread类的静态本地方法,而wait()方法是Object类的本地方法;
sleep()方法是不会释放锁,带着锁冻结,而是让线程暂停一段时间,当定时时间结束再重新参与CPU的调度,而wait()方法会释放锁,使线程放入等待池。
sleep方法是不需要被唤醒的,休眠之后会退出阻塞,但是wait()需要
sleep()多用于线程休眠,而wait()多用于多线程之间的通信
yield()方法使线程直接进入就绪状态,释放CPU的执行权,但保留了CPU的执行资格,也就是说正在运行的线程调用yield()方法后进入就绪状态,很有可能马上又被执行
join()方法执行后,线程进入阻塞,例如在线程A中调用线程B的join()方法,则线程A会进入阻塞,知道线程B结束或中断,A才会执行;

6、终止线程的方法有哪些?
答:stop()方法、suspend()方法

7、synchronized与lock有什么异同?
答:synchronized可加在方法上,也可加在特定的代码块中,括号中表示需要锁的对象;而lock需要显示的指定起始位置和终止位置,synchronized是托管给JVM实现,而lock是通过代码实现。

8、什么是守护线程?
答:守护线程是为其他线程服务的,俗称其他线程的保姆,一般具有较低的优先级。比如JVM中的垃圾回收器就是一个守护线程。只要JVM启动,它就会始终在运行,实时监控和管理系统中可以被回收的资源。

9、线程安全的理解?

10、ThreadLock的原理和使用场景?

Java基础

1、JDK、JRE、JVM之间的关系?
答:JDK:java开发工具、JRE:java运行环境、JVM:java虚拟机;
JDK包含JRE和java工具(javac、java),JRE包含JVM和java核心类库;

2、什么是面向对象?面向对象和面向过程的区别?
面向对象对比面向过程,比如洗衣服
面向过程:打开洗衣机->放衣服->放洗衣粉->清洗->甩干
面向对象:拆分人和洗衣机,人:打开洗衣机、放入衣服、放洗衣粉。洗衣机:清洗、甩干
面向过程注重每一个步骤及顺序直接高效,面向对象注重有哪些参与者,以及各自的职责。面向对象更易于复用、扩展和维护。

3、面向对象有哪些特征?
封装、继承、多态
封装:比如getter/setter方法,将属性私有化,对外提供get/set方法来操作属性
继承:子类继承父类,子类拥有父类的特性,可以扩展自己的其他功能
多态:比如方法重写,父类引用指向子类对象,cat和dog都可抽象出一个animal 当操作时,可以Animal animal = new Cat(),提高程序扩展性

4、重载和覆盖的区别?
重载:发生在同一个类中,方法名相同,参数列表不同
重写:发生在父子类中,子类重写父类方法,方法名和参数列表都相同。返回值范围小于等于父类,抛出异常范围小于等于父类,修饰符范围大于等于父类,若父类方法私有,子类不可重写。

5、==和equals、hashcode的区别?
若==:基本类型比较的是变量值,引用类型比较的是地址
equals:object中默认是==的比较,需要重写。String中重写了equals方法,比较的是字符串的内容

6、接口、抽象类的区别?
抽象类:1、可存在普通成员方法,而接口只能是public abstract方法;2、抽象类成员变量可多类型,接口的成员变量只能是public static final类型;3、抽象类只能单继承,接口可多实现;
接口的设计目的:是对类进行约束,只约束哪些行为,而不去具体实现;
抽象类的设计目的:代码复用,不允许实例化,抽象类是is的关系,而接口是like的关系;

7、static关键字的作用?
分配单一的内存空间,与对象创建数量无关,也就是共享;实现方法或属性与类关联在一起而不是对象,也就是说在不创建对象的情况下可直接通过类调用
修饰成员变量:静态变量属于类,多个实例对象指向同一个地址,只要静态变量所在的类被加载,则静态变量就会被分配空间,因此可直接使用。而没有static修饰的变量属于对象,只有对象被创建才会被分配内存空间,从而才能使用。
修饰成员方法:不需要创建对象就可以直接通过类名调用;静态成员方法只能访问静态成员变量或方法,不能使用this或super关键字,因为static修饰的方法被调用时,这个类的对象可能还没被创建出来。
实现单例模式:单例模式的特点是该类只能有一个实例

8、值传递和引用传递的区别?
值传递不影响实参的值,引用传递会影响实参的值

9、String、StringBuffer、StringBuilder的区别?
String类被final修饰,值不可变,StringBuffer和StringBuilder是可变长的,用append改变字符串,如果字符串不会频繁改变用String,如果会频繁改变用StringBuffer或StringBuilder,若考虑多线程共享变量时,则采用StringBuffer,因为StringBuffer使用Synchronized修饰,是线程安全的。

10、java中数组是不是对象?
是对象,因为数组有自己的属性(length),还有一些方法(如clone),对象的特点就是封装数据,对外部提供方法,因此是对象。

11、finally块中代码什么时候被执行?
当执行完catch最后执行finally中的代码

12、javaIO流的实现机制是什么?
流的本质是传输数据,根据处理数据类型的不同,可分为字节流(8bit为为单位)或字符流(16bit为单位),

13、什么是迭代器?迭代器的作用是什么?
迭代器(Iterator)是一个对象,他的作用是遍历容器中的各个元素,通过iterator方法返回一个迭代器,然后通过Iterator的next()方法返回第一个元素,hasNext()方法判断容器中是否有元素,如果有,再次调用next()方法获取下一个元素。remove()方法删除迭代器返回的元素。

14、HashMap的底层原理?

15、什么是反射机制?
可以在运行时动态的创建类的对象,类加载Class.forName();类名.Class;实例.getClass;
创建对象的方法:1、new一个;2、通过反射Class.forName()加载类,然后调用newInstance()方法创建对象;3、通过clone()方法创建;4、通过反序列化的方式创建对象;

16、什么是类加载器?类的加载过程?
通过类的权限定名获取该类的二进制字节流
类加载器:BootstrapClassLoader引导类加载器、ExtClassLoader扩展类加载器、AppClassLoader系统类加载器;
BootstrapClassLoader:(顶级,java核心类用该类加载,用于加载java的核心类库【加载包名为java、javax、sun等开头的类】,加载扩展类加载器和应用程序类加载器);
ExtClassLoader:(二级,派生于ClassLoader,从jdk的安装目录jre/lib/ext子目录下加载类库);
AppClassLoader:(三级,用户自定义类由该类加载);
自定义类加载器(所有派生于ClassLoader的加载器)
类的加载过程:加载、链接、初始化
加载:通过一个类的权限定名获取此类的二进制字节流;将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口;
链接:
初始化:

17、什么是双亲委派?
是一种任务委派的模式。如果一个类加载器收到了类加载的请求,它不会自己去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终达到顶级的启动类加载器;如果父类加载器可以完成类加载任务,则就成功返回,若无法完成加载任务,子加载器才会尝试自己去加载,这就是双亲委派。

18、GC如何判断对象可以被回收?
引用计数法:每个对象有一个引用计数器,新增一个引用对象时,则计数器加一,引用释放时,计数器减一,当计数为零时,则对象可回收。
可达性算法:从GCRoots开始向下搜索,所走过的路径称为引用链。当一个对象到GCRoots没有任何引用链时,则证明对象不可用,则JVM判断是可回收对象。
GCRoots的对象:1、虚拟机栈中的引用对象;2、方法区中类静态属性引用的对象;3、方法区中常量引用的对象;4、本地方法栈中引用的对象(Native方法)

19、如果catch代码块中有return,那么finally中的代码还会执行吗?
会,在return之前执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值