Socket面试题整理

Socket是什么?

socket是应用层与传输层的一个抽象,将复杂的TCP/IP协议隐藏在Socket接口之后,只对应用层暴露简单的接口

socket是一种特殊的文件,它也有文件描述符,进程可以打开一个socket,并且像处理文件一样对它进行read()和write()操作,而不必关心数据是怎么在网络上传输的

socket是一个tcp连接的两端

Socket如何唯一标识一个进程?

socket基于tcp协议实现,网络层的ip地址唯一标识一台主机,而传输层的协议+端口号可以唯一标识绑定到这个端口的进程

通信双方如何进行端口绑定?

通常服务端启动时会绑定一个端口提供服务,而客户端在发起连接请求时会被随机分配一个端口号

Socket属于网络的哪一层?

Socket不算是一个协议,它是应用层与传输层间的一个抽象层。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用,以实现进程在网络中通信

Socket是全双工的吗?

基于TCP协议,是全双工的

HTTP协议是全双工的吗?

HTTP 协议设计的初衷本身就是请求/响应模式,这是规范决定的。不过在技术上是可以利用下层的 TCP 来进行全双工通信的。

Socket与WebSocket的区别

Socket是应用层与传输层的一个抽象,将复杂的TCP/IP协议隐藏在Socket接口之后,只对用户暴露简单的接口

而WebScoket是应用层协议,它也是基于TCP实现,同时借助了HTTP协议建立连接

WebSocket连接过程:

  1. 服务端与客户端建立TCP连接(三次握手)、建立HTTP连接
  2. 客户端(浏览器)向服务端发送一个请求头包含
    Upgrade: websocket
    Connection: Upgrade
    

    的HTTP请求,申请升级到Websocket连接

  3. 服务端回应的响应头:
    HTTP/1.1 101 Switching Protocals
    Connection: Upgrade
    Upgrade: websocket
    

    同意升级协议,至此双方将基于WebSocket协议通信

Socket通信流程


 ·

  (绿色为服务器操作,纯黑色为用户操作)

  服务器根据地址类型(ipv4、ipv6)、socket类型、协议创建socket

  服务器为socket绑定对应的IP地址和端口号

  服务器监听端口号请求,接收用户发来的连接请求,此时服务器没有打开socket

·  用户创建socket

   用户打开socket,并通过IP地址+端口号试图connect服务器的socket

  服务器接收到了用户发来的socket连接请求,被动打开socket,开始接收客户端请求,直到用户返回连接信息。这时候服务器的socket进入堵塞状态,所谓堵塞,即accept();方法一直接收到客户端返回连接信息后才返回,然后开始接收下一个用户端请求

  客户端连接成功,开始向服务器输入状态信息

  服务器accept();方法返回,连接成功

  客户端写入信息

  服务器读取信息

  客户端关闭

  服务端关闭

  

三次握手


  在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接,就是socket通信流程中的建立socket连接部分

   

  

  第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认

  第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态

  第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

Java基础面试知识点总结

https://blog.csdn.net/a724888/article/details/70038420

引用和指针的区别

  • 1. 本质区别:内存 :定义一个指针的时候,编译器为他分配内存,而引用不会单独分配空间,如果sizeof指针和引用的话就会看到区别,sizeof(指针)是系统分配给指针的内存是4个字节,而sizeof(引用)的话 是它所引用对象的大小,如果是int p[10];那么它的大小就是40。;
  • 2.初始化 :引用必须在定义的时候初始化,指针不必;
  • 3.空值 :引用不能为NULL;
  • 4.改变 :引用一旦创建就不能更改引用关系(指针还可以指向其他的对象);

浅析内存泄漏和内存溢出的区别

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

memory leak会最终会导致out of memory!

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。一个盘子用尽各种方法只能装4个果子,你装了5个,结果掉倒地上不能吃了。这就是溢出!比方说栈,栈满时再做进栈必定产生空间溢出,叫上溢,栈空时再做退栈也产生空间溢出,称为下溢。就是分配的内存不足以放下数据项序列,称为内存溢出。

以发生的方式来分类,内存泄漏可以分为4类:

1. 常发性内存泄漏。发生内存泄漏的代码会被多次执行到,每次被执行的时候都会导致一块内存泄漏。

2. 偶发性内存泄漏。发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生。常发性和偶发性是相对的。对于特定的环境,偶发性的也许就变成了常发性的。所以测试环境和测试方法对检测内存泄漏至关重要。

3. 一次性内存泄漏。发生内存泄漏的代码只会被执行一次,或者由于算法上的缺陷,导致总会有一块仅且一块内存发生泄漏。比如,在类的构造函数中分配内存,在析构函数中却没有释放该内存,所以内存泄漏只会发生一次。

4. 隐式内存泄漏。程序在运行过程中不停的分配内存,但是直到结束的时候才释放内存。严格的说这里并没有发生内存泄漏,因为最终程序释放了所有申请的内存。但是对于一个服务器程序,需要运行几天,几周甚至几个月,不及时释放内存也可能导致最终耗尽系统的所有内存。所以,我们称这类内存泄漏为隐式内存泄漏。

从用户使用程序的角度来看,内存泄漏本身不会产生什么危害,作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积,而隐式内存泄漏危害性则非常大,因为较之于常发性和偶发性内存泄漏它更难被检测到。

Session和Cookie的区别与联系

一,Session

1,概念:session存放在服务端,一般情况下,服务器默认30分钟保存这个Session,过了时间限制就会销毁,在销毁之前,开发者可以将用户的一些数据以key和value的形式暂时存放在这个Session中。当然,也有使用数据库将这个Session序列化保存起来,好处是没有了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候,所以一般采取第一种方式,以减轻服务器压力。

2,请求流程:当浏览器第一次发送请求时,服务器自动生成一个Session和一个Session ID用来唯一表示这个Session,并将其通过响应发送到浏览器,当浏览器第二次发送请求的时候,会将前一次服务器响应中Session ID放在请求中一并发送到服务器上,服务器从中提取出Session ID并和保存的所有Session ID进行对比,找到这个用户对应的Session。

3,Session客户端实现形式(即Session ID的保存方法) 一般浏览器提供两种方式来保存,还有一种是程序员使用html隐藏域的方式自定义实现;

【1】使用Cookie来保存,这是最常见的方法,例如“记录我的登录状态”功能的实现正是基于这种方式的。服务器通过设置Cookie的方式将Session ID发送到浏览器,如果我们不设置这个过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。如果我们设置这个时间为若干天后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同样会发送到服务器上。

【2】使用URL附加信息的方式,也就是像我们经常看到JSP网站会有aaa.jsp?JSESSIONID=*一样的。这种方式和第一种方式里面不设置Cookie过期时间是一样的

【3】第三种方式是在页面表单里添加隐藏域,这种方式实际上和第二种方式一样,只不过前者通过GET方式发送数据后者是用POST方式发送数据,但是明显后者比较麻烦。

4,Cookie和Session区别

cookie存储在客户端(浏览器),session存储在服务端,简 单的说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送 当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录,或具有某种权限。由于数据是存储在服务器 上面,所以你不能伪造,但是如果你能够获取某个登录用户的sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务 器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性。

cookie是属于session对象的一种,但有不同,Cookie不会占用服务器资源,是存在客户端内存或者一个cookie文本文件中,而“session”则会占用服务器资源,所以尽量不要使用session,而是用cookie,但我们一直认为cookie是不可靠的,session是可靠的,但是目前很多著名的站点都使用cookie,,有时候为了解决禁用cookie后的页面处理,通常采用url重写技术,调用session中大量有用的方法从session中获取数据后置入页面。

5,Cookie和Session的应用场景

Cookies的安全性能一直是倍受争议的。虽然Cookies是保存在本机上的,但是其信息的完全可见性且易于本地编辑性,往往可以引起很多的安全问题。所以Cookies到底该不该用,到底该怎样用,就有了一个需要给定的底线。

【1】session

登陆验证信息。一般采用Session(“Logon”)=true or false的形式。 用户的各种私人信息,比如姓名等,某种情况下,需要保存在Session里 需要在页面间传递 的内容信息,比如调查工作需要分好几步。每一步的信息都保存在Session里,最后在统一更 新到数据库

【2】cookie

判断用户是否登陆过网站,以便下次登录时能够直接登录。如果我们删除cookie,则每次登 录必须从新填写登录的相关信息。 另一个重要的应用是“购物车”中类的处理和设计。用户可能在一段时间内在同一家网站的不同 页面选择不同的商品,可以将这些信息都写入cookie,在最后付款时从cookie中提取这些信 息,当然这里面有了安全和性能问题需要我们考虑了。

6,使用cookie应遵循的原则

(1)不要保存私人信息。 (2)任何重要数据,最好通过加密形式来保存数据(最简单的可以用URLEncode,当然也可以用完善的可逆加密方式,遗憾的是,最好不要用md5来加密)。 (3)是否保存登陆信息,需有用户自行选择。 (4)长于10K的数据,不要用到Cookies。 (5)也不要用Cookies来玩点让客户惊喜的小游戏。

泛型总结

(改编自网络)

1. Java中的泛型是什么 ? 使用泛型的好处是什么?

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

好处:

1、类型安全,提供编译期间的类型检测

2、前后兼容

3、泛化代码,代码可以更多的重复利用

4、性能较高,用GJ(泛型JAVA)编写的代码可以为java编译器和虚拟机带来更多的类型信息,这些信息对java程序做进一步优化提供条件。

2. Java的泛型是如何工作的 ? 什么是类型擦除 ?

如何工作:

1、类型检查:在生成字节码之前提供类型检查

2、类型擦除:所有类型参数都用他们的限定类型替换,包括类、变量和方法(类型擦除)

3、如果类型擦除和多态性发生了冲突时,则在子类中生成桥方法解决

4、如果调用泛型方法的返回类型被擦除,则在调用该方法时插入强制类型转换

类型擦除:

所有类型参数都用他们的限定类型替换,比如T->Object   ? extends  BaseClass->BaseClass

这是一道更好的泛型面试题。泛型是通过类型擦除来实现的,编译器在编译时擦除了所有类型相关的信息,所以在运行时不存在任何类型相关的信息。例如 List<String>在运行时仅用一个List来表示。这样做的目的,是确保能和Java 5之前的版本开发二进制类库进行兼容。你无法在运行时访问到类型参数,因为编译器已经把泛型类型转换成了原始类型。根据你对这个泛型问题的回答情况,你会 得到一些后续提问,比如为什么泛型是由类型擦除来实现的或者给你展示一些会导致编译器出错的错误泛型代码。请阅读我的Java中泛型是如何工作的来了解更 多信息。

