1.和equals的区别是什么?
== 作用:
equals()方法的作用:
2.基本类型和包装类对象使用 == 和 equals进行比较的结果?
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2); //打印true
System.out.println(i3==i4); //打印false
使用equals()比较
不同类型的对象对比,返回false
byte b1 = 127;
Byte b2 = new Byte("127");
Byte b3 = new Byte("127");
System.out.println("Byte 基本类型和包装对象使用 == 比较 : " + (b1 == b2));//true
System.out.println("Byte 基本类型和包装对象使用 equals 比较 : " + b2.equals(b1));//true
System.out.println("Byte 包装对象和包装对象使用 == 比较 : " + (b2 == b3));//false
System.out.println("Byte 包装对象和包装对象使用 equals 比较 : " + b2.equals(b3));//true
System.out.println();
3.装箱和拆箱的执行过程?
4.hashCode()相同,equals()也一定为true吗?
首先,答案肯定是不一定。同时反过来 equals() 为true,hashCode() 也不一定相同。
关于 hashCode() 和 equals() 是方法是有一些 常规协定:
1、两个对象用 equals() 比较返回true,那么两个对象的hashCode()方法必须返回相同的结果。
2、两个对象用 equals() 比较返回false,不要求hashCode()方法也一定返回不同的值,但是最好返回不同值,以提搞哈希表性能。
3、重写 equals() 方法,必须重写 hashCode() 方法,以保证 equals() 方法相等时两个对象 hashcode() 返回相同的值。
5.final在java中的作用
final 语义是不可改变的。
6.finally语句块一定执行吗?
不一定,如
代码如下:
public static String test() {
String str = null;
int i = 0;
if (i == 0) {
return str;//直接返回未执行到finally语句块
}
try {
System.out.println("try...");
return str;
} finally {
System.out.println("finally...");
}
}
public static String test2() {
String str = null;
int i = 0;
i = i / 0;//抛出异常未执行到finally语句块
try {
System.out.println("try...");
return str;
} finally {
System.out.println("finally...");
}
}
public static String test3() {
String str = null;
try {
System.out.println("try...");
System.exit(0);//系统退出未执行到finally语句块
return str;
} finally {
System.out.println("finally...");
}
}
7.final与static的区别
static:
final:
8.java中操作字符串都有哪些类?它们之间有什么区别?
Java 中,常用的对字符串操作的类有 String、StringBuffer、StringBuilder
9.如何将字符串反转?
10.String类的常用方法有哪些?
String 类的常用方法:
11.普通类和抽象类有哪些区别?
12.抽象类能使用final修饰吗?
不能,抽象类是被用于继承的,final修饰代表不可修改、不可继承的。
13.接口和抽象类有什么区别?
14.Java中的 << >> >>> 是什么?
System.out.println("16 <<1 : " + (16 <<1));//32
System.out.println("16 >> 3 : " + (16 >> 3));//2
System.out.println("16 >>> 2 : " + (16 >>> 2));//4
System.out.println("-16 >> 2 : " + (-16 >> 2));//-4
System.out.println("-16 >>> 2 : " + (-16 >>> 2));//1073741820
简单理解:
<<1 相当于乘以2
>> 1 相当于除以2
>>> 不考虑高位的正负号,正数的 >>> 等同于 >>
15.throw和throws的区别?
throw:
表示方法内抛出某种异常对象(只能是一个)
用于程序员自行产生并抛出异常
位于方法体内部,可以作为单独语句使用
如果异常对象是非 RuntimeException 则需要在方法申明时加上该异常的抛出,即需要加上 throws 语句 或者 在方法体内 try catch 处理该异常,否则编译报错
执行到 throw 语句则后面的语句块不再执行
throws:
方法的定义上使用 throws 表示这个方法可能抛出某些异常(可以有多个)
用于声明在该方法内抛出了异常
必须跟在方法参数列表的后面,不能单独使用
需要由方法的调用者进行异常处理
16.内部类的作用和特点
作用:
特点:
17.Java跨平台运行的原理
18.Java的安全性体现在哪里?
使用引用取代了指针,指针的功能强大,但是也容易造成错误,如数组越界问题
拥有一套异常处理机制,使用关键字 throw、throws、try、catch、finally
强制类型转换需要符合一定规则
字节码传输使用了加密机制
运行环境提供保障机制:字节码校验器->类装载器->运行时内存布局->文件访问限制
不用程序员显示控制内存释放,JVM 有垃圾回收机制
19.什么是JVM?
20.面向过程和面向对象的理解
软件开发思想,先有面向过程,后有面向对象
在大型软件系统中,面向过程的做法不足,从而推出了面向对象
都是解决实际问题的思维方式
两者相辅相成,宏观上面向对象把握复杂事物的关系;微观上面向过程去处理
面向过程以实现功能的函数开发为主;面向对象要首先抽象出类、属性及其方法,然后通过实例化类、执行方法来完成功能
面向过程是封装的是功能;面向对象封装的是数据和功能
面向对象具有继承性和多态性;面向过程则没有
21.重载和重写的区别:
作用范围:重写的作用范围是父类和子类之间;重载是发生在一个类里面
参数列表:重载必须不同;重写不能修改
返回类型:重载可修改;重写方法返回相同类型或子类
抛出异常:重载可修改;重写可减少或删除,一定不能抛出新的或者更广的异常
访问权限:重载可修改;重写一定不能做更严格的限制
22.this和super关键字的作用
this:
super:
23.static关键字的作用是什么?
24.什么是Java的多态?
实现多态的三个条件:
向上转型:将一个父类的引用指向一个子类对象,自动进行类型转换。
向下转型:将一个指向子类对象的引用赋给一个子类的引用,必须进行强制类型转化。
25.instanceof关键字的作用是什么?
instanceof 运算符是用来在运行时判断对象是否是指定类及其父类的一个实例。
比较的是对象,不能比较基本类型
26.什么是Java的垃圾回收机制?
垃圾回收机制,简称 GC
特点
27.基本类型和包装类的区别?
28.对面向对象的理解
对 Java 语言来说,一切皆是对象。
对象有以下特点:
面向对象的特性:
29.不通过构造方法能创建对象吗?
Java 创建对象的方式:
1、2 会调用构造函数
3、4 不会调用构造函数
30.匿名内部类可以继承类或实现接口吗?为什么?
原因:
31.同步代码块和同步方法有什么区别?
32.静态内部类和非静态内部类有什么区别?
33.静态与非静态成员变量区别?
34.反射的使用场景、作用及优缺点?
使用场景
作用
优点
缺点
35.类的实例化方法调用顺序
类加载器实例化时进行的操作步骤:加载 -> 连接 -> 初始化
36.什么是泛型?为什么要使用泛型?
泛型:
为什么要用泛型?
比如集合类使用泛型,取出和操作元素时无需进行类型转换,避免出现 java.lang.ClassCastException 异常
1.程序,进程和线程的区别联系。
进程:指在系统中正在运行的一个应用程序;程序一旦运行就是进程;进程——资源分配的最小单位。
线程:系统分配处理器时间资源的基本单元,或者说进程之内独立执行的一个单元执行流。线程——程序执行的最小单位。
进程(线程+内存+文件/网络句柄);线程(栈+PC【程序计数器】+TLS【线程本地存储】)
1.进程要分配一大部分的内存,而线程只需要分配一部分栈就可以了.
2.一个程序至少有一个进程,一个进程至少有一个线程.
3.进程是资源分配的最小单位,线程是程序执行的最小单位。
4.一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
2.多线程的实现防方式。
一个有四种。
--继承Thread类
--实现Runnerable接口
--实现Callable接口通过重写FutrueTask包装器来创建Thread线程
--通过线程池创建线程,使用线程池接口ExcutorService结合Callable、Futrue实现有返回结果的多线程。
前两种无返回值原因:通过重写run方法,run方法的返回值是void,所以没有返回值。
后两种有返回值的原因:通过Callable接口可以拿到有返回值,Callable可以看作是Runnable的补充。
3.线程有哪些状态?
初始:新创建了一个线程对象,但还没有调用start()方法。
运行:java线程种将就绪和运行两种状态统称为运行。线程对象创建后,其它线程调用了该对象的start()方法。该状态的线程位于可运行的线程池中,等待被线程调度选中,获取cpu的使用全,此时出去就去状态,就去状态的线程再获得cpu的时间片后可变为原型状态。
阻塞:表示线程阻塞于锁。
等待:进入该状态的线程需要等待其它线程做出一些特定动作(通知或中断)
超时等待:该状态不同于等待,它可以自行的再指定时间后返回。
终止:表示该线程已经执行完毕/
4.sleep()和wait()有什么区别。
类的不同:sleep()来自Thread类,而wait来自Object。
释放锁:sleep()不是放锁,wait释放。
用法不同:sleep()再时间到后会自行恢复,wait()可以用notify()/notifyAll()直接唤醒。
5.notify()与notifyAll()的区别?
notifyAll()会唤醒所有的进程,notify()只会唤醒一个进程。notifyAll()调用后会将所有线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留再锁池等待锁被释放后再次参与竞争。notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。
6.线程的run()和start()有什么区别。
start()用于启动线程,而run()用于执行线程池运行时代码。run()可以重复调用,而start()只能调用一次。
7.创建线程池有哪几种方式?
一共有七种,最核心的是ThreadPoolExecutor(),也是最原始的线程池创建;
newSingleThreadExecutor():它的特点是将工作线程数目限制为1;
newCachedThreadPool():它是一种用来处理大量短时间龚总任务的线程池。它会试图缓存线程并重用,当无缓存线程可用时会创建新线程;
newFixedThreadPool(int nThreads):重用指定数目(nThreads)的线程,任何时候做多有nThreads个工作线程是活动的。这意味着,如果任务数量超过了活动队列的数目,将在工作队列中等待空闲线程的出现;若有动作线程退出,将会有新的工作线程被创建,以不足指定的数目nThreads;
上面3种创建方式都是对ThreadPoolExecutor的封装。
newSingleThreadScheduledExecutor():创建单线程池,返回 ScheduledExecutorService,可以进行定时或周期性的工作调度;
newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似,创建的是个 ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程;
newWorkStealingPool(int parallelism):这是一个经常被人忽略的线程池,Java 8 才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序;
8.线程池都有哪些状态?
RUNNING:这是最正常的状态,接受新的任务,处理等待队列中的任务。
SHUTDOWN:不接受新的任务提交,但会继续处理等待队列中的任务。
STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的进程。
TIDYING:所有的任务都销毁后,线程池的状态在转化为TIDYING状态时,会执行terminated();
TERMINATED:terminated()方法结束后,线程池的状态会变成这个。
9.Java 程序中怎么保证多线程的运行安全?
1.使用安全类;如java.util.concurrent下的类;
2.使用自动锁:synchronized。
3.使用手动锁Lock.
10.多线程中 synchronized 锁升级的原理是什么?
原理:在锁对象的对象头里有一个threadID字段,在第一次访问时threadID为空,jvm让其持有偏向锁,并将threadID设置为线程id,再次进入的时候会先判断threadID是否与其线程id一致,若一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数后,如果还没有正常互殴去到要使用的对象,此时就会把轻量级锁升级为重量级锁,此过程就构成了synchronized 锁升级。
目的:为了减少锁带来的性能消耗。
11.什么是死锁?
线程A持有独占锁a,并尝试去获取独占锁b的同时,线程B持有独占锁b,并尝试去获取独占a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称之为死锁。
12.怎么防止死锁?
1.尽量使用tryLock(long tineout,TimeUnit unit)的方法(ReentrantLock、ReetrantReadWriteLock),设置超时时间,超时可以退出方式死锁。
2.尽量使用java.util.concurrent并发类来代替自己的手写锁。
3.尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
4.尽量减少同步代码块
13.ThreadLocal 是什么?有哪些使用场景?
ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每个线程都可以独立的改变自己的副本,而不会影响其它线程所对应的副本。
使用场景:数据库的连接和session管理等。
14.说一下 synchronized 底层实现原理?
原理:synchronized 是由 monitorenter 和 monitorexit 指令获取线程的执行权;同步方法通过加 ACC_SYNCHRONIZED 标识实现线程的执行权的控制权。monitor对象是同步的基本实现单元,在java6前,monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在java6后,Java虚拟机对他们进行了改变,提供了三种不同的monitor实现,也就是偏向锁,轻量级锁和重量级锁,大大改进了性能。
15.synchronized 和 volatile 的区别是什么?
1.volatile是变量修饰符;synchronized 可以修饰类,方法,代码段。
2.volatile只能实现变量的修改可见性,不能保证原子性;synchronized 都可以保证;
3.volatile不会熬成线程的阻塞;synchronized 可能会;
16.synchronized 和 Lock 有什么区别?
1.synchronized 可以给类,方法,代码块加锁;Lock只能给代码块加锁;
2.synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁不会造成死锁;而Lock需要手动获取锁和释放锁,如果没有unlock()去释放锁就会造成死锁。
3.通过lock可以知道有没有成功获取锁,而synchronized 无法办到。
1…什么是反射?
反射是在运行状态中,对于一个任意的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法功能称之为反射机制。
Java 的动态就体现在反射。通过反射我们可以实现动态装配,降低代码的耦合度;动态代理等。反射的过度使用会严重消耗系统资源。JDK 中 java.lang.Class 类,就是为了实现反射提供的核心类之一。一个 jvm 中一种 Class 只会被加载一次。
2…什么是 Java 序列化?什么情况下需要序列化?
Java序列化是为了保存各种对象在内存中的状态,并且可以把保存的对象状态再读出来。
以下情况需要序列化:
想把内存中的对象保存到一个文件中或者数据库中的时候;
想用套接字在网络上传送对象的时候;
想通过远程方法调用传输对象的时候。
3.动态代理是什么?有哪些应用?
动态代理是运行时动态生成代理类。应用有springaop,java注解获取对象。
4.怎么实现动态代理?
jdk原生动态代理和cglib动态代理。前者基于接口实现,后者基于继承当前类的子类实现的。
5.说说反射在你实际开发中的使用
反射使用不好,对性能影响比较,一般项目中很少直接使用。
反射主要用于底层的框架中,Spring 中就大量使用了反射,比如:
1JSP 和 servlet 有什么区别?
jsp是servlet技术的扩展,本质上就是servlet的简易方式。servlet和jsp最主要的区别在于,servlet的应用逻辑是在Java文件中,并且完全从表示层中的html里分离出来,而jsp是Java和html可以组合成一个扩展名为jsp的文件。jsp侧重于试图,servlet主要用于逻辑控制。
2.jsp的就打内置对象及作用/
1.request 封装客户端的请求,其中包含来自get和post请求的参数;
2.response 封装服务器对客户端的响应
3.application 封装服务器运行环境的对象
4.pageContext 通过该对象可以获取其它8个对象
5.session 封装用户会话的请求
6.page jsp页面本身(相当于Java程序中的this)
7.config Web应用的配置对象
8.exception 封装页面抛出异常的对象
9.out 输出服务器响应的输出流对象
3.说一下 JSP 的 4 种作用域?
1.page:代表一个页面相关的对象和属性
2.request:代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,设计多个web组件;需要在页面显示的临时数据可以放在此作用域
3.session:代表某个用户与服务器简历的一次会话相关的对象和属性,跟某个用户相关的数据应该放在用户自己的session中
4.application:代表与整个web应用程序相关的对象和属性,它的实质上是跨越整个web应用程序,包括多个页面,请求和会话的一个全局作用域。
4.session 和 cookie 有什么区别?
session:是一种将会话状态保存在服务器端的技术
cookie:是在http协议下,Web服务器保存在用户浏览器上的小文本文件,它可以包含有关用户的信息,无论何时用户连接到服务器,web站点都可以访问cookie信息。
存储位置不同:session存储在服务器端;cookie存储在客户端
安全性不同:cookie安全性一般,在浏览器存储,可以被伪造和修改
容量和个数限制:cookie有容量限制,每个站点下的cookie也有个数限制
存储的多样性:session可以存储在Redis,数据库中,应用程序中,而cookie只能存储在浏览器中
5.说一下 session 的工作原理?
session的工作原理是客户端登录完成后,服务器会自动创建对于的session,session创建后,会把session的id返回给客户端,客户端在存储到浏览器中。这样客户端每次访问服务器时,都会带着sessionid,服务器拿到sessionid后,在内存找到对应的session就可以正常工作了。
6.如果客户端禁止 cookie 能实现 session 还能用吗?
可以用,session知识依赖cookie存储sessionid,如果cookie被禁用了,可以使用url中添加sessionid的方式保证session能正常使用
7.spring mvc 和 struts 的区别是什么?
拦截级别:struts2 是类级别的拦截;spring mvc 是方法级别的拦截。
数据独立性:spring mvc 的方法之间基本上独立的,独享 request 和 response 数据,请求数据通过参数获取,处理结果通过 ModelMap 交回给框架,方法之间不共享变量;而 struts2 虽然方法之间也是独立的,但其所有 action 变量是共享的,这不会影响程序运行,却给我们编码和读程序时带来了一定的麻烦。
拦截机制:struts2 有以自己的 interceptor 机制,spring mvc 用的是独立的 aop 方式,这样导致struts2 的配置文件量比 spring mvc 大。
对 ajax 的支持:spring mvc 集成了ajax,所有 ajax 使用很方便,只需要一个注解 @ResponseBody 就可以实现了;而 struts2 一般需要安装插件或者自己写代码才行。
8.如何避免sql注入
1.使用预处理对象preparedStatement,抛弃statement对象
2.使用正则表达式过滤掉字符中的特殊字符。
1.throw 和 throws 的区别?
1.throw:真实抛出一个异常
2.throws:声明可能抛出的一个异常
2.final、finally、finalize 有什么区别?
1.final是修饰符,如果修饰类则不能被继承;修饰方法和变量,则不能改变只能使用
2.finally:是try…catch最后一部分,表示不论发生任何情况都会执行,可以省略,但如果finally部分存在则一定执行里面的代码
3.finalize:是object的protected方法,子类可以覆盖方法以实现资源清理工作,Gc在回收对象之前调用该方法。
3.try-catch-finally 中哪个部分可以省略?
try-catch-finally 其中 catch 和 finally 都可以被省略,但是不能同时省略。
4.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
finally 一定会执行,即使是 catch 中 return 了,catch 中的 return 会等 finally 中的代码执行完之后,才会执行。
5.常见的异常类有哪些?
NullPointerException 空指针异常
ClassNotFoundException 指定类不存在
NumberFormatException 字符串转换为数字异常
IndexOutOfBoundsException 数组下标越界异常
ClassCastException 数据类型转换异常
FileNotFoundException 文件未找到异常
NoSuchMethodException 方法不存在异常
IOException IO 异常
SocketException Socket 异常
1.http 响应码 301 和 302 代表的是什么?有什么区别?
301:永久重定向;302暂时重定向。
区别:301对搜索引擎优化更加有利;302有被提示为网络拦截的风险。
2.forward 和 redirect 的区别?
forward的url不会发生改变,redirect的url会发生改变;
forward可以共享request里的数据,redirect不能共享;
forward比redirect效率高。
3.简述 tcp 和 udp的区别?
tcp和udp是OSI模型中国的运输层中的协议。tcp提供可靠的通信传输,而udp则被常用于让广播和细节控制交给应用的通信协议。
tcp面向连接,udp面向非链接;
tco提供可靠的数据传输,udp不保证;
tcp面向字节流,udp面向报文;
tcp数据传输慢,udp快
4.tcp 为什么要三次握手,两次不行吗?为什么?
我们假设A和B是通信的双方。我理解的握手实际上就是通信,发一次信息就是进行一次握手。
第一次握手:A给B打电话说,你可以听到我说话吗?
第二次握手:B收到了A的信息,然后对A说:我可以听得到你说话啊,你能听得到我说话吗?
第三次握手:A收到了B的信息,然后说可以的,我要给你发信息啦!
在三次握手之后,A和B都能确定这么一件事:我说的话,你能听到;你说的话,我也能听到。这样,就可以开始正常通信了。
注意:HTTP是基于TCP协议的,所以每次都是客户端发送请求,服务器应答,但是TCP还可以给其他应用层提供服务,即可能A、B在建立链接之后,谁都可能先开始通信。
如果采用两次握手,那么只要服务器发出确认数据包就会建立连接,但由于客户端此时并未响应服务器端的请求,那此时服务器端就会一直在等待客户端,这样服务器端就白白浪费了一定的资源。若采用三次握手,服务器端没有收到来自客户端的再此确认,则就会知道客户端并没有要求建立请求,就不会浪费服务器的资源。
5…说一下 tcp 粘包是怎么产生的?
tcp 粘包可能发生在发送端或者接收端,分别来看两端各种产生粘包的原因:
发送端粘包:发送端需要等缓冲区满才发送出去,造成粘包;
接收方粘包:接收方不及时接收缓冲区的包,造成多个包接收。
6.OSI 的七层模型都有哪些?
物理层:利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
数据链路层:负责建立和管理节点间的链路。
网络层:通过路由选择算法,为报文或分组通过通信子网选择最适当的路径。
传输层:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。
会话层:向两个实体的表示层提供建立和使用连接的方法。
表示层:处理用户信息的表示问题,如编码、数据格式转换和加密解密等。
应用层:直接向用户提供服务,完成用户希望在网络上完成的各种工作。
7.get 和 post 请求有哪些区别?
get 请求会被浏览器主动缓存,而 post 不会。
get 传递参数有大小限制,而 post 没有。
post 参数传输更安全,get 的参数会明文限制在 url 上,post 不会。
1.为什么要使用 spring?
spring提供了ioc技术,容器会自动管理依赖的对象,从而不需要自己创建和管理依赖对象,更轻松的实现了程序的解耦。
spring提供了事务支持,使得事务操作变得更加方便。
spring提供了面向切面编程,这样可以更方便的统一处理切面类问题,如统一处理日志,异常等。
2.解释一下什么是 aop?
aop是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。简单来说就是统一处理处理切面类问题,如统一处理日志,异常等。
3.什么是 ioc?
控制反转时spring的核心,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。
简单来说,控制指的是当前对象对内部成员的控制权;控制反转指的时这种控制权不由当前对象管理了,由其它类来管理。
4.spring有哪些主要模块?
spring core:框架的最基础部分,提供ioc和依赖注入特性。
spring context:提供一种框架式的对象访问方式。
spring dao提供了jdbc的抽象层
spring aop面向切面编程实现,可以自定义拦截器,切点等。
spring Web提供了针对web开发的集成特性,例如文件上传,利用servlet listeners进行ioc容器的初始化和针对web的applicationContext
spring web mvc:spring中的mvc封装包提供了web应用的mvc实现。
5.spring 常用的注入方式有哪些?
构造器注入
setter注入(常用)
注解方式注入
6.spring 中的 bean 是线程安全的吗?
spring中的bean默认是单例模式,spring框架并没有对单例bean进行多线程的封装处理。实际上大部分时候spring bean是无状态的(无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象 .不能保存数据,是不变类,是线程安全的。),所以某种程度上bean是线程安全的。
但如果bean有状态的话,那就要开发者自己去保证线程安全了,最简单的就是改变bean的作用域,把“singleton”改为“prototype”,这样请求bean相当于new Bean()了,就可以保证线程安全了。
有状态就是有保存数据存储功能;无状态就是不会保存数据
7.spring 支持几种 bean 的作用域
五种:singleton、prototype、request、session、global-session;
singleton:ioc容器中只存在一个bean实例,bean以单例模式存在,是系统默认值;
prototype:每次容器调用bean时都会创建一个新的实例,及每次getBean()相当于new Bean()操作;
request:每次http请求都会创建一个bean
session:同一个http session共享一个bean实例;
global-session:用于portlet容器,因为每个portlet有单独的session,global-session提供一个全局性的http session。
注意:使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。
8.spring 自动装配 bean 有哪些方式?
no:默认值,表示没有自动装配
byName:根据bean的名称注入对象依赖项;
byType:它根据类型注入对象依赖项;
构造函数:通过构造函数来注入依赖项,需设置大量的参数。
autodetect:容器首先通过构造函数使用autowire装配,如果不能,则通过byType自动装配。
9.spring 事务实现方式有哪些?
声明式事务:声明式事务也有两种实现方式,基于xml配置文件的方式和注解的方式(在类上加@Transaction注解)
编程式事务:以编码的形式管理和维护事务。
10.说一下spring的事务隔离?
spring有五大隔离级别,默认值时ISOLATION_DEFAULT(使用数据库的设置),其它四个隔离级别和数据库的隔离级别一致:
ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
ISOLATIONREADUNCOMMITTED:读未提交,最低隔离级别,事务未提交前,就可被其它事务读取(会出现脏读,不可重复读,幻读)
ISOLATIONREADCOMMITTED:读已提交,一个事务提交后才能被其它事务读取(会造成不可重复读和幻读)
ISOLATIONREPEATABLEREAD:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一直,禁止读取到别的事务未提交的数据(会造成幻读);mysql默认级别。
ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读,不可重复读,幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据。
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
11.spring mvc 运行流程?
1.web请求被DispatcherServlet 拦截
2.DispatcherServlet 调用映射器处理器(handlerMapping)查找页面处理器(handler),handlerMapping向DispatcherServlet 返回handler。handlerMapping把web请求映射为HandlerExecutionChain对象,它包含一个Handler处理器和多个拦截器(handlerInterceptior)对象
3.DispatcherServlet 调用处理器适配器(handlerAdapter)去执行handler
4.handlerAdapter会根据适配的结果去执行handler,handler执行完成后适配器返回ModelAndView,handlerAdapter向DispatcherServlet 返回ModelAndView.
5.DispatcherServlet 调用视图解析器(viewResolver)进行解析,他根据逻辑视图解析成jsp,viewResolver向DispatcherServlet 返回View.
6.DispatcherServlet 进行视图渲染;
7.DispatcherServlet 向用户返回相应结果。
12.@RequestMapping 的作用是什么?
将http请求映射到相应的类/方法上。
13.@Autowired的作用是什么?
@Autowired它可以对类成员变量,方法及构造函数进行标注,完成自动装配的工作,通过@Autowired的使用来消除set/get方法。
1.MyBatis 中 #{}和 ${}的区别是什么?
#{}是预编译处理,${}是字符替换。在使用#{}时,MyBatis会将sql中的#{}替换成?,配合PreparedStatement的方法赋值,自动进行java类型和jdbc类型转换,这样可以有效的防止sql注入,保证程序的运行安全。
${}:表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
2.MyBatis 有几种分页方式?
逻辑分页:使用Mybatis自带的RowBounds进行分页,它是一次性查询很多数据,然后在数据中再进行检索;
物理分页:自己手写sql分页或使用分页插件PageHelper,去数据库查询指定的条数的分页数据的形式。
3…RowBounds 是一次性查询全部结果吗?为什么?
RowBounds 表面是在所有数据中检索数据,其实并非是一次性查询出所有数据,因为Mybatis是对jdbc的封装, 在jdbc驱动中有一个Fatchsize的配置,它规定了每次最多从数据库查询多少数据。
4.MyBatis 逻辑分页和物理分页的区别是什么?
逻辑分页是一次性查询很多数据,然后再在结果中检索分页的数据,这样做的弊端是需要消耗大量的内存,有内存溢出的风险,对数据库压力较大。
物理分页是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的缺点。
5.MyBatis 是否支持延迟加载?延迟加载的原理是什么?
MyBatis 支持延迟加载,设置 lazyLoadingEnabled=true 即可。
原理:调用的时候触发加载,而不是在初始化的时候就加载信息。比如调用 a. getB(). getName(),这个时候发现 a. getB() 的值为 null,此时会单独触发事先保存好的关联 B 对象的 SQL,先查询出来 B,然后再调用 a. setB(b),而这时候再调用 a. getB(). getName() 就有值了,这就是延迟加载的基本原理。
6.说一下 MyBatis 的一级缓存和二级缓存?
一级缓存:指的是Mybatis中的sqlsession对象的缓存,当我们执行查询之后,查询结果会同时存入到sqlsession为我们提供的一块区域中。该区域结构是一个map结构。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否存在,存在的话直接拿出来用。当sqlsession对象消失的时候,mybatis的一级缓存也就消失了(执行增删改,commit,close)。
二级缓存:指的是sqlsessionfactory对象的缓存,由同一个sqlsessionfactory对象创建的sqlsession共享其缓存。
使用步骤:让mybatis框架支持二级缓存(在sqlmapConfig.xml文件中配置);让当前映射文件支持二级缓存(在Userdao.xml中配置);让当前的操作支持二级缓存(在select标签中配置)
1.数据库的三范式是什么?
第一范式:强调的是列的原子性,即数据库每一列都是不可分割的原子数据项。
第二范式:要求在实体的属性完全依赖主关键字,锁为完全依赖指的是不能存在仅依赖主关键字一部分属性。(在1NF的基础上消除非主属性对主键的部分函数依赖)
第三范式:任何非主属性都不依赖其它非主属性。(在2NF基础上消除传递依赖)
2.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 MySQL 数据库,又插入了一条数据,此时 id 是几?
表类型如果是myISAM,id就是8.如果是InnoDB,id就是6.
InnoDB 表只会把自增主键的最大 id 记录在内存中,所以重启之后会导致最大 id 丢失。
3.ACID 是什么?
Atomicity(原子性):是不可分割的最小单位,要么同时成功要么同时失败。
Consistency(一致性):在事务开始前后,数据库完整性没有被破坏。
Isolation(隔离性):各个事务之间相互独立。
Durability(持久性):当事务提交或回滚后,数据库会持久化保存数据,不会丢失。
4.char 和 varchar 的区别是什么?
char:固定长度,当你输入"abc"三个字符的时候,它们占的空间还是 10 个字节,其他 7 个是空字节。
优点:效率高;缺点:占用空间;适用场景:存储密码的 md5 值,固定长度的,使用 char 非常合适。
varchar:可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。
5…MySQL 的内连接、左连接、右连接有什么区别?
内连接关键字:inner join;左连接:left join; 右连接:right join.
内连接是把匹配的关联数据显示出来;
左连接是左边的表全部显示出来,右边的表显示出符合条件的数据;右连接与之相反。
6.MySQL 索引是怎么实现的?
索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的。
7.说一下 MySQL 常用的引擎?
InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count(*) from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。
MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(*) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。
8.如何做 MySQL 的性能优化?
为搜索字段创建索引;
避免使用select *,列出需要查询的字段;
选择正确的存储引擎;
9.sql执行顺序
SQL 不同于与其他编程语言的最明显特征是处理代码的顺序。在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是FROM子句,尽管SELECT语句第一个出现,但是几乎总是最后被处理。
每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回 给调用者。如果没有在查询中指定某一子句,将跳过相应的步骤。
各个关键字的执行顺序
(8)SELECT (9)DISTINCT (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
10.order by,group by和having的使用
order by 是对行的排序方式,默认的为升序(desc)(降序是asc)。 order by 后面必须列出排序的字段名,可以是多个字段名。
group by 为分组函数,一般和聚合函数配合使用。GROUP BY子句中可以按一个列或多个列进行分组,参与分组的多个列有一个不相同就是不同的组,例如按姓名和年龄分组,必须姓名和年龄一致才算一组。一般如带“每个”关键字的就表示需要进行分组,如:找出每个部门的平均工资,需要按部门进行分组。
having 是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。having子句被限制已经在SELECT语句中定义的列和聚合表达式上。通常,你需要通过在HAVING子句中重复聚合函数表达式来引用聚合值。
Having与Where的区别:
Having是分完组后再进行过滤。
Where是先过滤,再进行分组操作。
不能在WHERE子句中使用聚合函数,可以在HAVING子句中使用聚合函数
如果可以,尽量写Where条件,不写Having。
1.说一下 JVM 的主要组成部分?及其作用?
类加载器(ClassLoader)
运行时数据区(Runtime Data Area)
执行引擎(Execution Engine)
本地库接口(Native Interface)
组件的作用:首先通过类加载器(ClassLoader)会把 Java 代码转换成字节码,运行时数据区(Runtime Data Area)再把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器执行引擎(Execution Engine),将字节码翻译成底层系统指令,再交由 CPU 去执行,而这个过程中需要调用其他语言的本地库接口(Native Interface)来实现整个程序的功能。
2.说一下 JVM 运行时数据区?
程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;
方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
3.说一下堆栈的区别?
堆是用来存放对象的,栈是用来执行程序的;
堆是线程共享的,栈是线程私有的;
堆远大于栈
4.类加载器分类:
启动类加载器(Bootstrap ClassLoader),是虚拟机自身的一部分,用来加载Java_HOME/lib/目录中的,或者被 -Xbootclasspath 参数所指定的路径中并且被虚拟机识别的类库;
其他类加载器:
扩展类加载器(Extension ClassLoader):负责加载\lib\ext目录或Java. ext. dirs系统变量指定的路径中的所有类库;
应用程序类加载器(Application ClassLoader)。负责加载用户类路径(classpath)上的指定类库,我们可以直接使用这个类加载器。一般情况,如果我们没有自定义类加载器默认就是用这个加载器。
学生表:学号,姓名,班级号;班级表:班级号,班级名;分数表:课程号,学号,课程,分数。
1、查询各班各科分数最高的学生学号,姓名(学生表),班级名称(班级表),科目名称,分数(分数表):
select t.stuid,t.stuname,t.classname,t…course,max(t…score)
from (select stu.stuid,stu.stuname,c.classname,sc.course,sc.score from student stu inner join class c on c.classid=stu.classid inner join score sc on stu.stuid=sc.stuid) as t
group by classname,course
2.下面练习题中设计四个表。分别为:
dept表:
emp表
salgrade表
tbyear表
查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。
select d.deptno,d.dname,d.loc,count(*)
from dept d inner join (select deptno,count(*) from emp group by deptno) e
on d.deptno=e.deptno
列出薪金比关羽高的所有员工。
SELECT *
FROM emp e
WHERE e.sal>(SELECT sal FROM emp WHERE ename='关羽')
列出所有员工的姓名及其直接上级的姓名。
SELECT e1.ename,e2.ename 上级
FROM emp e1 LEFT OUTER JOIN emp e2
ON e1.mgr=e2.empno
列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称。
select e1.empno,e1.ename,d.dname
from emp e1 left join emp e2 on e1.mgr=e2.empno
left join dept d on e1.deptno=d.deptno
where e1.hiredatae<e2.hiredate
列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
select d.dname,e.*
from dept d left join emp e
on d.deptno=e.deptno
列出所有文员的姓名及其部门名称,部门的人数。
select e.ename,d.dname,z.count(*)
from emp e inner join dept d on e.deptno=d.deptno
inner join(select deptno,count(*) from emp group by deptno) z
on z.deptno=d.deptno
where e.job='文员'
列出最低薪金大于15000的各种工作及从事此工作的员工人数。
SELECT job,COUNT(*)
FROM emp
GROUP BY job
HAVING MIN(sal)>15000
列出在销售部工作的员工的姓名,假定不知道销售部的部门编号。
SELECT e1.ename
FROM emp e1 INNER JOIN dept d
ON e1.deptno=d.deptno
WHERE d.dname='销售部'
列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级。
SELECT e1.*,e2.ename 上级,d.dname 部门名称,sal.`grade`
FROM emp e1 LEFT OUTER JOIN emp e2 ON e1.mgr=e2.empno
LEFT OUTER JOIN dept d ON e1.deptno=d.deptno
LEFT OUTER JOIN salgrade sal ON e1.sal BETWEEN losal AND hisal
WHERE e1.`sal`>(SELECT AVG(sal) FROM emp)
列出与庞统从事相同工作的所有员工及部门名称。
SELECT e.ename,d.dname
FROM emp e INNER JOIN dept d
ON e.deptno=d.deptno
WHERE e.job=(SELECT job FROM emp WHERE ename='庞统')
.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称。
SELECT e.ename,e.sal,d.dname
FROM emp e LEFT OUTER JOIN dept d
ON e.deptno=d.deptno
WHERE e.sal>ALL(SELECT sal FROM emp WHERE deptno=30)
列出每个部门的员工数量、平均工资。
SELECT d.dname,e1.*
FROM (SELECT e.deptno,COUNT(*),AVG(sal) FROM emp e GROUP BY e.deptno)e1 INNER JOIN dept d
ON e1.deptno=d.deptno;
查出年份、利润、年度增长比
SELECT tb1.*,IFNULL(CONCAT((tb1.zz-tb2.zz)/tb2.zz*100,'%'),0) 年度增长比
FROM tbyear tb1 LEFT OUTER JOIN tbyear tb2
ON tb1.`year`=tb2.`year`+1;