3. 什么是泛型中的限定通配符和非限定通配符 ?

有两种限定通配符,一种是<? extends T>它通过确保类型必须是T的子类来设定类型的上界,另一种是<? super T>它通过确保类型必须是T的父类来设定类型的下界。泛型类型必须用限定内的类型来进行初始化,否则会导致编译错误。另一方面<?>表 示了非限定通配符,因为<?>可以用任意类型来替代

4. List<? extends T>和List <? super T>之间有什么区别 ?

协变:<? extends T>  协变,协变后不能插入数据

逆变:<? super class>  协变的相反过程,可以插入数据,但不能协变

5. 如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?

编写泛型方法并不困难,你需要用泛型类型来替代原始类型,比如使用T, E or K,V等被广泛认可的类型占位符。泛型方法的例子请参阅Java集合类框架。最简单的情况下,一个泛型方法可能会像这样:

public V put(K key, V value) {

return cache.put(key, value);

}

6. Java中如何使用泛型编写带有参数的类?

这是上一道面试题的延伸。面试官可能会要求你用泛型编写一个类型安全的类,而不是编写一个泛型方法。关键仍然是使用泛型类型来代替原始类型,而且要使用JDK中采用的标准占位符。

7. 编写一段泛型程序来实现LRU缓存?

对于喜欢Java编程的人来说这相当于是一次练习。给你个提示,LinkedHashMap可以用来实现固定大小的LRU缓存,当LRU缓存已经满 了的时候,它会把最老的键值对移出缓存。LinkedHashMap提供了一个称为removeEldestEntry()的方法,该方法会被put() 和putAll()调用来删除最老的键值对。当然,如果你已经编写了一个可运行的JUnit测试,你也可以随意编写你自己的实现代码。

8. 你可以把List<String>传递给一个接受List<Object>参数的方法吗?

List<Object> objectList;

List<String> stringList;

objectList = stringList; //compilation error incompatible types

9. Array中可以用泛型吗?

不可以

这可能是Java泛型面试题中最简单的一个了,当然前提是你要知道Array事实上并不支持泛型,这也是为什么Joshua Bloch在Effective Java一书中建议使用List来代替Array,因为List可以提供编译期的类型安全保证,而Array却不能。

10. 如何阻止Java中的类型未检查的警告?

如果你把泛型和原始类型混合起来使用,例如下列代码,Java 5的javac编译器会产生类型未检查的警告,例如

List<String> rawList = new ArrayList()

注意:使用了未检查或称为不安全的操作;

这种警告可以使用@SuppressWarnings(“unchecked”)注解来屏蔽。

11.Java中List<?>和List<Object>之间的区别是什么?

这道题跟上一道题看起来很像,实质上却完全不同。List<?> 是一个未知类型的List,而List<Object> 其实是任意类型的List。你可以把List<String>, List<Integer>赋值给List<?>,却不能把List<String>赋值给 List<Object>。

https://www.iteye.com/blog/zhouchaofei2010-2259899

100道Java基础面试题收集整理(附答案)

不积跬步无以至千里,这里会不断收集和更新Java基础相关的面试题,目前已收集100题。

1.什么是B/S架构?什么是C/S架构

  1. B/S(Browser/Server),浏览器/服务器程序
  2. C/S(Client/Server),客户端/服务端,桌面应用程序

    2.你所知道网络协议有那些?

    HTTP:超文本传输协议
    FTP:文件传输协议
    SMPT:简单邮件协议
    TELNET:远程终端协议
    POP3:邮件读取协议

3.Java都有那些开发平台?

JAVA SE:主要用在客户端开发
JAVA EE:主要用在web应用程序开发
JAVA ME:主要用在嵌入式应用程序开发

4.什么是JVM?java虚拟机包括什么?

JVM:java虚拟机,运用硬件或软件手段实现的虚拟的计算机,Java虚拟机包括:寄存器,堆栈,处理器

  • 堆内存是JVM中最大的一块,由年轻代和老年代组成,而年轻代内存又被分成三部分,Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代的这3种空间年轻代按照8:1:1的比例来分配

  • 方法区存储类信息、常量、静态变量等数据,是线程共享的区域,为与Java堆区分,方法区还有一个别名Non-Heap(非堆)

  • 栈又分为java虚拟机栈和本地方法栈主要用于方法的执行

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

4. JVM执行程序的过程

1) 加载.class文件 2) 管理并分配内存 3) 执行垃圾收集

7. JVM运行时数据区

第一块:PC寄存器

PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。

第二块:JVM栈

JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。

第三块:堆(Heap)

它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。

(1) 堆是JVM中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的

(2) Sun Hotspot JVM为了提升对象内存分配的效率,对于所创建的线程都会分配一块独立的空间TLAB(Thread Local Allocation Buffer),其大小由JVM根据运行的情况计算而得,在TLAB上分配对象时不需要加锁,因此JVM在给线程的对象分配内存时会尽量的在TLAB上分配,在这种情况下JVM中分配对象内存的性能和C基本是一样高效的,但如果对象过大的话则仍然是直接使用堆空间分配

(3) TLAB仅作用于新生代的Eden Space,因此在编写Java程序时,通常多个小的对象比大的对象分配起来更加高效。

(4) 所有新创建的Object 都将会存储在新生代Yong Generation中。如果Young Generation的数据在一次或多次GC后存活下来,那么将被转移到OldGeneration。新的Object总是创建在Eden Space。

第四块:方法区域(Method Area)

(1)在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代。

(2)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

第五块:运行时常量池(Runtime Constant Pool)

存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。

第六块:本地方法堆栈(Native Method Stacks)

JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。

8. JVM垃圾回收

GC (Garbage Collection)的基本原理:将内存中不再被使用的对象进行回收,GC中用于回收的方法称为收集器,由于GC需要消耗一些资源和时间,Java在对对象的生命周期特征进行分析后,按照新生代、旧生代的方式来对对象进行收集,以尽可能的缩短GC对应用造成的暂停

(1)对新生代的对象的收集称为minor GC;

(2)对旧生代的对象的收集称为Full GC;

(3)程序中主动调用System.gc()强制执行的GC为Full GC。

不同的对象引用类型, GC会采用不同的方法进行回收,JVM对象的引用分为了四种类型:

(1)强引用:默认情况下,对象采用的均为强引用(这个对象的实例没有其他对象引用,GC时才会被回收)

(2)软引用:软引用是Java中提供的一种比较适合于缓存场景的应用(只有在内存不够用的情况下才会被GC)

(3)弱引用:在GC时一定会被GC回收

(4)虚引用:由于虚引用只是用来得知对象是否被GC

2. JRE/JDK/JVM是什么关系?

JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台。所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。

JDK(Java Development Kit)是程序开发者用来来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是 安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。

JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。

5.Java是否需要开发人员回收内存垃圾吗?

大多情况下是不需要的。Java提供了一个系统级的线程来跟踪内存分配,不再使用的内存区将会自动回收

6.什么是JDK?什么是JRE?

JDK:java development kit:java开发工具包,是开发人员所需要安装的环境

JRE:java runtime environment:java运行环境,java程序运行所需要安装的环境

7.什么是数据结构?

计算机保存,组织数据的方式

8.Java的数据结构有那些?

线性表(ArrayList)
链表(LinkedList)
栈(Stack)
队列(Queue)
图(Map)
树(Tree)

9.什么是OOP?

面向对象编程

10.什么是面向对象?

世间万物都可以看成一个对象。每个物体包括动态的行为和静态的属性,这些就构成了一个对象。

11.类与对象的关系?

类是对象的抽象,对象是类的具体,类是对象的模板,对象是类的实例

12.Java中有几种数据类型

整形:byte,short,int,long
浮点型:float,double
字符型:char
布尔型:boolean

13.什么是隐式转换,什么是显式转换

显示转换就是类型强转,把一个大类型的数据强制赋值给小类型的数据;隐式转换就是大范围的变量能够接受小范围的数据;隐式转换和显式转换其实就是自动类型转换和强制类型转换。

14.Char类型能不能转成int类型?能不能转化成string类型,能不能转成double类型

Char在java中也是比较特殊的类型,它的int值从1开始,一共有2的16次方个数据;Char<int<long<float<double;Char类型可以隐式转成int,double类型,但是不能隐式转换成string;如果char类型转成byte,short类型的时候,需要强转。

15.什么是拆装箱?

拆箱:把包装类型转成基本数据类型
装箱:把基本数据类型转成包装类型

16.Java中的包装类都是那些?

byte:Byte short:Short int:Integer long:Long float:Float double:Double char:Character boolean:Boolean

17.一个java类中包含那些内容?

属性、方法、内部类、构造方法、代码块。

18.例如: if(a+1.0=4.0),这样做好吗?

不好,因为计算机在浮点型数据运算的时候,会有误差,尽量在布尔表达式中不使用浮点型数据(if,while,switch中判断条件不使用浮点型)

19.那针对浮点型数据运算出现的误差的问题,你怎么解决?

使用Bigdecimal类进行浮点型数据的运算

20.++i与i++的区别

++i:先赋值,后计算
i++:先计算,后赋值

21.程序的结构有那些?

顺序结构
选择结构
循环结构

22.数组实例化有几种方式?

静态实例化:创建数组的时候已经指定数组中的元素,

1

int[] a=new int[]{1,3,3}

动态实例化:实例化数组的时候,只指定了数组程度,数组中所有元素都是数组类型的默认值

23.Java中各种数据默认值

Byte,short,int,long默认是都是0
Boolean默认值是false
Char类型的默认值是’’
Float与double类型的默认是0.0
对象类型的默认值是null

24.Java常用包有那些?

Java.lang
Java.io
Java.sql
Java.util
Java.awt
Java.net
Java.math

25.Java最顶级的父类是哪个?

Object

26.Object类常用方法有那些?

Equals
Hashcode
toString
wait
notify
clone
getClass

27.java中有没有指针?

有指针,但是隐藏了,开发人员无法直接操作指针,由jvm来操作指针

28.java中是值传递引用传递?

理论上说,java都是引用传递,对于基本数据类型,传递是值的副本,而不是值本身。对于对象类型,传递是对象的引用,当在一个方法操作操作参数的时候,其实操作的是引用所指向的对象。

29.假设把实例化的数组的变量当成方法参数,当方法执行的时候改变了数组内的元素,那么在方法外,数组元素有发生改变吗?

改变了,因为传递是对象的引用,操作的是引用所指向的对象

30.实例化数组后,能不能改变数组长度呢?

不能,数组一旦实例化,它的长度就是固定的

31.假设数组内有5个元素,如果对数组进行反序,该如何做?

创建一个新数组,从后到前循环遍历每个元素,将取出的元素依次顺序放入新数组中

32.形参与实参

形参:全称为“形式参数”,是在定义方法名和方法体的时候使用的参数,用于接收调用该方法时传入的实际值;实参:全称为“实际参数”,是在调用方法时传递给该方法的实际值。

33.构造方法能不能显式调用?

不能构造方法当成普通方法调用,只有在创建对象的时候它才会被系统调用

34.构造方法能不能重写?能不能重载?

可以重写,也可以重载

35.什么是方法重载?

方法的重载就是在同一个类中允许同时存在一个以上的同名方法,只要它们的参数个数或者类型不同即可。在这种情况下,该方法就叫被重载了,这个过程称为方法的重载(override)

36.内部类与静态内部类的区别?

静态内部类相对与外部类是独立存在的,在静态内部类中无法直接访问外部类中变量、方法。如果要访问的话,必须要new一个外部类的对象,使用new出来的对象来访问。但是可以直接访问静态的变量、调用静态的方法;

普通内部类作为外部类一个成员而存在,在普通内部类中可以直接访问外部类属性,调用外部类的方法。

如果外部类要访问内部类的属性或者调用内部类的方法,必须要创建一个内部类的对象,使用该对象访问属性或者调用方法。

如果其他的类要访问普通内部类的属性或者调用普通内部类的方法,必须要在外部类中创建一个普通内部类的对象作为一个属性,外同类可以通过该属性调用普通内部类的方法或者访问普通内部类的属性

如果其他的类要访问静态内部类的属性或者调用静态内部类的方法,直接创建一个静态内部类对象即可。

37.Static关键字有什么作用?

Static可以修饰内部类、方法、变量、代码块

Static修饰的类是静态内部类

Static修饰的方法是静态方法,表示该方法属于当前类的,而不属于某个对象的,静态方法也不能被重写,可以直接使用类名来调用。在static方法中不能使用this或者super关键字。

Static修饰变量是静态变量或者叫类变量,静态变量被所有实例所共享,不会依赖于对象。静态变量在内存中只有一份拷贝,在JVM加载类的时候,只为静态分配一次内存。

Static修饰的代码块叫静态代码块,通常用来做程序优化的。静态代码块中的代码在整个类加载的时候只会执行一次。静态代码块可以有多个,如果有多个,按照先后顺序依次执行。

38.Final在java中的作用

Final可以修饰类,修饰方法,修饰变量。
修饰的类叫最终类。该类不能被继承。
修饰的方法不能被重写。
修饰的变量叫常量,常量必须初始化,一旦初始化后,常量的值不能发生改变。

39.Java中操作字符串使用哪个类?

String,StringBuffer,StringBuilder

40.StringBuffer,Stringbuilder有什么区别?

StringBuffer与StringBuilder都继承了AbstractStringBulder类,而AbtractStringBuilder又实现了CharSequence接口,两个类都是用来进行字符串操作的。

在做字符串拼接修改删除替换时,效率比string更高。

StringBuffer是线程安全的,Stringbuilder是非线程安全的。所以Stringbuilder比stringbuffer效率更高,StringBuffer的方法大多都加了synchronized关键字

41.String str=”aaa”,与String str=new String(“aaa”)一样吗?

不一样的。因为内存分配的方式不一样。
第一种,创建的”aaa”是常量,jvm都将其分配在常量池中。
第二种创建的是一个对象,jvm将其值分配在堆内存中。

42.String str=”aa”,String s=”bb”,String aa=aa+s;一种创建了几个对象?

一共有两个引用,三个对象。因为”aa”与”bb”都是常量,常量的值不能改变,当执行字符串拼接时候,会创建一个新的常量是” aabbb”,有将其存到常量池中。

43.将下java中的math类有那些常用方法?

Pow():幂运算
Sqrt():平方根
Round():四舍五入
Abs():求绝对值
Random():生成一个0-1的随机数,包括0不包括1

44.String类的常用方法有那些?

charAt:返回指定索引处的字符
indexOf():返回指定字符的索引
replace():字符串替换
trim():去除字符串两端空白
split():分割字符串,返回一个分割后的字符串数组
getBytes():返回字符串的byte类型数组
length():返回字符串长度
toLowerCase():将字符串转成小写字母
toUpperCase():将字符串转成大写字符
substring():截取字符串
format():格式化字符串
equals():字符串比较

45.判断两个对象是否相同,能使用equlas比较吗?

不能。Equlas大多用来做字符串比较,要判断基本数据类型或者对象类型,需要使用==

46.==与equlas有什么区别?

==可以判断基本数据类型值是否相等,也可以判断两个对象指向的内存地址是否相同,也就是说判断两个对象是否是同一个对象,Equlas通常用来做字符串比较。

47.如何将字符串反转?

Stringbuilder或者stringbuffer的reverse方法

48.面向对象的语言有那些特征?

封装、继承、多态

49.Java中的继承是单继承还是多继承

Java中既有单继承,又有多继承。对于java类来说只能有一个父类,对于接口来说可以同时继承多个接口

50.什么是重写?什么是重载?

重载和重写都是java多态的表现。

重载叫override,在同一个类中多态的表现。当一个类中出现了多个相同名称的方法,但参数个数和参数类型不同,方法重载与返回值无关

重写叫overwrite,是字符类中多态的表现。当子类出现与父类相同的方法,那么这就是方法重写。方法重写时,子类的返回值必须与父类的一致。如果父类方法抛出一个异常,子类重写的方法抛出的异常类型不能小于父类抛出的异常类型。

51.构造方法能不能重载?能不能重写?

可以重载,必须重写

52.如果父类只有有参构造方法,那么子类必须要重写父类的构造方法吗?

必须重写

53.创建一个子类对象的时候,那么父类的构造方法会执行吗?

会执行。当创建一个子类对象,调用子类构造方法的时候,子类构造方法会默认调用父类的构造方法。

54.什么是父类引用指向子类对象?

是java多态一种特殊的表现形式。创建父类引用,让该引用指向一个子类的对象

55.当父类引用指向子类对象的时候,子类重写了父类方法和属性,那么当访问属性的时候,访问是谁的属性?调用方法时,调用的是谁的方法?

子类重写了父类方法和属性,访问的是父类的属性,调用的是子类的方法

56.Super与this表示什么?

Super表示当前类的父类对象
This表示当前类的对象

57.抽象的关键字是什么?

Abstract

58.抽象类必须要有抽象方法吗

不是必须。抽象类可以没有抽象方法。

59.如果一个类中有抽象方法,那么这个一定是抽象类?

包含抽象方法的类一定是抽象类

60.抽象类可以使用final修饰吗?

不可以。定义抽象类就是让其他继承的,而final修饰类表示该类不能被继承,与抽象类的理念违背了

61.普通类与抽象类有什么区别?

普通类不能包含抽象方法,抽象类可以包含抽象方法
抽象类不能直接实例化,普通类可以直接实例化

62.什么是接口?

接口就是某个事物对外提供的一些功能的声明,是一种特殊的java类

63.JAVA为什么需要接口?

接口弥补了java单继承的缺点

64.接口有什么特点?

接口中声明全是public static final修饰的常量
接口中所有方法都是抽象方法
接口是没有构造方法的
接口也不能直接实例化
接口可以多继承

65.接口与抽象类有什么区别?

抽象类有构造方法,接口没有构造方法
抽象类只能单继承,接口可以多继承
抽象类可以有普通方法,接口中的所有方法都是抽象方法
接口的属性都是public static final修饰的,而抽象的不是

66.Java中异常分为哪两种?

编译时异常
运行时异常

67.说几个常见的编译时异常类?

NullPointerException:空指针异常
ArrayIndexOutOfBoundsException:数组下标越界
NumberFormatException:数字转换异常
IllegalArgumentException:参数不匹配异常
InstantiationException:对象初始化异常
ArithmeticException:算术异常

68.异常的处理机制有几种?

异常捕捉:try…catch…finally,异常抛出:throws。

69.如何自定义一个异常

继承一个异常类,通常是RumtimeException或者Exception

70.在异常捕捉时,如果发生异常,那么try.catch.finally块外的return语句会执行吗?

会执行,如果有finally,在finally之后被执行,如果没有finally,在catch之后被执行

71.Try.catch.finally是必须要存在的吗?

Try块必须存在,catch和finally可以不存在,但不能同时不存在

72.Thow与thorws区别

Throw写在代码块内,throw后面跟的是一个具体的异常实例
Throw写在方法前面后面,throws后面跟的是异常类,异常类可以出现多个

73.Error与Exception区别?

Error和Exception都是java错误处理机制的一部分,都继承了Throwable类。

Exception表示的异常,异常可以通过程序来捕捉,或者优化程序来避免。

Error表示的是系统错误,不能通过程序来进行错误处理。

74.使用Log4j对程序有影响吗?

有,log4j是用来日志记录的,记录一些关键敏感的信息,通常会将日志记录到本地文件或者数据库中。记录在本地文件中,会有频繁的io操作,会耗费一些系统资源。记录在数据库中,会频繁地操作数据库表,对系统性能也有一定的影响。但是为了程序安全以及数据的恢复或者bug的跟踪,这点资源消耗是可以承受的。

75.Log4j日志有几个级别?

由低到高:debug、info、wran、error

76.除了使用new创建对象之外,还可以用什么方法创建对象?

Java反射

77.Java反射创建对象效率高还是通过new创建对象的效率高?

通过new创建对象的效率比较高。通过反射时,先找查找类资源,使用类加载器创建,过程比较繁琐,所以效率较低

78.Java中集合框架的有几个?

Coillection、Map。

79.Collection接口下有那些集合框架?

List:线性表、Set:无序集合。

80.List接口有什么特点?

顺序存储、可以有重复值。

81.Set接口有什么特点

无须存储、不能有重复值。

82.ArrayList与LinkedList有什么区别?

ArrayList与LinkedList都实现了List接口。
ArrayList是线性表,底层是使用数组实现的,它在尾端插入和访问数据时效率较高,
Linked是双向链表,他在中间插入或者头部插入时效率较高,在访问数据时效率较低

83.Array与ArrayList有什么不一样?

Array与ArrayList都是用来存储数据的集合。ArrayList底层是使用数组实现的,但是arrayList对数组进行了封装和功能扩展,拥有许多原生数组没有的一些功能。我们可以理解成ArrayList是Array的一个升级版。

84.Map有什么特点

以键值对存储数据
元素存储循序是无须的
不允许出现重复键

85.JDBC操作的步骤

加载数据库驱动类
打开数据库连接
执行sql语句
处理返回结果
关闭资源

86.在使用jdbc的时候,如何防止出现sql注入的问题。

使用PreparedStatement类,而不是使用Statement类

87.怎么在JDBC内调用一个存储过程

使用CallableStatement

88.是否了解连接池,使用连接池有什么好处?

数据库连接是非常消耗资源的,影响到程序的性能指标。连接池是用来分配、管理、释放数据库连接的,可以使应用程序重复使用同一个数据库连接,而不是每次都创建一个新的数据库连接。通过释放空闲时间较长的数据库连接避免数据库因为创建太多的连接而造成的连接遗漏问题,提高了程序性能。

89.你所了解的数据源技术有那些?使用数据源有什么好处?

Dbcp,c3p0等,用的最多还是c3p0,因为c3p0比dbcp更加稳定,安全;通过配置文件的形式来维护数据库信息,而不是通过硬编码。当连接的数据库信息发生改变时,不需要再更改程序代码就实现了数据库信息的更新。

90.Java的io流分为哪两种?

按功能来分

输入流(input),输出流(output)

按类型来分

字节流,字符流

91.常用io类有那些?

File
FileInputSteam,FileOutputStream
BufferInputStream,BufferedOutputSream
PrintWrite
FileReader,FileWriter
BufferReader,BufferedWriter
ObjectInputStream,ObjectOutputSream

92.字节流与字符流的区别

以字节为单位输入输出数据,字节流按照8位传输
以字符为单位输入输出数据,字符流按照16位传输

93.final、finalize()、finally

性质不同

  1. final为关键字;
  2. finalize()为方法;
  3. finally为区块标志,用于try语句中;

作用

  1. final为用于标识常量的关键字,final标识的关键字存储在常量池中(在这里final常量的具体用法将在下面进行介绍);
  2. finalize()方法在Object中进行了定义,用于在对象“消失”时,由JVM进行调用用于对对象进行垃圾回收,类似于C++中的析构函数;用户自定义时,用于释放对象占用的资源(比如进行I/0操作);
  3. finally{}用于标识代码块,与try{}进行配合,不论try中的代码执行完或没有执行完(这里指有异常),该代码块之中的程序必定会进行;

94.抽象类和接口的区别?

抽象类:

  1. 抽象方法,只有行为的概念,没有具体的行为实现。使用abstract关键字修饰,没有方法体。子类必须重写这些抽象方法。
  2. 包含抽象方法的类,一定是抽象类。
  3. 抽象类只能被继承,一个类只能继承一个抽象类。

接口:

  1. 全部的方法都是抽象方法,属型都是常量
  2. 不能实例化,可以定义变量。
  3. 接口变量可以引用具体实现类的实例
  4. 接口只能被实现,一个具体类实现接口,必须实现全部的抽象方法
  5. 接口之间可以多实现
  6. 一个具体类可以实现多个接口,实现多继承现象

95.线程同步的方法

  1. wait():让线程等待。将线程存储到一个线程池中。
  2. notify():唤醒被等待的线程。通常都唤醒线程池中的第一个。让被唤醒的线程处于临时阻塞状态。
  3. notifyAll(): 唤醒所有的等待线程。将线程池中的所有线程都唤醒。

96.线程与进程的区别

进程是系统进行资源分配和调度的一个独立单位,线程是CPU调度和分派的基本单位

进程和线程的关系:

  1. 一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
  2. 资源分配给进程,同一进程的所有线程共享该进程的所有资源。
  3. 线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
  4. 线程是指进程内的一个执行单元,也是进程内的可调度实体。

线程与进程的区别:

  1. 调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
  2. 并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
  3. 拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
  4. 系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后,在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些。

97.&和&&的区别

&是位运算符。&&是布尔逻辑运算符,在进行逻辑判断时用&处理的前面为false后面的内容仍需处理,用&&处理的前面为false不再处理后面的内容。

98.重载与重写

  1. Overload为重载,Override为重写方法的重写和重载是Java多态性的不同表现。重写是父类与子类之间多态性的一种表现,重载是一个类中多态性的一种表现。
  2. 如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Override)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被"屏蔽"了。
  3. 如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overload)。
    重载的方法是可以改变返回值的类型。

99.如果对象的引用被置为null,垃圾收集器是否会立即释放对象占用的内存?

不会,在下一个垃圾回收周期中,这个对象将是可被回收的。

100.串行(serial)收集器和吞吐量(throughput)收集器的区别是什么?

吞吐量收集器使用并行版本的新生代垃圾收集器,它用于中等规模和大规模数据的应用程序。而串行收集器对大多数的小应用(在现代处理器上需要大概100M左右的内存)就足够了。

https://www.cnblogs.com/java1024/p/8608063.html

数据库面试题及答案

1. 触发器的作用?

   触发器是一种特殊的存储过程, 主要是通过时间来出发而被执行的. 它可以强化约束,

来维护数据的完整性和一致性, 可以跟踪数据库内的操作从而不允许未经许可的更新和变化. 可以级联运算

2. 什么是存储过程? 用什么来调用?

  存储过程是一个预编译的SQL语句, 有点事允许模块化的设计, 只需要创建一次,就可以被多次调用,

如果需要执行多次SQL,那么存储过程的速度更快. 可以用命令对象来调用存储过程. 可以供外部程序调用, 如java程序

3. 存储过程的有优缺点?
  优点: 存储过程是一个预编译的SQL语句, 执行效率高
  放在数据库中,直接调用,减少网络通信
  安全性高
  可重复使用
  缺点: 移植性差

4. 存储过程与函数的区别?   

  存储过程: 在数据库中完成指定的增删改查操作
  申明: procedure
  函数: 在编程语言中进行任务的处理
  申明: function

5. 索引的作用? 和他的优点缺点是什么?   

  索引就是一种特殊的查询表, 数据库的搜索可以利用它加速对数据的检索. 类似于现实生活中的目录. 不需要查找整本书就可以找到想要的结果.

6. 什么样的字段适合建立索引?   

  唯一, 不为空, 经常被查询的字段 7. 索引的类型有哪些?
  逻辑上: 单行索引,多行索引,唯一索引,非唯一索引,函数索引,域索引. 
  物理上: 分区索引, 非分区索引
  B-tree: 正常性B树
  反转型B树
  bitmap位图索引
8. 什么是事务? 什么是锁?
  事务就是被绑在一起作为一个逻辑工作单元的SQL语句分组, 如果任何一个语句操作失败那么整个操作就会失败, 会回滚到之前的状态. 要么全部执行, 要么一个都不执行. 
  锁: DBMS中, 锁是实现事务的关键. 
9. 什么叫视图? 游标是什么?
  视图就是一种虚拟的表, 具有和物理表相同的功能. 可以对视图进行增改查操作, 视图通常是一个表或多个表的行或列的子集
  游标是遍历结果集的一个指针, 用来逐条处理数据
10. 视图的优缺点?
  优点: 对数据的选择性访问
  用户可以通过简单的查询从复杂查询中得到结果
  维护数据的独立性
  对相同的数据产生不同的视图
  缺点: 性能
11. 列举几种表连接的方式,有什么区别?
  左连接: 左边为主表表数据全部显示, 匹配表的不匹配部分不显示
  右连接: 右边为主表表数据全部显示, 匹配表的不匹配部分不显示
  内连接: 只有两个元素表相匹配的才能在结果集中显示
  全外连接: 连接中的不匹配的数据全部会显示出来
  交叉连接: 笛卡尔乘积, 显示的结果是连接表数的乘积
12. 主键和外键的区别?
  主键在本表中是唯一的,不为空的, 外键可以重复和为空. 
  外键和另外一张表相关联, 不能创建对应表中不存在的外键.
13. 在数据库中查询语句速度很慢, 如何优化?
  建立索引
  减少表之间的关联
  优化SQL语句
  简化查询字段
14. 数据库三范式是什么?
  第一范式: 列不可再分
  第二范式: 行可以唯一区分, 主键约束
  第三范式: 表的非主属性不能依赖其他表的非主属性外键约束
15. union和union all有什么不同?
  union会删掉重复的记录, union all不会
16. varchar2和varchar有什么区别?
  varchar2是Oracle自己开发的, 目前varchar2和varchar是同义词, 关键点是varchar是可变长度的, 可以根据实际的长度来存储
17. oracle和mysql的区别?
  库函数不同
  Oracle是用表空间来管理的, mysql不是
  SQL语句不同
  分页查询不同
18. oracle语句有多少类型?
  DDL, DML, DCL
  DDL: 建表,建数据库,建立约束,修改约束,权限修改
  DML: insert, update, delete
  DCL: 管理用户权限
19. oracle的分页查询语句?
  select * from table where row_num between 1 and 10;
20. 从数据库中随机选择50条?
  select * from (select * from example order by dbms_random.random) where rownum <= 50;
21. order by与group by的区别?
  order by是排序查询
  group by是分组查询 having只能在group by之后, 使用group by查询的语句需要使用聚合函数
22. commit在哪里会运用?
  Oracle的commit就是DML语句提交数据. 在未提交之前你的操作都是保存在内存中, 没有更新到物理内存中.

  执行commit从用户角度来讲就是更新到物理文件了. 事实上commit还写入了日志文件
23. 行转列, 列转行怎么转?
  使用decode函数, 或者使用case when语句
24. 什么是PL/SQL?
  PL/SQL是一种程序语言,叫做过程化SQL语言, PL/SQL是对oracle数据库对SQL语句的扩展.

  在普通的SQL语句的使用上增加了编程语言的特点. 通过逻辑判断,循环等操作来实现复杂的功能或者计算.     

  PL/SQL只有Oracle数据库有, mySQL现在不支持PL/SQL
25. 序列的作用?
  Oracle使用序列来生成唯一的编号, 用来处理一个表中的自增字段. 
26. 表和视图的关系?
  视图其实就是一条查询语句, 用于显示一个或多个表或其他视图中的数据, 表就是关系型数据库中实际存储数据用的. 
27. oracle基本数据类型?
  字符串 char nchar varchar varchar2 nvarchar2
  数字 number integer
  浮点 binary_float binary_double float
  日期时间 date timestamp
  字符块 blob clob nclob bfile
28. truncate与delete的区别?
  delete table: 删除内容, 不删除定义, 不释放空间
  truncate: 删除内容和定义,释放空间
29. oracle获取系统时间?
  select to_char(sysdate,"yyyy-MM-dd") from dual
30. oracle如何去重? 
  使用distinct关键字

https://www.cnblogs.com/zjulanjian/p/10526856.html

java线程池 面试题(精简)

什么是线程池?

线程池是一种多线程处理形式,处理过程中将任务提交到线程池,任务的执行交由线程池来管理。

如果每个请求都创建一个线程去处理,那么服务器的资源很快就会被耗尽,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

为什么要使用线程池?

创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。这样频繁的创建线程和销毁线程,再加上业务工作线程,消耗系统资源的时间,可能导致系统资源不足。(我们可以把创建和销毁的线程的过程去掉)

线程池有什么作用?

线程池作用就是限制系统中执行线程的数量。

1、提高效率 创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。

2、方便管理 可以编写线程池管理代码对池中的线程同一进行管理,比如说启动时有该程序创建100个线程,每当有请求的时候,就分配一个线程去工作,如果刚好并发有101个请求,那多出的这一个请求可以排队等候,避免因无休止的创建线程导致系统崩溃。

说说几种常见的线程池及使用场景

1、newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

2、newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

3、newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

4、newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。

线程池中的几种重要的参数

corePoolSize就是线程池中的核心线程数量,这几个核心线程,只是在没有用的时候,也不会被回收

maximumPoolSize就是线程池中可以容纳的最大线程的数量

keepAliveTime,就是线程池中除了核心线程之外的其他的最长可以保留的时间,因为在线程池中,除了核心线程即使在无任务的情况下也不能被清                                除,其余的都是有存活时间的,意思就是非核心线程可以保留的最长的空闲时间,

util,就是计算这个时间的一个单位。

workQueue,就是等待队列,任务可以储存在任务队列中等待被执行,执行的是FIFIO原则(先进先出)。

threadFactory,就是创建线程的线程工厂。

handler,是一种拒绝策略,我们可以在任务满了之后,拒绝执行某些任务。

说说线程池的拒绝策略

当请求任务不断的过来,而系统此时又处理不过来的时候,我们需要采取的策略是拒绝服务。RejectedExecutionHandler接口提供了拒绝任务处理的自定义方法的机会。在ThreadPoolExecutor中已经包含四种处理策略。

AbortPolicy策略:该策略会直接抛出异常,阻止系统正常工作。

CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前的被丢弃的任务。

DiscardOleddestPolicy策略: 该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务。

DiscardPolicy策略:该策略默默的丢弃无法处理的任务,不予任何处理。

除了JDK默认提供的四种拒绝策略,我们可以根据自己的业务需求去自定义拒绝策略,自定义的方式很简单,直接实现RejectedExecutionHandler接口即可。

execute和submit的区别?

在前面的讲解中,我们执行任务是用的execute方法,除了execute方法,还有一个submit方法也可以执行我们提交的任务。

这两个方法有什么区别呢?分别适用于在什么场景下呢?我们来做一个简单的分析。

execute适用于不需要关注返回值的场景,只需要将线程丢到线程池中去执行就可以了。

submit方法适用于需要关注返回值的场景

五种线程池的使用场景

newSingleThreadExecutor:一个单线程的线程池,可以用于需要保证顺序执行的场景,并且只有一个线程在执行。

newFixedThreadPool:一个固定大小的线程池,可以用于已知并发压力的情况下,对线程数做限制。

newCachedThreadPool:一个可以无限扩大的线程池,比较适合处理执行时间比较小的任务。

newScheduledThreadPool:可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。

newWorkStealingPool:一个拥有多个任务队列的线程池,可以减少连接数,创建当前可用cpu数量的线程来并行执行。

线程池的关闭

关闭线程池可以调用shutdownNow和shutdown两个方法来实现

shutdownNow:对正在执行的任务全部发出interrupt(),停止执行,对还未开始执行的任务全部取消,并且返回还没开始的任务列表。

shutdown:当我们调用shutdown后,线程池将不再接受新的任务,但也不会去强制终止已经提交或者正在执行中的任务。

初始化线程池时线程数的选择

如果任务是IO密集型,一般线程数需要设置2倍CPU数以上,以此来尽量利用CPU资源。

如果任务是CPU密集型,一般线程数量只需要设置CPU数加1即可,更多的线程数也只能增加上下文切换,不能增加CPU利用率。

上述只是一个基本思想,如果真的需要精确的控制,还是需要上线以后观察线程池中线程数量跟队列的情况来定。

线程池都有哪几种工作队列

1、ArrayBlockingQueue

是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。

2、LinkedBlockingQueue

一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列

3、SynchronousQueue

一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

4、PriorityBlockingQueue

一个具有优先级的无限阻塞队列。
————————————————
版权声明:本文为CSDN博主「Linias」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_29373285/article/details/85238728

解决线程安全问题的三种方法

一、使用同步代码块
如:卖票案例 出现了线程安全 重复的票不能出现

步骤
成员位置建立锁对象;
synchronized(锁对象){
出现安全问题代码
}

1 锁对象 任意对象
2 必须保证多个线程使用的是同一个锁对象
3 把{} 只让一个线程进

例子:

public class RunnableImpl implements  Runnable{
    // 定义共享资源   线程不安全
    private int ticket = 100;
    //在成员位置创建一个锁对象
    Object obj = new Object();
    // 线程任务  卖票
    @Override
    public void run() {
        while(true){
            //建立锁对象
            synchronized (obj){
                if(ticket>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //卖票操作
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                    ticket--;
                }
            }
        }
    }
}

二、使用同步方法解决多线程安全
步骤

1 创建一个方法 修饰符添加synchronized
2 把访问了 共享数据的代码放入到方法中
3 调用同步方法

例子

public class RunnableImpl implements  Runnable{
    // 定义共享资源   线程不安全
    private int ticket = 100;
    // 线程任务  卖票
    @Override
    public void run() {
        while(true){
            payTicket();//调用下面synchronized修饰的方法
        }
    }
    public synchronized void payTicket(){
        if(ticket>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //卖票操作
            System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
            ticket--;
        }
    }
}
————————————————
版权声明:本文为CSDN博主「陈福国」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45112637/article/details/90668721

HashMap和Hashtable的区别

HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
区别1: 
HashMap可以存放 null
Hashtable不能存放null
区别2:
HashMap不是线程安全的类
Hashtable是线程安全的类

StringBuffer和StringBuilder的区别
StringBuffer 是线程安全的
StringBuilder 是非线程安全的
所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性

非线程安全的为什么会比线程安全的 快? 因为不需要同步嘛,省略了些时间

线程在一定条件下,状态会发生变化。线程一共有以下几种状态:

1、新建状态(New):新创建了一个线程对象。

2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

阻塞的情况分三种:

(1)、等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

(2)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

(3)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

线程变化的状态转换图如下:

注:拿到对象的锁标记,即为获得了对该对象(临界区)的使用权限。即该线程获得了运行所需的资源,进入“就绪状态”,只需获得CPU,就可以运行。因为当调用wait()后,线程会释放掉它所占有的“锁标志”,所以线程只有在此获取资源才能进入就绪状态。
下面小小的作下解释: 
1、线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,  当我们new了这个对象后,线程就进入了初始状态; 
2、当该对象调用了start()方法,就进入就绪状态; 
3、进入就绪后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态; 
4、进入运行状态后情况就比较复杂了 
    4.1、run()方法或main()方法结束后,线程就进入终止状态; 
    4.2、当线程调用了自身的sleep()方法或其他线程的join()方法,进程让出CPU,然后就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源即调用sleep ()函数后,线程不会释放它的“锁标志”。)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配CPU时间片。典型地,sleep()被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。
    4.3、线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到就绪状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态; 调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间片从而需要转到另一个线程。yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
   4.4、当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入就绪状态,等待OS分配CPU时间片;

4.5. suspend() 和 resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。典型地,suspend()和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume()使其恢复。 
   4.6、wait()和 notify() 方法:当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

wait() 使得线程进入阻塞状态,它有两种形式:

一种允许指定以毫秒为单位的一段时间作为参数;另一种没有参数。前者当对应的 notify()被调用或者超出指定时间时线程重新进入可执行状态即就绪状态,后者则必须对应的 notify()被调用。当调用wait()后,线程会释放掉它所占有的“锁标志”从而使线程所在对象中的其它synchronized数据可被别的线程使用。waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronizedblock中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

注意区别:初看起来wait() 和 notify() 方法与suspend()和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的suspend()及其它所有方法在线程阻塞时都不会释放占用的锁(如果占用了的话),而wait() 和 notify() 这一对方法则相反。

上述的核心区别导致了一系列的细节上的区别

首先,前面叙述的所有方法都隶属于 Thread类,但是wait() 和 notify() 方法这一对却直接隶属于 Object 类也就是说,所有对象都拥有这一对方法。初看起来这十分不可思议,但是实际上却是很自然的,因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

其次,前面叙述的所有方法都可在任何位置调用,但是wait() 和 notify() 方法这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调用必须放置在这样的 synchronized方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException异常。

wait() 和 notify()方法的上述特性决定了它们经常和synchronized方法或块一起使用,将它们和操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则相当于 block和wake up 原语(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。

关于 wait() 和 notify() 方法最后再说明两点:

第一:调用notify() 方法导致解除阻塞的线程是从因调用该对象的 wait()方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。

第二:除了notify(),还有一个方法 notifyAll()也可起到类似作用,唯一的区别在于,调用 notifyAll()方法将把因调用该对象的 wait()方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。

谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend()方法和不指定超时期限的wait()方法的调用都可能产生死锁。遗憾的是,Java并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁。

SpringCloud相关面试题(汇总)

微服务的相关面试题。非原创,网上收集而来。

一、微服务概述

1、微服务的优点缺点?说下开发项目中遇到的坑?

优点:

(1)每个服务直接足够内聚,代码容易理解

(2)开发效率高,一个服务只做一件事,适合小团队开发

(3)松耦合,有功能意义的服务。

(4)可以用不同语言开发,面向接口编程。

(5)易于第三方集成

(6)微服务只是业务逻辑的代码,不会和HTML,CSS或其他界面结合.

(7)可以灵活搭配,连接公共库/连接独立库

缺点:

(1)分布式系统的责任性

(2)多服务运维难度加大。

(3)系统部署依赖,服务间通信成本,数据一致性,系统集成测试,性能监控。

2、什么是springcloud?

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

Spring cloud流应用程序启动器是基于Spring Boot的Spring集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序

3、spring cloud 和dubbo区别?

(1)服务调用方式 dubbo是RPC springcloud Rest Api

(2)注册中心,dubbo 是zookeeper springcloud是eureka,也可以是zookeeper

(3)服务网关,dubbo本身没有实现,只能通过其他第三方技术整合,springcloud有Zuul路由网关,作为路由服务器,进行消费者的请求分发,springcloud支持断路器,与git完美集成配置文件支持版本控制,事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。

4、REST 和RPC对比

(1)RPC主要的缺陷是服务提供方和调用方式之间的依赖太强,需要对每一个微服务进行接口的定义,并通过持续继承发布,严格版本控制才不会出现冲突。

(2)REST是轻量级的接口,服务的提供和调用不存在代码之间的耦合,只需要一个约定进行规范。

5、你所知道的微服务技术栈?

(1)服务开发:springboot spring springmvc

(2)服务配置与管理:Netfix公司的Archaiusm ,阿里的Diamond

(3)服务注册与发现:Eureka,Zookeeper

(4)服务调用:Rest RPC gRpc

(5)服务熔断器:Hystrix

(6)服务负载均衡:Ribbon Nginx

(7)服务接口调用:Fegin

(8)消息队列:Kafka Rabbitmq activemq

(9)服务配置中心管理:SpringCloudConfig

(10)服务路由(API网关)Zuul

(11)事件消息总线:SpringCloud Bus

6、负载均衡的意义是什么?

在计算中,负载均衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载均衡旨在优化资源使用,最大吞吐量,最小响应时间并避免任何单一资源的过载。使用多个组件进行负载均衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务进程。

7、微服务之间是如何独立通讯的?

(1)远程调用,比如feign调用,直接通过远程过程调用来访问别的service。
(2)消息中间件

8、为什么要使用微服务?

(1)随着互联网的快速发展,各行各业都在用互联网。互联网已经离不开人们的形形色色。随着越来越多的用户,业务场景也愈来愈复杂。

(2)传统的单体架构已经很难满足互联网技术发展的要求,代码可维护性扩展性和可读性降低,维护成本的提高都是驱动微服务的发展趋势。

二、SpringCloud概述

1、springcloud如何实现服务的注册?

(1)服务发布时,指定对应的服务名,将服务注册到 注册中心(eureka zookeeper)
(2)注册中心加@EnableEurekaServer,服务用@EnableDiscoveryClient,然后用ribbon或feign进行服务直接的调用发现。

2、Eureka和Zookeeper区别

(1)Eureka取CAP的AP,注重可用性,Zookeeper取CAP的CP注重
一致性。

(2)Zookeeper在选举期间注册服务瘫痪,虽然服务最终会恢复,但选举期间不可用。

(3)eureka的自我保护机制,会导致一个结果就是不会再从注册列表移除因长时间没收到心跳而过期的服务。依然能接受新服务的注册和查询请求,但不会被同步到其他节点。不会服务瘫痪。

(4)Zookeeper有Leader和Follower角色,Eureka各个节点平等。

(5)Zookeeper采用过半数存活原则,Eureka采用自我保护机制解决分区问题。

(6)eureka本质是一个工程,Zookeeper只是一个进程。

3、eureka自我保护机制是什么?

当Eureka Server 节点在短时间内丢失了过多实例的连接时(比如网络故障或频繁启动关闭客户端)节点会进入自我保护模式,保护注册信息,不再删除注册数据,故障恢复时,自动退出自我保护模式。

4、什么是服务熔断?什么是服务降级?

服务直接的调用,比如在高并发情况下出现进程阻塞,导致当前线程不可用,慢慢的全部线程阻塞,导致服务器雪崩。

服务熔断:相当于保险丝,出现某个异常,直接熔断整个服务,而不是一直等到服务超时。

服务降级:通过维护一个自己的线程池,当线程到达阈值的时候就启动服务降级,如果其他请求继续访问就直接返回fallback的默认值。

5、什么是Ribbon?

ribbon是一个负载均衡客户端,可以很好的控制http和tcp的一些行为。feign默认集成了ribbon。

6、什么是feigin?它的优点是什么?

(1)feign采用的是基于接口的注解

(2)feign整合了ribbon,具有负载均衡的能力

(3)整合了Hystrix,具有熔断的能力

使用:

(1)添加pom依赖。

(2)启动类添加@EnableFeignClients

(3)定义一个接口@FeignClient(name=“xxx”)指定调用哪个服务

7、Ribbon和Feign的区别?

(1)Ribbon都是调用其他服务的,但方式不同。

(2)启动类注解不同,Ribbon是@RibbonClient ,feign的是@EnableFeignClients

(3)服务指定的位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。

(4)调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。Feign需要将调用的方法定义成抽象方法即可。

8、springcloud断路器作用?

当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)

断路器有完全打开状态:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象 断路器完全打开 那么下次请求就不会请求到该服务

半开:短时间内 有恢复迹象 断路器会将部分请求发给该服务,正常调用时 断路器关闭

关闭:当服务一直处于正常状态 能正常调用

9、什么是Spring Cloud Bus?

spring cloud bus 将分布式的节点用轻量的消息代理连接起来,它可以用于广播配置文件的更改或者服务直接的通讯,也可用于监控。如果修改了配置文件,发送一次请求,所有的客户端便会重新读取配置文件。

使用:

(1)添加依赖

(2)配置rabbimq

10、什么是SpringCloudConfig?

在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

使用:

(1)添加pom依赖

(2)配置文件添加相关配置

(3)启动类添加注解@EnableConfigServer

11、Spring Cloud Gateway?

Spring Cloud Gateway是Spring Cloud官方推出的第二代网关框架,取代Zuul网关。网关作为流量的,在微服务系统中有着非常作用,网关常见的功能有路由转发、权限校验、限流控制等作用。

使用了一个RouteLocatorBuilder的bean去创建路由,除了创建路由RouteLocatorBuilder可以让你添加各种predicates和filters,predicates断言的意思,顾名思义就是根据具体的请求的规则,由具体的route去处理,filters是各种过滤器,用来对请求做各种判断和修改。

12、什么是Hystrix?

防雪崩利器,具备服务降级,服务熔断,依赖隔离,监控(Hystrix Dashboard)服务降级:

双十一 提示 哎哟喂,被挤爆了。app秒杀 网络开小差了,请稍后再试。

优先核心服务,非核心服务不可用或弱可用。HystrixCommand注解指定。fallbackMethod(回退函数)中具体实现降级逻辑。

Spring Boot 面试题

1、什么是 Spring Boot?

Spring Boot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。

更多 Spring Boot 详细介绍请看这篇文章《什么是Spring Boot?》。

2、为什么要用 Spring Boot?

Spring Boot 优点非常多,如:

  • 独立运行
  • 简化配置
  • 自动配置
  • 无代码生成和XML配置
  • 应用监控
  • 上手容易
  • ...

Spring Boot 集这么多优点于一身,还有理由不使用它呢?

3、Spring Boot 的核心配置文件有哪几个?它们的区别是什么?

Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。

application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。

bootstrap 配置文件有以下几个应用场景。

  • 使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
  • 一些固定的不能被覆盖的属性;
  • 一些加密/解密的场景;

具体请看这篇文章《Spring Boot 核心配置文件详解》。

4、Spring Boot 的配置文件有哪几种格式?它们有什么区别?

.properties 和 .yml,它们的区别主要是书写格式不同。

1).properties

app.user.name = javastack

2).yml

app:user:name: javastack

另外,.yml 格式不支持 @PropertySource 注解导入配置。

5、Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。

@ComponentScan:Spring组件扫描。

6、开启 Spring Boot 特性有哪几种方式?

1)继承spring-boot-starter-parent项目

2)导入spring-boot-dependencies项目依赖

具体请参考这篇文章《Spring Boot开启的2种方式》。

7、Spring Boot 需要独立的容器运行吗?

可以不需要,内置了 Tomcat/ Jetty 等容器。

8、运行 Spring Boot 有哪几种方式?

1)打包用命令或者放到容器中运行

2)用 Maven/ Gradle 插件运行

3)直接执行 main 方法运行

9、Spring Boot 自动配置原理是什么?

注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。

具体看这篇文章《Spring Boot自动配置原理、实战》。

10、Spring Boot 的目录结构是怎样的?

cn+- javastack+- MyApplication.java|+- customer|   +- Customer.java|   +- CustomerController.java|   +- CustomerService.java|   +- CustomerRepository.java|+- order+- Order.java+- OrderController.java+- OrderService.java+- OrderRepository.java

这个目录结构是主流及推荐的做法,而在主入口类上加上 @SpringBootApplication 注解来开启 Spring Boot 的各项能力,如自动配置、组件扫描等。具体看这篇文章《Spring Boot 主类及目录结构介绍》。

11、你如何理解 Spring Boot 中的 Starters?

Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成 Spring 及其他技术,而不需要到处找示例代码和依赖包。如你想使用 Spring JPA 访问数据库,只要加入 spring-boot-starter-data-jpa 启动器依赖就能使用了。

Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。具体请看这篇文章《Spring Boot Starters启动器》。

12、如何在 Spring Boot 启动的时候运行一些特定的代码?

可以实现接口 ApplicationRunner 或者 CommandLineRunner,这两个接口实现方式一样,它们都只提供了一个 run 方法,具体请看这篇文章《Spring Boot Runner启动器》。

13、Spring Boot 有哪几种读取配置的方式?

Spring Boot 可以通过 @PropertySource,@Value,@Environment, @ConfigurationProperties 来绑定变量,具体请看这篇文章《Spring Boot读取配置的几种方式》。

14、Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?

Spring Boot 支持 Java Util Logging, Log4j2, Lockback 作为日志框架,如果你使用 Starters 启动器,Spring Boot 将使用 Logback 作为默认日志框架,具体请看这篇文章《Spring Boot日志集成》。

15、SpringBoot 实现热部署有哪几种方式?

主要有两种方式:

  • Spring Loaded
  • Spring-boot-devtools

Spring-boot-devtools 使用方式可以参考这篇文章《Spring Boot实现热部署》。

16、你如何理解 Spring Boot 配置加载顺序?

在 Spring Boot 里面,可以使用以下几种方式来加载配置。

1)properties文件;

2)YAML文件;

3)系统环境变量;

4)命令行参数;

等等……

具体请看这篇文章《Spring Boot 配置加载顺序详解》。

17、Spring Boot 如何定义多套不同环境配置?

提供多套配置文件,如:

applcation.propertiesapplication-dev.propertiesapplication-test.propertiesapplication-prod.properties

运行时指定具体的配置文件,具体请看这篇文章《Spring Boot Profile 不同环境配置》。

18、Spring Boot 可以兼容老 Spring 项目吗,如何做?

可以兼容,使用 @ImportResource 注解导入老 Spring 项目配置文件。

19、保护 Spring Boot 应用有哪些方法?

  • 在生产中使用HTTPS
  • 使用Snyk检查你的依赖关系
  • 升级到最新版本
  • 启用CSRF保护
  • 使用内容安全策略防止XSS攻击
  • ...

更多请看这篇文章《10 种保护 Spring Boot 应用的绝佳方法》。

20、Spring Boot 2.X 有什么新特性?与 1.X 有什么区别?

  • 配置变更
  • JDK 版本升级
  • 第三方类库升级
  • 响应式 Spring 编程支持
  • HTTP/2 支持
  • 配置属性绑定
  • 更多改进与加强...

具体请看这篇文章《Spring Boot 2.x 新特性总结及迁移指南》。


终于写完了,希望大家好好学习下再去面试,不然再被面试官问这些问题,又答不上来就尴尬了。弄懂了这些问题,对你理解 Spring Boot 也有非常大的帮助。

这 20 道面试题就算第一季吧,后面会整理更多季 Spring Boot/Cloud 相关的面试题。更多的 Spring Boot 系列技术文章,请关注微信公众号:Java技术栈(id: javastack),在后台回复关键字 "boot" 获取。

Mybatis常考面试题汇总

1、#{}和${}的区别是什么?
#{}和${}的区别是什么?

在Mybatis中,有两种占位符

#{}解析传递进来的参数数据
${}对传递进来的参数原样拼接在SQL中
#{}是预编译处理,${}是字符串替换。
使用#{}可以有效的防止SQL注入,提高系统安全性。
2、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
当实体类中的属性名和表中的字段名不一样 ,怎么办 ?

第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致

<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”> 
       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; 
    </select> 
第2种: 通过来映射字段名和实体类属性名的一一对应的关系

<select id="getOrder" parameterType="int" resultMap="orderresultmap">
        select * from orders where order_id=#{id}
    </select>
   <resultMap type=”me.gacl.domain.order” id=”orderresultmap”> 
        <!–用id属性来映射主键字段–> 
        <id property=”id” column=”order_id”> 
        <!–用result属性来映射非主键字段,property为实体类属性名,column为数据表中的属性–> 
        <result property = “orderno” column =”order_no”/> 
        <result property=”price” column=”order_price” /> 
    </reslutMap>
我认为第二种方式会好一点。

3、如何获取自动生成的(主)键值?
如何获取自动生成的(主)键值?

如果我们一般插入数据的话,如果我们想要知道刚刚插入的数据的主键是多少,我们可以通过以下的方式来获取

需求:

user对象插入到数据库后,新记录的主键要通过user对象返回,通过user获取主键值。
解决思路:

通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。
mysql:

<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select LAST_INSERT_ID()
        </selectKey>
        INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
    </insert>
oracle:

实现思路:

先查询序列得到主键,将主键设置到user对象中,将user对象插入数据库。
    <!-- oracle
    在执行insert之前执行select 序列.nextval() from dual取出序列最大值,将值设置到user对象 的id属性
     -->
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <selectKey keyProperty="id" order="BEFORE" resultType="int">
            select 序列.nextval() from dual
        </selectKey>
        
        INSERT INTO USER(id,username,birthday,sex,address) VALUES( 序列.nextval(),#{username},#{birthday},#{sex},#{address})
    </insert> 
4、在mapper中如何传递多个参数?
在mapper中如何传递多个参数?

第一种:使用占位符的思想

在映射文件中使用#{0},#{1}代表传递进来的第几个参数
**使用@param注解:来命名参数 **
#{0},#{1}方式
//对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
 
<select id="selectUser"resultMap="BaseResultMap">  
    select *  fromuser_user_t   whereuser_name = #{0} anduser_area=#{1}  
</select>  
@param注解方式
        public interface usermapper { 
         user selectuser(@param(“username”) string username, 
         @param(“hashedpassword”) string hashedpassword); 
        }
 <select id=”selectuser” resulttype=”user”> 
         select id, username, hashedpassword 
         from some_table 
         where username = #{username} 
         and hashedpassword = #{hashedpassword} 
    </select>
第二种:使用Map集合作为参数来装载

try{
            //映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
 
 
            /**
             * 由于我们的参数超过了两个,而方法中只有一个Object参数收集
             * 因此我们使用Map集合来装载我们的参数
             */
            Map<String, Object> map = new HashMap();
            map.put("start", start);
            map.put("end", end);
            return sqlSession.selectList("StudentID.pagination", map);
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    <!--分页查询-->
    <select id="pagination" parameterType="map" resultMap="studentMap">
 
        /*根据key自动找到对应Map集合的value*/
        select * from students limit #{start},#{end};
 
    </select>
5、Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能。
Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
6、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?
Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?

如果配置了namespace那么当然是可以重复的,因为我们的Statement实际上就是namespace+id

如果没有配置namespace的话,那么相同的id就会导致覆盖了。

7、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
8、通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。
Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement
举例:

com.mybatis3.mappers.StudentDao.findStudentById,
 
可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

详情可参考:

www.cnblogs.com/soundcode/p…
9、Mybatis比IBatis比较大的几个改进是什么
Mybatis比IBatis比较大的几个改进是什么

a.有接口绑定,包括注解绑定sql和xml绑定Sql ,
b.动态sql由原来的节点配置变成OGNL表达式,
c. 在一对一,一对多的时候引进了association,在一对多的时候引入了collection节点,不过都是在resultMap里面配置
10、接口绑定有几种实现方式,分别是怎么实现的?
接口绑定有几种实现方式,分别是怎么实现的?

接口绑定有两种实现方式:

一种是通过注解绑定,就是在接口的方法上面加上@Select@Update等注解里面包含Sql语句来绑定
另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名.
11、Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

举例:select * from student,拦截sql后重写为:select t.* from (select * from student)t limit 0,10

分页插件使用参考资料:

www.cnblogs.com/kangoroo/p/…
blog.csdn.net/yuchao2015/…
www.cnblogs.com/ljdblog/p/6…
12、简述Mybatis的插件运行原理,以及如何编写一个插件
简述Mybatis的插件运行原理,以及如何编写一个插件

Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

13、Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。

它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。

14、Mybatis都有哪些Executor执行器?它们之间的区别是什么?
Mybatis都有哪些Executor执行器?它们之间的区别是什么?

Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

15、MyBatis与Hibernate有哪些不同?
MyBatis与Hibernate有哪些不同?

Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的缺点是学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。 总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
————————————————
版权声明:本文为CSDN博主「Java程序员-张凯」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41701956/article/details/88545768

SpringMVC常见面试题总结(超详细回答)

JAVA高级架构 2019-05-24

1、什么是Spring MVC ?简单介绍下你对springMVC的理解?

Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

2、SpringMVC的流程?

(1)用户发送请求至前端控制器DispatcherServlet;

(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;

(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;

(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;

(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);

(6)Handler执行完成返回ModelAndView;

(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;

(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;

(9)ViewResolver解析后返回具体View;

(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)

(11)DispatcherServlet响应用户。

3、Springmvc的优点:

(1)可以支持各种视图技术,而不仅仅局限于JSP;

(2)与Spring框架集成(如IoC容器、AOP等);

(3)清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。

(4) 支持各种请求资源的映射策略。

4、Spring MVC的主要组件?

(1)前端控制器 DispatcherServlet(不需要程序员开发)

作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。

(2)处理器映射器HandlerMapping(不需要程序员开发)

作用:根据请求的URL来查找Handler

(3)处理器适配器HandlerAdapter

注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。

(4)处理器Handler(需要程序员开发)

(5)视图解析器 ViewResolver(不需要程序员开发)

作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)

(6)视图View(需要程序员开发jsp)

View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

5、springMVC和struts2的区别有哪些?

(1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。

(2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

(3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

6、SpringMVC怎么样设定重定向和转发的?

(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"

(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

7、SpringMvc怎么和AJAX相互调用的?

通过Jackson框架就可以把Java里面的对象直接转化成Js可以识别的Json对象。具体步骤如下 :

(1)加入Jackson.jar

(2)在配置文件中配置json的映射

(3)在接受Ajax方法里面可以直接返回Object,List等,但方法前面要加上@ResponseBody注解。

8、如何解决POST请求中文乱码问题,GET的又如何处理呢?

(1)解决post请求乱码问题:

在web.xml中配置一个CharacterEncodingFilter过滤器,设置成utf-8;

<filter>

<filter-name>CharacterEncodingFilter</filter-name>

<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>utf-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CharacterEncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

(2)get请求中文参数出现乱码解决方法有两个:

①修改tomcat配置文件添加编码与工程编码一致,如下:

<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

②另外一种方法对参数进行重新编码:

String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码。

9、Spring MVC的异常处理 ?

答:可以将异常抛给Spring框架,由Spring框架来处理;我们只需要配置简单的异常处理器,在异常处理器中添视图页面即可。

10、SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决?

答:是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。

11、 SpringMVC常用的注解有哪些?

@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。

@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。

12、SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代?

答:一般用@Conntroller注解,表示是表现层,不能用别的注解代替。

13、如果在拦截请求中,我想拦截get方式提交的方法,怎么配置?

答:可以在@RequestMapping注解里面加上method=RequestMethod.GET。

14、怎样在方法里面得到Request,或者Session?

答:直接在方法的形参中声明request,SpringMvc就自动把request对象传入。

15、如果想在拦截的方法里面得到从前台传入的参数,怎么得到?

答:直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样。

16、如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象?

答:直接在方法中声明这个对象,SpringMvc就自动会把属性赋值到这个对象里面。

17、SpringMvc中函数的返回值是什么?

答:返回值可以有很多类型,有String, ModelAndView。ModelAndView类把视图和数据都合并的一起的,但一般用String比较好。

18、SpringMvc用什么对象从后台向前台传递数据的?

答:通过ModelMap对象,可以在这个对象里面调用put方法,把对象加到里面,前台就可以通过el表达式拿到。

19、怎么样把ModelMap里面的数据放入Session里面?

答:可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入session里面的key。

20、SpringMvc里面拦截器是怎么写的:

有两种写法,一种是实现HandlerInterceptor接口,另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在SpringMvc的配置文件中配置拦截器即可:

<!-- 配置SpringMvc的拦截器 -->

<mvc:interceptors>

<!-- 配置一个拦截器的Bean就可以了 默认是对所有请求都拦截 -->

<bean id="myInterceptor" class="com.zwp.action.MyHandlerInterceptor"></bean>

<!-- 只针对部分请求拦截 -->

<mvc:interceptor>

<mvc:mapping path="/modelMap.do" />

<bean class="com.zwp.action.MyHandlerInterceptorAdapter" />

</mvc:interceptor>

</mvc:interceptors>

21、注解原理:

注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象。通过代理对象调用自定义注解的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。

原文地址:https://blog.csdn.net/a745233700/article/details/80963758

Spring常见面试题总结

1、Spring是什么?

Spring是一个轻量级的IoC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于XML的配置、基于注解的配置、基于Java的配置。

主要由以下几个模块组成:

Spring Core:核心类库,提供IOC服务;

Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);

Spring AOP:AOP服务;

Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;

Spring ORM:对现有的ORM框架的支持;

Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;

Spring MVC:提供面向Web应用的Model-View-Controller实现。

2、Spring 的优点?

(1)spring属于低侵入式设计,代码的污染极低;

(2)spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;

(3)Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。

(4)spring对于主流的应用框架提供了集成支持。

3、Spring的AOP理解:

OOP面向对象,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。

AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。

AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。

(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。

(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:

①JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

②如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

(3)静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。

InvocationHandler 的 invoke(Object proxy,Method method,Object[] args):proxy是最终生成的代理实例; method 是被代理目标实例的某个具体方法; args 是被代理目标实例某个方法的具体入参, 在方法反射调用时使用。

4、Spring的IoC理解:

(1)IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权力转移到Spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。DI依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。

(2)最直观的表达就是,IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。

(3)Spring的IOC有三种注入方式 :构造器注入、setter方法注入、根据注解注入。

IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

5、BeanFactory和ApplicationContext有什么区别?

BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。

(1)BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:

①继承MessageSource,因此支持国际化。

②统一的资源文件访问方式。

③提供在监听器中注册bean的事件。

④同时加载多个配置文件。

⑤载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

(2)①BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

②ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

③相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

(3)BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

(4)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

6、请解释Spring Bean的生命周期?

首先说一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;

Spring上下文中的Bean生命周期也类似,如下:

(1)实例化Bean:

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。

(2)设置对象属性(依赖注入):

实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成依赖注入。

(3)处理Aware接口:

接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:

①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值;

②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。

③如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;

(4)BeanPostProcessor:

如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;

(5)InitializingBean 与 init-method:

如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

(6)如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;

以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。

(7)DisposableBean:

当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;

(8)destroy-method:

最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

7、 解释Spring支持的几种bean的作用域。

Spring容器中的bean可以分为5个范围:

(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。

(2)prototype:为每一个bean请求提供一个实例。

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

8、Spring框架中的单例Beans是线程安全的么?

Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。

9、Spring如何处理线程并发问题?

在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。

ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

10-1、Spring基于xml注入bean的几种方式:

(1)Set方法注入;

(2)构造器注入:①通过index设置参数的位置;②通过type设置参数类型;

(3)静态工厂注入;

(4)实例工厂;

详细内容可以阅读:https://blog.csdn.net/a745233700/article/details/89307518

10-2、Spring的自动装配:

在spring中,对象无需自己查找或创建与其关联的其他对象,由容器负责把需要相互协作的对象引用赋予各个对象,使用autowire来配置自动装载模式。

在Spring框架xml配置中共有5种自动装配:

(1)no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。

(2)byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。

(3)byType:通过参数的数据类型进行自动装配。

(4)constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。

(5)autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

基于注解的方式:

使用@Autowired注解来自动装配指定的bean。在使用@Autowired注解之前需要在Spring配置文件进行配置,。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。在使用@Autowired时,首先在容器中查询对应类型的bean:

如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据;

如果查询的结果不止一个,那么@Autowired会根据名称来查找;

如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false。

@Autowired可用于:构造函数、成员变量、Setter方法

注:@Autowired和@Resource之间的区别

(1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

(2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入。

11、Spring 框架中都用到了哪些设计模式?

(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

(2)单例模式:Bean默认为单例模式。

(3)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

(4)模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

(5)观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现--ApplicationListener。

12、Spring事务的实现方式和实现原理:

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

(1)Spring事务的种类:

spring支持编程式事务管理和声明式事务管理两种方式:

①编程式事务管理使用TransactionTemplate。

②声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。

声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

(2)spring的事务传播行为:

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。

① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

(3)Spring中的隔离级别:

① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。

② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外一个事务可以看到这个事务未提交的数据。

③ ISOLATION_READ_COMMITTED:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。

④ ISOLATION_REPEATABLE_READ:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。

⑤ ISOLATION_SERIALIZABLE:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。

13、Spring框架中有哪些不同类型的事件?

Spring 提供了以下5种标准的事件:

(1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

(2)上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

(3)上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

(4)上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

(5)请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。

14、解释一下Spring AOP里面的几个名词:

(1)切面(Aspect):被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。

(2)连接点(Join point):指方法,在Spring AOP中,一个连接点 总是 代表一个方法的执行。

(3)通知(Advice):在切面的某个特定的连接点(Join point)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。

(4)切入点(Pointcut):切入点是指 我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。

(5)引入(Introduction):(也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。

(6)目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。

(7)织入(Weaving):指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。

切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切入点使得定位通知(advice)可独立于OO层次。 例如,一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上(例如服务层的所有业务操作)。

15、Spring通知有哪些类型?

https://blog.csdn.net/qq_32331073/article/details/80596084

(1)前置通知(Before advice):在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

(2)返回后通知(After returning advice):在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

(3)抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。

(4)后通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

(5)环绕通知(Around Advice):包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。 环绕通知是最常用的一种通知类型。大部分基于拦截的AOP框架,例如Nanning和JBoss4,都只提供环绕通知。

同一个aspect,不同advice的执行顺序:

①没有异常情况下的执行顺序:

around before advice

before advice

target method 执行

around after advice

after advice

afterReturning

②有异常情况下的执行顺序:

around before advice

before advice

target method 执行

around after advice

after advice

afterThrowing:异常发生

java.lang.RuntimeException: 异常发生

Java面试题汇总大杂汇相关推荐

  1. ​大公司的Java笔试题汇总(含答案)​

    大公司的Java笔试题汇总(含答案) 1.下列哪一种叙述是正确的(D ) A. abstract修饰符可修饰字段.方法和类 B. 抽象方法的body部分必须用一对大括号{ }包住 C. 声明抽象方法, ...

  2. Java面试题汇总及答案2021最新(序列化含答案)

    Java面试题汇总及答案2021最新(序列化含答案) 为大家整理了2021最新的Java面试题及答案下载,这套Java面试题总汇已经汇总了Java基础面试到高级Java面试题,几乎涵盖了作为一个Jav ...

  3. 年终盘点 | 2019年Java面试题汇总篇(附答案)

    作者 | 老王 来源 | Java中文社群「微信公众号」 在这岁月更替辞旧迎新的时刻,老王盘点了一下自己 2019 年发布的所有文章,意外的发现关于「Java面试」的主题文章,竟然发布了 52 篇,几 ...

  4. 【吐血整理】年度盘点 | 2019年Java面试题汇总篇——附答案

    在这岁月更替辞旧迎新的时刻,老王盘点了一下自己 2019 年发布的所有文章,意外的发现关于「Java面试」的主题文章,竟然发布了 52 篇,几乎是全年每周一篇面试文章的节奏,当然其中有不少的面试题来源 ...

  5. 超详细的Java面试题汇总(基础篇+框架篇)

    Java面试题汇总-基础篇 1.面向对象是什么? 答:面向对象是一种思想,世间万物都可以看做一个对象,这里只讨论面向对象编程(OOP),Java是一个支持并发.基于类和面向对象的计算机编程语言,面向对 ...

  6. Java面试题汇总及答案2021最新(ioNio)

    Java面试题汇总及答案2021最新(io&Nio) 最近给大家整理了一批Java关于io和nio的面试题一共15题,是20201最新时间整理的,并且都含答案打包下载. 适宜阅读人群 需要面试 ...

  7. 【分享】20个高级Java面试题汇总(含答案)

    原标题:[分享]20个高级Java面试题汇总(含答案) 什么是可变参数? 可变参数允许调用参数数量不同的方法.请看下面例子中的求和方法.此方法可以调用1个int参数,或2个int参数,或多个int参数 ...

  8. JAVA面试题汇总 一

    1. Java中的异常处理机制的简单原理和应用. 当Java程序违反了Java的语义规则时,Java虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2种情况.一种是Java类库内置的语义检查.例 ...

  9. Java面试题(一)100家大公司java笔试题汇总

    Java考试题 一:单选题 -– 1.下列哪一种叙述是正确的(D ) A. abstract修饰符可修饰字段.方法和类 B. 抽象方法的body部分必须用一对大括号{ }包住 C. 声明抽象方法,大括 ...

最新文章

  1. Django 用户登陆访问限制 @login_required
  2. 检查邮箱是否包含教育后缀.edu结尾的邮箱
  3. Ubuntuzilla: 安装最新版Mozilla软件的简单方法
  4. 【体验】感谢热心网友送的3D打印结构外壳,nodemcu外壳,3D打印wifi外壳
  5. 用 Go 开发 Go 编译器
  6. 程序媛计划——python正则表达式
  7. js showModalDialog参数的使用详解(转)
  8. 【渝粤教育】国家开放大学2018年秋季 2202T公共行政学 参考试题
  9. windows安装nvm
  10. 【OS学习笔记】三十九 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----动态加载的用户程序/任务一代码
  11. MVC中根据后台绝对路径读取图片并显示在IMG中
  12. 面试这些公司是在浪费时间
  13. 不是明年年初?苹果明年三季度才会推出AirPods Pro 2
  14. AgreementMaker:Efficient Matching for Large Real-World 翻译
  15. Houdini特效资源如何导入?Houdini工程文件导入教程
  16. 浏览器request得不到cookie_Servlet第五篇「介绍会话技术、Cookie的API、详解、应用」...
  17. mysql备份的 三种方式
  18. 帅地鸽了大半年,一个专注于面试、基础知识、算法的小破站上线了
  19. CS61A 2021Spring Lab: Cats
  20. Mac中Word 2016导出PDF附带书签目录结构

热门文章

  1. AB计算机总线,什么是总线?简要说明AB、DB、CB的含义及其性能?
  2. Alignedreid项目源码分析
  3. CF大陆斗C战士(一)
  4. Hex文件头部修改软件
  5. 数仓、数据湖、湖仓一体、数据网格的探索与研究
  6. powershell中文乱码解决办法
  7. 百度文库 -3ds max
  8. 处理器CPU概念及CPU多线程
  9. 在我的世界里玩我的世界是一种怎样的体验?
  10. HyperLynx(十一)BoardSim和PCB板级仿真分析(二)