来源于:https://mp.weixin.qq.com/s/UXjDP1xmkhBTaTObe8aH2Qhtml
1.java事件机制包括哪三个部分?分别介绍。
事件、事件监听器、事件源java
二、为何要使用线程池?
首先,服务器建立和销毁工做线程的开销很大,若是服务器与不少客户端通讯,而且与每一个客户端通讯的时间很短,那么就会在建立和销毁线程的时候形成很大的开销。(小而多,且频繁的任务)mysql
其次,活动的线程也消耗系统资源,若是线程的建立数量没有限制,当大量的客户链接服务器的时候,就会建立出大量的工做线程,他们会消耗大量的内存空间,致使系统的内存空间不足,影响服务器的使用。(不加以控制耗尽内存资源)react
最后,若是线程的数目固定,而且每一个线程都有很长的生命周期,那么线程切换也就是固定的,这样就会给服务器减轻不少压力,可是若是频繁的建立和销毁线程,必将致使频繁的切换线程,使得线程之间的切换再也不遵循系统的固定切换周期,线程切换的开销也会增大不少(维护一组固定的线程能减轻服务器压力)nginx
三、线程池有什么做用?
a. 重用存在的线程,减小对象建立、消亡的开销,性能佳。
b. 可有效控制最大并发线程数,提升系统资源的使用率,同时避免过多资源竞争,避免堵塞。
c. 提供定时执行、按期执行、单线程、并发数控制等功能。c++
四、说说Java中几种常见的线程池及使用场景。
newCachedThreadPool(弹性缓存线程池) 底层:返回ThreadPoolExecutor实例
通俗:当有新任务到来,则插入到SynchronousQueue中,因为SynchronousQueue是同步队列,所以会在池中寻找可用线程来执行,如有能够线程则执行,若没有可用线程则建立一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁
适用:执行不少短时间异步的小程序或者负载较轻的服务器程序员
newFixedThreadPool 底层:返回ThreadPoolExecutor实例
通俗:建立可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;若是池中的全部线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:执行长期的任务,性能好不少web
newSingleThreadExecutor(单线程线程池) 底层:FinalizableDelegatedExecutorService包装的ThreadPoolExecutor实例
通俗:建立只有一个线程的线程池,且线程的存活时间是无限的;当该线程正繁忙时,对于新任务会进入阻塞队列中(无界的阻塞队列)
适用:一个任务一个任务执行的场景面试
NewScheduledThreadPool(定时器线程池): 底层:建立ScheduledThreadPoolExecutor实
通俗:建立一个固定大小的线程池,线程池内线程存活时间无限制,线程池能够支持定时及周期性任务执行,若是全部线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构
适用:周期性执行任务的场景(轮巡)redis
备注
通常若是线程池任务队列采用LinkedBlockingQueue(无界)队列的话,那么不会拒绝任何任务(由于队列大小没有限制),这种状况下,ThreadPoolExecutor最多仅会按照最小线程数来建立线程,也就是说线程池大小被忽略了。
若是线程池任务队列采用ArrayBlockingQueue队列的话,那么ThreadPoolExecutor将会采起一个很是负责的算法,好比假定线程池的最小线程数为4,最大为8所用的ArrayBlockingQueue最大为10。随着任务到达并被放到队列中,线程池中最多运行4个线程(即最小线程数)。即便队列彻底填满,也就是说有10个处于等待状态的任务,ThreadPoolExecutor也只会利用4个线程。若是队列已满,而又有新任务进来,此时才会启动一个新线程,这里不会由于队列已满而拒接该任务,相反会启动一个新线程。新线程会运行队列中的第一个任务,为新来的任务腾出空间
spring 中的线程池
Spring中的ThreadPoolTaskExecutor是借助于JDK并发包中的java.util.concurrent.ThreadPoolExecutor来实现的.
spring线程池与JDK线程池区别
spring线程池是经过JDK的线程池ThreadPoolExecutor的实现。可是具备以下两个优势
(1)不须要本身设置阻塞队列
只须要设置阻塞队列大小,不须要指定那种阻塞队列。
(2)自动关闭线程池
经过实现DisposableBean的destroy方法
五、线程池都有哪几种工做队列?
无界队列
队列大小无限制,经常使用的为无界的LinkedBlockingQueue,使用该队列作为阻塞队列时要尤为小心,当任务耗时较长时可能会致使大量新任务在队列中堆积最终致使OOM
有界队列
类是遵循FIFO原则的队列如ArrayBlockingQueue,另外一类是优先级队列如PriorityBlockingQueue。PriorityBlockingQueue中的优先级由任务的Comparator决定。
六、怎么理解无界队列和有界队列?
有界队列也满,线程池执行了拒绝操做。
无界队列
无界队列会保持快速增加,直到耗尽系统内存。
七、线程池中的几种重要的参数及流程说明。
corePollSize:核心线程数。 当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
maximumPoolSize:最大线程数。代表线程中最多可以建立的线程数量
keepAliveTime:空闲的线程保留的时间。
BlockingQueue<Runnable>:阻塞队列,存储等待执行的任务。参数有ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue可选
ThreadFactory:线程工厂,用来建立线程
RejectedExecutionHandler:队列已满,并且任务量大于最大线程的异常处理策略。有如下取值
八、什么是反射机制?
* 1.在运行时判断任意一个对象所属的类。
* 2.在运行时构造任意一个类的对象。
* 3.在运行时判断任意一个类所具备的成员变量和方法。
* 4.在运行时调用任意一个对象的方法。
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
九、说说反射机制的做用。
一、反射最重要的用途就是开发各类通用框架。
一、得到Class对象 使用Class类的forName静态方法 调用某个对象的getClass()方法
二、判断是否为某个类的实例 用instanceof关键字来判断是否为某个类的实例
三、建立实例 使用Class对象的newInstance()方法来建立Class对象对应类的实例。
四、获取方法 getDeclaredMethods()
五、获取构造器信息
六、获取类的成员变量(字段)信息
getFiled: 访问公有的成员变量
getDeclaredField:全部已声明的成员变量。但不能获得其父类的成员变量
getFileds和getDeclaredFields用法
七、调用方法 invoke()
注意: 因为反射会额外消耗必定的系统资源 反射调用方法时能够忽略权限检查,所以可能会破坏封装性而致使安全问题。
一、你怎么理解http协议?
HTTP是Hyper Text Transfer Protocol(超文本传输协议) 默认端口号是80
协议中规定了客户端应该按照什么格式给服务器发送请求,同时也约定了服务端返回的响应结果应该是什么格
同时 HTTP 是一种无状态的协议,协议自己不记录客户端的历史请求记录。
参照:https://www.jianshu.com/p/b5993a20292a 讲解比较详细
十二、说说http协议的工做流程。
(1)浏览器分析连接所指向页面的URL。
(2)浏览器向DNS服务器请求解析URL的IP地址。
(3)域名系统DNS解析出URL对应的IP地址。
(4)浏览器与服务器创建TCP链接(默认端口号80)。
(5)浏览器发出HTTP的GET请求报文。
(6)服务器经过HTTP响应报文把相应的文件发送给浏览器。
1三、http有哪些请求提交方式?
POST、GET、HEAD、PUT 等
1四、http中的200,302,403,404,500,503都表明什么状态?
200 - 服务器成功返回网页 404 - 请求的网页不存在 503 - 服务器超时
1五、http get和post有什么区别?
最直观的区别就是GET把参数包含在URL中,POST经过request body传递参数。 ... GET请求在URL中传送的参数是有长度限制的,而POST么有。 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 GET比POST更不安全,由于参数直接暴露在URL上,因此不能用来传递敏感信息
1六、你怎么理解cookie和session,有哪些不一样点?
cookie的内容主要包括:名字,值,过时时间,路径和域。路径与域一块儿构成cookie的做用范围 若不设置过时时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失
当程序须要为某个客户端的请求建立一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识
(称为session id),若是已包含则说明之前已经为此客户端建立过session,服务器就按照session id把这个session检索出来
使用(检索不到,会新建一个),若是客户端请求不包含session id,则为此客户端建立一个session而且生成一个与此session相
关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应
中返回给客户端保存。
cookie数据存放在客户的浏览器上,session数据放在服务器上。 cookie不是很安全 session会在必定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
1八、什么是https,说说https的工做原理?
HTTPS全称为Hypertext Transfer Protocol over Secure Socket Layer,及以安全为目标的HTTP通道,简单说就是HTTP的安全版本,HTTPS的安全基础就是TLS/SSL
原理:客户端和服务端的交互 先经过非对称加密进行认证,在通过对称加密进行交互
1九、什么是http代理服务器,有什么用?
代理服务器大多被用来链接INTERNET(国际互联网)和Local Area Network(局域网)。
2二、说说Java虚拟机的生命周期及体系结构。
当启动一个Java程序时,一个虚拟机实例就诞生了,当程序关闭退出时,这个虚拟机实例随之消亡。JVM实例经过main()方法来运行一个Java程序。
JVM内部有两种线程:守护线程与非守护线程。守护线程一般是由虚拟机本身使用的,好比垃圾回收线程。当该程序全部的非守护线程都终止时,JVM实例将自动退出
2五、分布式系统你会考虑哪些方面?
1. 服务接口的设计相当重要
2. 后台升级要作到对用户透明
3. 应用方设计时候须要衡量后台服务失败的影响
3九、为何不把基本类型放堆中呢?
一:在方法中声明的变量,即该变量是局部变量,每当程序调用方法时,系统都会为该方法创建一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束
二:在类中声明的变量是成员变量,也叫全局变量,放在堆中的(由于全局变量不会随着某个方法执行结束而销毁)放在堆中
4一、Java中有没有指针的概念?
java中没有指针。 java中有引用(reference)c/c++中有指针
4二、Java中,栈的大小经过什么参数来设置?
JVM参数-堆分配参数总结
-Xms:设置最小堆值
-Xmx:设置最大堆值
-Xmn:设置年轻代值(设置它等于最小值和最大值相同)
-XX:NewSize:设置年轻代最小值
-XX:MaxNewSize:设置年轻代最大值
-Xss:设置线程栈值大小
-XX:PermSize:设置永久代最小值
-XX:MaxPermSize:设置永久代最大值
-XX:SuriviorRatio:设置年轻代中Eden与s0的比例
-XX:NewRatio:设置老年代与年轻代的比例。
-XX:MinHeapFreeRatio:设置堆空间最小空闲比例。当堆空间的空闲比例小于这个数值时,JVM变主动申请内存空间。
-XX:MaxHeapFreeRation:设置堆空间最大空闲比例。当堆空间的空闲比例大于这个数值时,JVM会压缩堆空间,获得一个较小的堆空间。
-XX:TargetSuriviorRatio:设置surivior空间使用率,当surivior空间使用率达到这个数值时,会将对应的对象送入老年代。
参见:https://blog.csdn.net/junchenbb0430/article/details/78407085 参数分配的影响
4五、讲一讲垃圾回收算法。
标记-清除法(Mark-Sweep) (被标记的是有引用的)
标记-清除算法是现代垃圾回收算法的思想基础,后面提到的全部算法都是基于该算法的思想。从名字就能看出,该算法分两个阶段进行——“标记”和“清除”。首先经过根对象标记全部可达的对象,而后清除全部未被标记的不可达对象。该算法有一个比较大的缺点,就是容易产生内存碎片。过多的内存碎片对于大对象的内存分配,效率很是低(碎片最直接的问题就是会致使没法分配大块的内存空间)
什么是可达?(理解为 能找到引用)
复制算法(Copying)
复制算法基于标记-清除算法并对其产生过多内存碎片的缺点进行了优化。复制算法将内存空间分红两等份(以下图的A和B),每次只使用其中的一块,当垃圾回收的时候,将A中的可达对象复制到B中,而后清空A中的全部对象。这样就避免了产生内存碎片的状况,但这种算法的缺点也是显而易见的,那就是太浪费空间。
标记整理算法
光从名字上就能看出,该算法继承自标记-清除算法。该算法在标记和清除之间又加了一个操做——压缩。首先将标记全部可达对象,而后将全部可达对象压缩(或者叫移动)到内存的一端,最后将边界之外的空间所有清空。这样既避免了产生内存碎片,又不须要空出一块内存空间,一箭双雕。
JVM中采用的并非某一种回收算法,而是多种算法组合使用,由于任何一种算法都不是完美的,都有自身的优缺点,有本身适用的场景。须要把他们放到合适的地方,这样才能各尽其能,达到一个最好的效果
4八、讲一讲内存分代及生命周期。
为何要分代?
若是说堆内存没有区域划分,全部新建立的对象和生命周期很长的对象放在一个区域,随着对象愈来愈多触发了JVM的垃圾回收机制,而每次回收都要遍历全部的对象,这个时间成本是不可思议的,严重影响GC效率。
新生代
新生代中的对象存活时间短,只须要在新生代区域中频繁进行GC,所有的新生对象都会在新生代
老年代
老年代也称Old区。老年代的对象是由新生代中存活屡次,或者是特殊缘由(缘由有多种,后续介绍)重新生代直接转移来的
永久代
永久代也称Permanent区或方法区。存储类信息、常量、静态变量以及即时编译器编译后的代码等等数据
针对HotSpot VM的实现
Minor GC:新生代GC(Minor GC):指发生在新生代的垃圾收集动做
Full GC:收集整个堆,包括young gen、old gen、perm gen
Young GC:只收集young gen的GC Old GC:只收集old gen的GC。
4九、什么状况下触发垃圾回收?
1. 执行 system.gc()的时候 (其实并不会立刻进行垃圾回收,甚至不必定会执行垃圾回收)
2.老年代空间不足 永久代空间不足 new 一个大对象,新生代放不下,直接到老年代,空间不够,触发FullGC
怎么避免频繁GC
1. 不要频繁的new 对象 2. 不要显示的调研system.gc() 3. 不要用String+ 使用StringBuilder 4.不要使用Long Integer 尽可能使用基本类型
5.少用静态变量 不会回收 6.能够使用null 进行回收
若是说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现
5五、如何进行JVM调优?有哪些方法?
JVM参数: GC的时间足够的小 GC的次数足够的少 发生Full GC的周期足够的长
5六、如何理解内存泄漏问题?有哪些状况会致使内存泄露?如何解决?
没法被释放的内存,累加的够多就会内存溢出
在For循环中,咱们不断的生成新的对象,而后将其添加到Vector对象中,以后将o引用置空。问题是当o引用被置空后,若是发生GC,咱们建立的Object对象是否可以被GC回收呢?答案是否认的。由于,GC在跟踪代码栈中的引用时,会发现v引用,而继续往下跟踪,就会发现v引用指向的内存空间中又存在指向Object对象的引用。也就是说尽管o引用已经被置空,可是Object对象仍然存在其余的引用,是能够被访问到的,因此GC没法将其释放掉。若是在此循环以后,Object对象对程序已经没有任何做用,那么咱们就认为此Java程序发生了内存泄漏
5九、为了解决数据库服务器的负担,如何作数据库的分布?
mycat,和 Sharding
6二、讲讲CAP理念。
CAP原则是NOSQL数据库的基石
分布式系统的CAP理论:理论首先把分布式系统中的三个特性进行了以下概括:
一致性(C):在分布式系统中的全部数据备份,在同一时刻是否一样的值。(等同于全部节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群总体是否还能响应客户端的读写请求。(对数据更新具有高可用性)
分区容忍性(P):以实际效果而言,分区至关于对通讯的时限要求。系统若是不能在时限内达成数据一致性,就意味着发生了分区的状况,必须就当前操做在C和A之间作出选择。
在分布式系统的设计中,没有一种设计能够同时知足一致性,可用性,分区容错性 3个特性
对于分布式数据系统,分区容忍性是基本要求,不然就失去了价值
C - Consistent ,一致性A - Availability ,可用性P - Partition tolerance ,分区容错性分布式系统之因此叫分布式,是由于提供服务的各个节点分布在不一样机器上,相互之间经过网络交互。那么必然存在网络故障断开的风险,这个网络断开的专业场景成为网络分区。
在网络分区发生时,两个分布式节点之间没法进行通讯,那么咱们对一个节点进行的修改操做将没法同步到另一个节点,因此数据的「一致性」将没法知足,由于两个分布式节点的数据再也不保持一致。除非咱们牺牲「可用性」,也就是暂停分布式节点服务,在网络分区发生时,再也不提供修改数据的功能,直到网络情况彻底恢复正常再继续对外提供服务。或者为了保证可用性,而牺牲数据一致性。
因此,CAP一句话就是,在网络分区时,不能同时保证可用性和一致性。
为了保证分布式中间件的可用性,大部分中间件会支持最终一致性
分布式锁是cp模型,redis 是ap模型
参照:https://www.cnblogs.com/duanxz/p/5229352.html 讲解cap
6三、怎么理解强一致性、单调一致性和最终一致性?
从客户端角度,多进程并发访问时,更新过的数据在不一样进程如何获取的不一样策略,决定了不一样的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。若是能容忍后续的部分或者所有访问不到,则是弱一致性。若是通过一段时间后要求能访问到更新后的数据,则是最终一致性。
6六、谈一谈一致性哈希算法。
是为了解决服务器的变更形成hash结果不一致的问题,不管增长机器最终hash要一致,结果不受影响
参照:https://zhuanlan.zhihu.com/p/34985026
70、OSI有哪七层模型?TCP/IP是哪四层模型。
应用层:应用程序间沟通的层,如简单电子邮件传输(SMTP)、文件传输协议(FTP)、网络远程访问协议(Telnet)等。
传输层:在此层中,它提供了节点间的数据传送服务,如传输控制协议(TCP)、用户数据报协议(UDP)等,TCP和UDP给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,而且肯定数据已被送达并接收。
互连网络层:负责提供基本的数据封包传送功能,让每一块数据包都可以到达目的主机(但不检查是否被正确接收),如网际协议(IP)。
网络接口层:对实际的网络媒体的管理,定义如何使用实际网络(如Ethernet、Serial Line等)来传送数据。
osi七层结构:
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
equals 和hashcode 若是hashcode不一样 则不进行equals比较 重写hashcode equals必需要重写
== 比较地址 equals比较内容
Strin的equals重写 原理(先进行地址比较,地址不相等就进行值(内容)的比较,值相等equals的2个对象就相等,地址相等2个对象就相等 )
四、&和&&的区别
$:只要有一个值为0结果为0,不然结果为1。 $$ :都为真才是真
五、Collection 和 Collections的区别
一、java.util.Collection 是一个集合接口
二、java.util.Collections 是一个包装类。它包含有各类有关集合操做的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
七、String s = new String("xyz");建立了几个String Object
答案:两个,一个是字符串字面量"xyz"所对应的、驻留(intern)在一个全局共享的字符串常量池中的实例,另外一个是经过new String(String)建立并初始化的、内容与"xyz"相同的实例
九、short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错
// s1 = s1+1;//报错,由于s1+1结果是int类型,等号左边是short类型,因此要强转
十、Java有没有goto 没有
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==仍是equals()? 它们有何区别?
用equals()而不用==来区分 set里面存放的是对象的引用,因此当两个元素只要知足了equals()时就已经指向同一个对象,
1六、List, Set, Map是否继承自Collection接口
答:List,Set是,Map不是。 map是本身的一个接口
20、构造器Constructor是否可被override
构造器Constructor不能被继承,所以不能重写Overriding,但能够被重载Overloading。
2四、两个对象值相同(x.equals(y) == true),但却可有不一样的hash code,这句话对不对
1) 对象相等则hashCode必定相等; 2) hashCode相等对象未必相等
String st1 = new String(“abc”);
答案是:在内存中建立两个对象,一个在堆内存,一个在常量池
例子
String st1 = new String("abc");
String st2 = "abc";
System.out.println(st1 == st2);
System.out.println(st1.equals(st2));
答案:false 和 true
因为有前面两道提内存分析的经验和理论,因此,我能快速得出上面的答案。==比较的st1和st2对象的内存地址,因为st1指向的是堆内存的地址,st2看到“abc”已经在常量池存在,就不会再新建,因此st2指向了常量池的内存地址,因此==判断结果输出false,二者不相等。第二个equals比较,比较是两个字符串序列是否相等,因为就一个“abc”,因此彻底相等。
30、float型float f=3.4是否正确?
答案:不正确。
缘由:精度不许确,应该用强制类型转换,以下所示:float f=(float)3.4 或float f = 3.4f
在java里面,没小数点的默认是int,有小数点的默认是 double;
3四、谈谈final, finally, finalize的区别
final 能够修饰类、方法、变量。 finally 一般是用来保证代码必定被执行的 finalize 是java.lang.Object的一个方法, 是用来保证对象在被垃圾回收以前完成特定资源的回收,如今finalize已经不被建议使用,
3八、运行时异常与通常异常有何异同
error:通常是指java虚拟机相关的问题,如系统崩溃、虚拟机出错误、动态连接失败等,这种错误没法恢复或不可能捕获,将致使应用程序中
运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,这些异常是不检查异常,程序中能够选择捕获处理,也能够不处理。
4六、描述一下JVM加载class文件的原理机制?
JVM中类的装载是由类加载器(ClassLoader)和它的子类来实现的
当Java程序须要使用某个类时,JVM会确保这个类已经被加载、链接(验证、准备和解析)和初始化。类的加载是指把类的.class文件中的数据读入到内存中,一般是建立一个字节数组读入.class文件,而后产生与所加载类对应的Class对象
从Java 2(JDK 1.2)开始,类加载过程采起了父亲委托机制
4七、排序都有哪几种方法?请列举
1、冒泡排序
十种排序算法总结(冒泡、插入、选择、希尔、归并、堆、快速,计数,桶,基数)
基本思想是:两两比较相邻记录的关键字,若是反序则交换 冒泡排序时间复杂度最好的状况为O(n),最坏的状况是O(n^2)
7、快速排序
经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的全部数据都比另一部分的全部数据都要小,而后再按此方法对这两部分数据分别进行快速排序,整个排序过程能够递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn)
4八、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别表明什么意义?在try块中能够抛出异常吗?
throws 用在方法上 throw 用在
垃圾回收器的基本原理是什么?垃圾回收器能够立刻回收内存吗?有什么办法主动通知虚拟机进行垃圾回收
对于GC来讲,当程序员建立对象时,GC就开始监控这个对象的地址、大小以及使用状况。一般,GC采用有向图的方式记录和管理堆(heap)中的全部对象。经过这种方式肯定哪些对象是"可达的",哪些对象是"不可达的"。当GC肯定一些对象为"不可达"时,GC就有责任回收这些内存空间。能够。程序员能够手动执行System.gc(),通知GC运行,可是Java语言规范并不保证GC必定会执行。
5四、静态变量和实例变量的区别?
在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。
在程序运行时的区别:实例变量属于某个对象的属性,必须建立了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量
5五、什么是java序列化,如何实现java序列化?
序列化:把对象转换为字节序列的过程称为对象的序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
有些信息咱们想让他持久的保存起来,那么这个就叫序列化。
就是把内存里面的这些对象给变成一连串的字节(bytes)描述的过程。
60、说出一些经常使用的类,包,接口,请各举5个
经常使用的接口 List set Map
经常使用的类: String Integer HashMap java.util.Date, stringbuffer
经常使用的包: java.io(inputstream) java.sql(date) java.lang(object) java.util (list)
多线程
四、Runnable接口和Callable接口的区别
Callable接口的call()方法能够有返回值(经过Future接口的get()方法,不过此方法是阻塞性的),而Runnable接口的run()方法没有返回值
Callable接口的call()方法能够声明抛出异常,而Runnable接口的run()方法不能够声明抛出异常
建立线程的2种方式,一种是直接继承Thread,另一种就是实现Runnable接口。
这2种方式都有一个缺陷就是:在执行完任务以后没法获取执行结果。
若是须要获取执行结果,就必须经过共享变量或者使用线程通讯的方式来达到效果,这样使用起来就比较麻烦。
而自从Java 1.5开始,就提供了Callable和Future,经过它们能够在任务执行完毕以后获得任务执行结果
九、一个线程若是出现了运行时异常会怎么样
若是异常没有被捕获该线程将会中止执行
1三、ThreadLocal有什么用
而ThreadLocal则用于线程间的数据隔离 经过ThreadLocal的set()方法设置到线程的ThreadLocal.ThreadLocalMap里的是是线程本身要存储的对象,其余线程不须要去访问,也是访问不到的
1七、怎么检测一个线程是否持有对象监视器
在java.lang.Thread中有一个方法叫holdsLock(),它返回true若是当且仅当当前线程拥有某个具体对象的锁。
20、ReadWriteLock是什么
读写锁分为读锁和写
写锁和写锁之间须要互斥,也就是说,若是只是读数据,就能够多个线程同时读,可是若是你要写数据,就必须互斥,使得同一时刻只有一个线程在操做。
2一、FutureTask是什么
FutureTask可用于异步获取执行结果或取消执行任务的场景。经过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,以后能够在外部经过FutureTask的get方法异步获取执行结果,所以,FutureTask很是适合用于耗时的计算,主线程能够在完成本身的任务后,再去获取结果。另外,FutureTask还能够确保即便调用了屡次run方法,它都只会执行一次Runnable或者Callable任务,或者经过cancel取消FutureTask的执行等。
2五、不可变对象对多线程有什么帮助
建立后状态不能被修改的对象叫做不可变对象。不可变对象天生就是线程安全的。
2七、若是你提交任务时,线程池队列已满,这时会发生什么
ThreadPoolExecutor's中的submit()方法会抛出一个RejectedExecutionException异常啦
3二、什么是CAS
CAS(比较与交换,Compare and swap) 是一种有名的无锁算法。无锁编程,即不使用锁的状况下实现多线程之间的变量同步,也就是在没有线程被阻塞的状况下实现变量的同步,因此也叫非阻塞同步
40、高并发、任务执行时间短的业务怎样使用线程池?并发不高、任务执行时间长的业务怎样使用线程池?并发高、业务执行时间长的业务怎样使用线程池?
newCachedThreadPool(弹性缓存线程池) newSingleThreadExecutor(单线程线程池) newFixedThreadPool
数据库
五、与Oracle相比,mysql有什么优点?
oracle
性能:Oracle 性能高
缺点:
对硬件的要求很高;
价格比较昂贵;
管理维护麻烦一些;
操做比较复杂,须要技术含量较高
mysql
优势:
体积小、速度快、整体拥有成本低,开源;
支持多种操做系统;
是开源数据库,提供的接口支持多种语言链接操做
八、请简洁描述mysql中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别?
读未提交(read uncommitted):能够读取其余 session 未提交的脏数据。
读已提交(read committed):容许不可重复读取,但不容许脏读取。提交后,其余会话能够看到提交的数据。
可重复读(repeatable read):禁止不可重复读取和脏读取、以及幻读(innodb 独有)。
串行(serializable):事务只能一个接着一个地执行,但不能并发执行。事务隔离级别最高。
不一样的隔离级别有不一样的现象,并有不一样的锁定/并发机制,隔离级别越高,数据库的并发性就越差。
3三、LIKE和REGEXP操做有什么区别?
其中like要求整个数据都要匹配,而REGEXP只须要部分匹配便可。
也就是说,用Like,必须这个字段的全部内容知足条件,而REGEXP只须要有任何一个片断知足便可
mysql索引采用 索引的数据结构(B Tree 、 B+Tree)
B树
1.全部非叶子结点至多拥有两个儿子(Left和Right);
2.全部结点存储一个关键字;
3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树;左小右大
B+Tree
B+Tree只有最下面的叶子节点才是它的数据,每一个节点能够多条数据,查找1是执行3次IO,查找2一样也是执行3次IO ,MySQL查询数据最多IO次数3-5次(固然数据量越大,树的高度也会增加,IO也会增长)
3四、BLOB和TEXT有什么区别?
TEXT与BLOB的主要差异就是BLOB保存二进制数据,TEXT保存字符数据。
5二、mysql里记录货币用什么字段类型好?
货币在数据库中MySQL经常使用Decimal和Numric类型表示 值做为字符串存储,而不是做为二进制浮点数,以便保存那些值的小数精度
不使用float或者double的缘由:由于float和double是以二进制存储的,因此有必定的偏差。
5四、mysql有关权限的表都有哪几个?
user权限表:记录容许链接到服务器的用户账号信息,里面的权限是全局级的。
db权限表:记录各个账号在各个数据库上的操做权限。
table_priv权限表:记录数据表级的操做权限。
columns_priv权限表:记录数据列级的操做权限。
host权限表:配合db权限表对给定主机上数据库级操做权限做更细致的控制。这个权限表不受GRANT和REVOKE语句的影响。
GC的三种收集方法:标记清除、标记整理、复制算法的原理与特色,分别用在什么地方,优化收集方法的思路
第一种:标记清除 适合在老年代进行垃圾回收,好比CMS收集器就是采用该算法进行回收的。
第二种:标记整理 适合老年代进行垃圾收集
第三种:复制算法 适合新生代区进行垃圾回收
参照:https://blog.csdn.net/fateruler/article/details/81158510
九、几种经常使用的内存调试工具:jmap、jstack、jconsole、jhat
十、类加载的几个过程?
1) 加载:根据查找路径找到相应的class文件,而后导入。类的加载方式分为
隐式加载和显示加载两种。隐式加载指的是程序在使用new关键词建立对象时,会隐式的调用类的加载器把对应的类加载到jvm中。显示加载指的是经过直接调用class.forName()方法来把所需的类加载到jvm中。
2) 检查:检查夹加载的class文件的正确性。
3) 准备;给类中的静态变量分配内存空间。
4) 解析:虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示,而在直接引用直接指向内存中的地址。
5) 初始化:对静态变量和静态代码块执行初始化工做。
1三、简述java垃圾回收机制?
只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收。
1九、什么是类加载器,类加载器有哪些?
引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。通常来讲,Java 应用的类都是由它来完成加载的。能够经过 ClassLoader.getSystemClassLoader()来获取它。
除了系统提供的类加载器之外,开发人员能够经过继承 java.lang.ClassLoader类的方式实现本身的类加载器,以知足一些特殊的需求。
参见:https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
20、简述java内存分配与回收策率以及Minor GC和Major GC
新生代 GC(Minor GC):指发生在新生代的垃圾收集动做,由于 Java 对象大多都具
备朝生夕灭的特性,因此 Minor GC 很是频繁,通常回收速度也比较快(适合采用复制算法)
老年代 GC(Major GC / Full GC):指发生在老年代的 GC,出现了 Major GC,常常
会伴随至少一次的 Minor GC(但非绝对的,在 ParallelScavenge 收集器的收集策略里
就有直接进行 Major GC 的策略选择过程) 。MajorGC 的速度通常会比 Minor GC 慢 10
倍以上。
pring Aop中四个重要概念,切点,切面,链接点,通知
1. 通知: 就是咱们编写的但愿Aop时执行的那个方法。咱们经过Aop但愿咱们编写的方法在目标方法执行前执行,或者执行后执行。
2. 切点:切点就是咱们咱们配置的知足咱们条件的目标方法。好比咱们规定:名字前面是select开头的才执行咱们自定义的通知方法。那么这些select开头的方法就是切点。
3. 链接点:链接点能够说是切点的全集。切点是链接点的子集。也能够理解为,链接点是咱们没有定义那个select开头规则时,知足条件的所有的方法。
4. 切面:切面是切点和通知的组合称谓,就是变相给组合起了个名字。
spring AOP 之一:spring AOP功能介绍
参照:https://www.cnblogs.com/duanxz/p/6754606.html
aop 配置 能够配置事物,能够配置apsect 切面上进行通知
aop实现了 jdk的动态代理和cglib 的动态代理 2种方式 jdk的代理 实现类须要实现接口才能代理 ,cglib 能够直接代理某个类 进行方法拦截
spring mvc 面试题答案 蚂蚁金福 https://zhuanlan.zhihu.com/p/59377434
SpingMvc中的控制器的注解通常用那个,有没有别的注解能够替代
通常用@Conntroller注解,表示是表现层,不能用用别的注解代替.
八、 @RequestMapping注解用在类上面有什么做用?
@RequestMapping 有两种标注方式,一种是标注在类级别上,一种是标注在方法级别上。标注在方法上时,value 表示访问该方法的 URL 地址。标注在类上时,value 至关于一个命名空间,即访问该 Controller 下的任意方法都须要带上这个命名空间。
参照https://www.cnblogs.com/caoyc/p/5635173.html
十一、怎么样在方法里面获得Request,或者Session?
能够经过httpservletrequst放在方法参数上 也能够 经过(Map)ActionContext.getContext().get("request")
springmvc 方法获取前台的参数 注解有
@RequestParam @PathVariable @RequestBody 返回的有@ResponseBody 表示服务器返回的时候以一种什么样的方式进行返回, 将内容或对象做为 HTTP 响应正文返回,值有不少,通常设定为json
1五、SpringMVC怎么样设定重定向和转发的?
return "forward:/userHome" return "redirect:/"; 经过forward , redirect
1七、SpringMvc 用什么对象从后台向前台传递数据的?
答:经过 ModelMap 对象,能够在这个对象里面用 put 方法,把对象加到里面,前台就能够过 el 表达式拿到。
2一、当一个方法向 AJAX 返回特殊对象,譬如 Object,List 等,须要作什么处理?
答:要加上@ResponseBody 注解
2二、SpringMvc 里面拦截器是怎么写的?
答:有两种写法,一种是实现接口,另一种是继承适配器类,而后在 SpringMvc 的配置文配置拦截器便可:<!-- 配置 SpringMvc 的拦截器 --><mvc:interceptors>
netty
1.BIO、NIO和AIO的区别?
BIO是一个链接一个线程。
NIO是一个请求一个线程。
AIO是一个有效请求一个线程。
Java BIO (传统io): 同步并阻塞,服务器实现模式为一个链接一个线程,即客户端有链接请求时服务器端就须要启动一个线程进行处理,若是这个链接不作任何事情会形成没必要要的线程开销,固然能够经过线程池机制改善。
Java NIO(改进后的io) : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的链接请求都会注册到多路复用器上,多路复用器轮询到链接有I/O请求时才启动一个线程进行处理。
Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,
BIO方式适用于链接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4之前的惟一选择,但程序直观简单易理解。
NIO方式适用于链接数目多且链接比较短(轻操做)的架构,好比聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于链接数目多且链接比较长(重操做)的架构,好比相册服务器,充分调用OS参与并发操做,编程比较复杂,JDK7开始支持。
同步 : 本身亲自出马持银行卡到银行取钱(使用同步IO时,Java本身处理IO读写);
异步 : 委托一小弟拿银行卡到银行取钱,而后给你(使用异步IO时,Java将IO读写委托给OS处理,须要将数据缓冲区地址和大小传给OS(银行卡和密码),OS须要支持异步IO操做API);
阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回);
非阻塞 : 柜台取款,取个号,而后坐在椅子上作其它事,等号广播会通知你办理,没到号你就不能去,你能够不断问大堂经理排到了没有,大堂经理若是说还没到你就不能去(使用非阻塞IO时,若是不能读写Java调用会立刻返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)
参照:https://blog.csdn.net/skiof007/article/details/52873421
参见:https://blog.csdn.net/anxpp/article/details/51512200 更详细
3.Netty的特色?
Netty是一个高性能、异步事件驱动的NIO框架 Netty的全部IO操做都是异步非阻塞的
Netty的特色
(1) 使用更高效的socket底层,对epoll空轮询引发的cpu占用飙升在内部进行了处理,避免了直接使用NIO的陷阱,简化了NIO的处理方式。
(2) 采用多种decoder/encoder 支持,对TCP粘包/分包进行自动化处理
(3) 可以使用接受/处理线程池,提升链接效率,对重连、心跳检测的简单支持
(4)可配置IO线程数、TCP参数, TCP接收和发送缓冲区使用直接内存代替堆内存,经过内存池的方式循环利用ByteBuf
(5) 经过引用计数器及时申请释放再也不引用的对象,下降了GC频率
(6)使用单线程串行化的方式,高效的Reactor线程模型
(7) 无锁化的串行设计,采用环形数组缓冲区实现无锁化并发编程
(8)大量使用了volitale、使用了CAS和原子类、线程安全类的使用、读写锁的使用
参见:https://blog.csdn.net/baiye_xing/article/details/73136174
6.了解哪几种序列化协议?
一、XML 二、JSON 三、Fastjson 等 参见:https://blog.csdn.net/baiye_xing/article/details/73249819
dubbo
四、dubbo都支持什么协议,推荐用哪一种?
Dubbo支持dubbo、rmi、hessian、http、webservice、thrift、redis等多种协议,可是Dubbo官网是推荐咱们使用Dubbo协议的。
五、Dubbo须要 Web 容器吗?
dubbo服务容器是一个standalone的启动程序,由于后台服务不须要Tomcat或JBoss等Web容器的功能, 服务容器只是一个简单的Main方法,
并加载一个简单的Spring容器,用于暴露服务。 服务容器的加载内容能够扩展,内置了spring, jetty, log4j等加载
十、Dubbo有哪几种配置方式?
根据 DUBBO 官方文档,配置 DUBBO 有 4 种方式,分别是:
1. XML 配置文件方式(经常使用的方式)
2. properties 配置文件方式
3. annotation 配置方式
4. API 配置方式
十一、Dubbo核心的配置有哪些?
生产者,提供者 参见:https://www.cnblogs.com/wangzhuxing/p/9735258.html
十二、在Provider 上能够配置的 Consumer 端的属性有哪些?
timeout group version registry
1三、Dubbo启动时若是依赖的服务不可用会怎样?
Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。不然能够指定不检查
1四、Dubbo推荐使用什么序列化框架,你知道的还有哪些?
dubbo默认使用的是
Hessian序列化
1五、Dubbo默认使用的是什么通讯框架,还有别的选择吗?
Dubbo使用的是netty ,reactor模式采用nio的方式通讯,主流通讯框架包括netty,mina,Grizzly
MYBATIS
二、讲下MyBatis的缓存
1、mybatis和同是持久层的hibernate同样,都存在着缓存机制,今天来讲一下mybatis的缓存机制。
查询缓存来缓存数据,从而达到提升查询性能的要求,以提升咱们项目的效率!!
2、mybatis的缓存机制有两级:
(1)一级缓存:一级缓存mybatsi已近为咱们自动开启,不用咱们手动操做,并且咱们是关闭不了的!!可是咱们能够手动清除缓存。(SqlSession级别)
(2)二级缓存:二级缓存须要咱们手动开启。(全局级别)
四:二级缓存
二级缓存的做用:经过度一级缓存的了解。推挤缓存是基于同一个SqlSesion类的实例对象的。可是,有些时候在wenb工厂中将会执行查询操做的方法分装在某个Service方法中,当查询完一次后,
Service方法结束,此时SqlSession类的实例对象就会关闭,一级缓存就会被清空。此时若再次调用用Service方法查询同一个信息,此时异界缓存就是空的,从而没法从缓存中获取信息!!
所以,咱们能够使用二级缓存,二级缓存存在与Mapper实例中,当多个SqlSession类的实例对象加载相同的mapper文件,并执行其中国的SQL配置时,他们就共享一个Mapper缓存。
当某个SqlSession类的实例对象执行了增,删,改,等改变数据的操做时,Mapper实例都会清空其二级缓存!
简单来讲就是 多个线程执行相同的sql 会从缓存中取 ,即便不是同一个sqlsession
hibernate的查询
有creatsqlquery(写sql的) createquery(查询对象的)
shiro 配置权限的方式有几种,分别解释一下
4种
1,在配置文件中对过滤的url进行权限的添加, 2. 在service方法上配置注解@RequiresPermissions(“user:delete”)
3. 在jsp页面中使用标签 <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
4.编程方式实现用户权限控制
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
//有权限
}else{
//无权限
}
参见:https://blog.csdn.net/qq_38263083/article/details/82716702
1七、MyBatis里面的动态Sql是怎么设定的?用什么语法?
MyBatis中用于实现动态SQL的元素主要有:if 、choose、 when、otherwise、trim、where、set 、foreach。
shiro的实现原理? 核心原理过滤器
subject:主体,能够是用户也能够是程序,主体要访问系统,系统须要对主体进行认证、受权。
securityManager:安全管理器,主体进行认证和受权都是经过securityManager进行。
authenticator:认证器,主体进行认证最终经过authenticator进行的。
authorizer:受权器,主体进行受权最终经过authorizer进行的。
sessionManager:web应用中通常是用web容器对session进行管理,shiro也提供一套session管理的方式。
SessionDao: 经过SessionDao管理session数据,针对个性化的session数据存储须要使用sessionDao。
cache Manager:缓存管理器,主要对session和受权数据进行缓存,好比将受权数据经过cacheManager进行缓存管理,和ehcache整合对缓存数据进行管理。
realm:域,领域,至关于数据源,经过realm存取认证、受权相关数据。
spring中有spring security (原名Acegi),是一个权限框架,它和spring依赖过于紧密,没有shiro使用简单。
shiro不依赖于spring,shiro不只能够实现 web应用的权限管理,还能够实现c/s系统,分布式系统权限管理,shiro属于轻量框架,愈来愈多企业项目开始使用shiro。
使用shiro实现系统的权限管理,有效提升开发效率,从而下降开发成本
mybatis 使用resultmap 实现一个查询
关联关系
一对多:
用collection 标签关联
多对一:
用association 标签关联
参见:https://blog.csdn.net/qq_33561055/article/details/78861131
mapper 代理如何实现的
采用Mapper动态代理方法只须要编写相应的Mapper接口(至关于Dao接口),那么Mybatis框架根据接口定义建立接口的动态代理对象,代理对象的方法体同Dao接口实现类方法。
Mapper接口开发须要遵循如下规范:
一、Mapper.xml文件中的namespace与mapper接口的全类名相同。
二、Mapper接口方法名和Mapper.xml中定义的每一个statement的id相同。
三、Mapper接口方法的输入参数类型和mapper.xml中定义的每一个sql 的parameterType的类型相同。
四、Mapper接口方法的输出参数类型和mapper.xml中定义的每一个sql的resultType的类型相同。
动态代理的实现 省去了获取sqlsession的步骤,在方法执行前进行动态执行
参见:https://blog.csdn.net/xiaokang123456kao/article/details/66476828
参见:https://blog.csdn.net/xiaokang123456kao/article/details/76228684
缓存的实现原理
?????
ConcurrentHashMap和Hashtable的区别
Hashtable和ConcurrentHashMap有什么分别呢?它们均可以用于多线程的环境,可是当Hashtable的大小增长到必定的时候,性能会急剧降低,
由于迭代时须要被锁定很长的时间。由于ConcurrentHashMap引入了分割(segmentation),不论它变得多么大,仅仅须要锁定map的某个部分,
而其它的线程不须要等到迭代完成才能访问map。简而言之,在迭代的过程当中,ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map。
hashmap 线程不安全的 由于多线程环境下,使用Hashmap进行put操做会引发死循环,致使CPU利用率接近100%,因此在并发状况下不能使用HashMap。
hashtable 每一步操做都有锁,线程安全可是很慢性能低
HashTable容器使用synchronized来保证线程安全,但在线程竞争激烈的状况下HashTable的效率很是低下。
由于当一个线程访问HashTable的同步方法时,其余线程访问HashTable的同步方法时,可能会进入阻塞或轮询状态。
如线程1使用put进行添加元素,线程2不但不能使用put方法添加元素,而且也不能使用get方法来获取元素,因此竞争越激烈效率越低。
ConcurrentHashMap 线程安全的 利用锁分段技术
HashTable容器在竞争激烈的并发环境下表现出效率低下的缘由,是由于全部访问HashTable的线程都必须竞争同一把锁,
那假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不一样数据段的数据时,线程间就不会存在锁竞争,
从而能够有效的提升并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术。
执行put方法的线程会得到锁,只有当此线程的put方法执行结束后才会释放锁,根据多线程的知识,得到锁的线程会通知其余试图操做put方法的线程,并通知其余线程出于等待状态,
直到释放锁后,其余线程才会去从新竞争锁。这一点保证了ConcurrentHashMap的线程安全。
线程安全的比hashtable 性能更高
参见:https://blog.csdn.net/sbq63683210/article/details/51679790
设计一个简单权限须要几张表
5张 user表 user-role表 role表 role-author表 author表
描述一下登陆须要哪些步骤
arraylist 如何扩容
初始化会被分配10个长度当超出长度后在扩容1.5倍
ArrayList是采起延迟分配对象数组大小空间的,当第一次添加元素时才会分配10个对象空间,
当添加第11个元素的时候,会扩容1.5倍,当添加到16个元素的时候扩容为15*1.5=22,以此类推。
当咱们在明确对象的大体数目时候提早指定初始化数组的大小是一个很是明智的选择
hashmap 如何扩容
默认的是长度*负载因子(0.75)
当map中包含的Entry的数量大于等于threshold = loadFactor * capacity的时候,且新建的Entry恰好落在一个非空的桶上,此刻触发扩容机制,将其容量扩大为2倍
AOP的实现原理
spring框架对于这种编程思想的实现基于两种动态代理模式,分别是 JDK动态代理 及 CGLIB的动态代理,这两种动态代理的区别是 JDK动态代理须要目标对象实现接口,而 CGLIB的动态代理则不须要
动态代理模式:动态代理类的源码是在程序运行期间,经过 JVM 反射等机制动态生成。代理类和委托类的关系是运行时才肯定的
使用 JDK 生成的动态代理的前提是目标类必须有实现的接口。但这里又引入一个问题,若是某个类没有实现接口,就不能使用 JDK 动态代理。因此 CGLIB 代理就是解决这个问题的。
CGLIB 是以动态生成的子类继承目标的方式实现,在运行期动态的在内存中构建一个子类
CGLIB 使用的前提是目标类不能为 final 修饰。由于 final 修饰的类不能被继承。
如今,咱们能够看看 AOP 的定义:面向切面编程,核心原理是使用动态代理模式在方法执行先后或出现异常时加入相关逻辑。
AOP 是基于动态代理模式。
AOP 是方法级别的。
AOP 能够分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码造成的类。
参照:http://www.importnew.com/31318.html
数据结构:
关于树:https://zhuanlan.zhihu.com/p/27700617
java io流的操做
参见:https://juejin.im/post/5af79bcc51882542ad771546
java io流中涉及的设计模式
private static final String SEPARATOR = File.separator;
File file = new File("e:" + SEPARATOR + "io" + SEPARATOR + "test.txt");
//一、得到子节输入流
FileInputStream fileInputStream=new FileInputStream(file);
二、构造转换流
InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream);
三、 构造缓冲字符流
BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
//备注一、2两步骤体现出了适配器模式
//2步骤体现了InputStreamReader类具备将子节输入流转换为字符输入流的功能
//二、3两步骤体现了装饰模式(wrapper包装模式)
io中的适配器模式
因为InputStream是字节流不能享受到字符流读取字符那么便捷的功能,所以借助
InputStreamReader将其转为Reader子类,所以能够拥有便捷操做文本文件方法。
OutputStream同理。
io中的装饰(包装)模式
将InputStream字节流包装为BufferedReader过程就装饰的过程。一开始
InputStream只有read一个字节的方法,包装为Reader以后拥有read一个字符的功
能,在包装成BufferedReader以后就拥有read一行字符串功能。OutputStream同理
最后说一点,咱们做为程序员,研究问题仍是要仔细深刻一点的。当你对原理了解的有够透彻,开发起来也就驾轻就熟了,不少开发中的问题和疑惑也就迎刃而解了,
并且在面对其余问题的时候也可作到举一反三。固然在开发中没有太多的时间让你去研究原理,开发中要以实现功能为前提,可等项目上线的后,
你有大把的时间或者空余的时间,你大可去刨根问底,深刻的去研究一项技术,为以为这对一名程序员的成长是很重要的事情。
1.请列举出在JDK中几个经常使用的设计模式?
享元模式
java.lang.Integer(其它基本类型包装类(除去Float,Double)也如此,还有BigDecimal)
Integer.valueOf()方法
byte,short,int,long,boolean,char的包装型在类加载到JVM时,已经缓存了制定范围的对象引用,由于值的设定使用的是static块或者常量。其中char的范围为:0~127;boolean的值为true和false;其它默认范围都是-127~128。其中int的上限127能够调整,这须要调整JVM的参数。
同时利用了享元模式的还有String这个类,由于生存的每一个字符串都是不可变的。
.迭代器模式
不少集合已经使用了迭代器进行遍历。(Iterator)
建造者模式
java.lang.StringBuilder,这是一个final类
public StringBuilder append(String str)方法,这一方法是对父类的覆写。
类功能:用于一个不可更改的字符序列。
方法功能:根据现有字符序列和追加字符,经过系统拷贝方法System.arraycopy生成一个新的字符序列。
适配器模式
java.util.Arrays
public static List asList(T… a)方法
类功能:此类包含了大量对数组操做的方法。
方法功能:将一个引用类型的数组转为一个List。从而能够使用List类的操做来操做数组对象,可是有一点要注意:就是不能使用add(),remove()操做,由于返回的list底层是基于数组的,数组结构是不能更改的。 list类就是这里的适配器,经过这个适配器,对数组的直接操做变为间接操做。
参见:https://blog.csdn.net/caoxiaohong1005/article/details/79961539
.在 Java 中,什么叫观察者设计模式(observerdesign pattern)?
发布订阅模式是最经常使用的一种观察者模式的实现,而且从解耦和重用角度来看,更优于典型的观察者模式
在发布订阅模式中,发布者和订阅者之间多了一个发布通道;一方面从发布者接收事件,另外一方面向订阅者发布事件;订阅者须要从事件通道订阅事件
7.在 Java 中,为何不容许从静态方法中访问非静态变量?
由于静态方法的调用不是经过实例对象进行的,因此在静态方法中没有this指针,不能访问所属类的非静态变量和方法,只能访问方法体内的局部变量、本身的参数和静态变量。
成员变量分为实例变量和静态变量。
10.举例说明什么状况下会更倾向于使用抽象类而不是接口?
使用模板方法设计模式要使用抽象类
nginx
nginx负载均衡的算法怎么实现的
nginx 的 upstream目前支持 4 种方式的分配
1)、轮询(默认)
每一个请求按时间顺序逐一分配到不一样的后端服务器,若是后端服务器down掉,能自动剔除。
2)、weight
指定轮询概率,weight和访问比率成正比,用于后端服务器性能不均的状况。
2)、ip_hash
每一个请求按访问ip的hash结果分配,这样每一个访客固定访问一个后端服务器,能够解决session的问题。
3)、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
4)、url_hash(第三方)
nginx内置策略包含加权轮询和ip hash
加权轮询算法分为先深搜索和先广搜索,那么nginx采用的是先深搜索算法,即将首先将请求都分给高权重的机器,直到该机器的权值降到了比其余机器低,才开始将请求分给下一个高权重的机器;
参见:http://dujianjian.win/2018/05/24/nginx/#nginx%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1%E7%9A%84%E7%AE%97%E6%B3%95%E6%80%8E%E4%B9%88%E5%AE%9E%E7%8E%B0%E7%9A%84
springmvc 方法跳转
重定向:"redirect:/url" request的做用域被改变了 就不是一个回话了
转发: "forward:/url" request的做用域仍是同一个 仍是同一个回话参数共享
参见:https://blog.csdn.net/u013041642/article/details/72190223
spring mvc 支持以下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void。
参见:https://www.cnblogs.com/xiepeixing/p/4243801.html
static synchronize 方法锁(类锁) 和直接synchronize 方法锁(对象锁) 不冲突 互相执行各自的
对象能够有任意个,多以与类不冲突 static 修饰的是共享的不是线程安全的
经常使用设计模式
参见:https://mp.weixin.qq.com/s/OAEtpM-h3OT_bBYgvyvE0w
观察者模式核心是:观察者要注册到被观察者里面,一旦被观察者变动了消息,就会通知到全部的被注册进来的用户,如今的注册中心,
redis,zookeeper,都有发布与订阅功能,就是相似此原理
在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。
当数据对象被加上排它锁时,其余的事务不能对它读取和修改。加了共享锁的数据对象能够被其余事务读取,但不能修改。
数据库利用这两 种基本的锁类型来对数据库的事务进行并发控制。
对于UPDATE、DELETE、INSERT语句,Innodb会自动给涉及的数据集加排他锁(X);对于普通SELECT语句,Innodb不会加任何锁。
mysql的共享锁(Share Lock)
Mysql会对查询结果中的每行都加共享锁
若是事务T对数据A加上共享锁后,则其余事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
用法
SELECT 条件 from 表 LOCK IN SHARE MODE;
排他锁(eXclusive Lock)
Mysql会对查询结果中的每行都加排他锁
排他锁又称写锁,若是事务T对数据A加上排他锁后,则其余事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
用法
SELECT 条件 from 表 FOR UPDATE;
innodb默认是行锁 在更改操做自动加上行锁,若是操做的行没有索引那么会自动加上表锁 找到行以后再变行锁
意向锁
意向锁
意向锁是表级锁,其设计目的主要是为了在一个事务中揭示下一行将要被请求锁的类型。InnoDB中的两个表锁:
意向共享锁(IS):表示事务准备给数据行加入共享锁,也就是说一个数据行加共享锁前必须先取得该表的IS锁
意向排他锁(IX):相似上面,表示事务准备给数据行加入排他锁,说明事务在一个数据行加排他锁前必须先取得该表的IX锁。
意向锁是InnoDB自动加的,不须要用户干预。
对于insert、update、delete,InnoDB会自动给涉及的数据加排他锁(X);对于通常的Select语句,InnoDB不会加任何锁,
事务能够经过如下语句给显示加共享锁或排他锁
公平锁、非公平锁
公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得。
非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待。(synchronize)
ReentrantLock锁内部提供了公平锁与分公平锁内部类之分,默认是非公平锁,
可重入锁
Lock lock1 = new ReentrantLock();
可重入锁,也叫作递归锁,指的是同一线程外层函数得到锁以后 ,内层递归函数仍然有获取该锁的代码,但不受影响。反之不可重入锁
使用:tryLock 避免死锁
synchronized:可重入锁
java.util.concurrent.locks.ReentrantLock:可重入锁;
分段锁
ConcurrentHashMap
乐观锁/悲观锁
悲观锁适合写操做很是多的场景,乐观锁适合读操做很是多的场景,不加锁会带来大量的性能提高。
悲观锁在Java中的使用,就是利用各类锁。
乐观锁在Java中的使用,是无锁编程,经常采用的是CAS算法,典型的例子就是原子类,经过CAS自旋实现原子操做的更新。
读写锁:
分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm本身控制的,你只要上好相应的锁便可。若是你的代码只读数据,
能够不少人同时读,但不能同时写,那就上读锁;若是你的代码修改数据,
只能有一我的在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁
参见:https://www.cnblogs.com/zzlp/p/5174745.html
CAS
使用:private static final Unsafe unsafe = Unsafe.getUnsafe();//compareAndSwapInt 简称cas
Compare And Swap.比较并交换.java中的同步器就是基于CAS技术实现的,为何它能保证操做的同步性呢?由于是原子操做的一种,
因此能够在多线程环境下来实现数据的交换操做不被打断.
CAS缺点
1. ABA问题。由于CAS须要在操做值的时候检查下值有没有发生变化,若是没有发生变化则更新,
可是若是一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,可是实际上却变化了。
2. 循环时间长开销大。
3. 只能保证一个共享变量的原子操做。
什么是AQS
AQS(AbstractQueuedSynchronizer),AQS是JDK下提供的一套用于实现基于FIFO等待队列的阻塞锁和相关的同步器的一个同步框架
可见 CountDownLatch 是基于AQS框架来实现的一个同步器.相似的同步器在JUC下还有很多。
java 中的锁:https://www.cnblogs.com/qifengshi/p/6831055.html
、getCurrentSession()与openSession()的区别?
* 采用getCurrentSession()建立的session会绑定到当前线程中,而采用openSession(),建立的session则不会
* 采用getCurrentSession()建立的session在commit或rollback时会自动关闭,而采用openSession(),建立的session必须手动关闭
事务 Spring read-only="true" 只读事务的一些概念
应用场合:
若是你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持SQL执行期间的读一致性;
若是你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询SQL必须保证总体的读一致性,不然,在前条SQL查询以后,后条SQL查询以前,数据被其余用户改变,则该次总体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持。
【注意是一次执行屡次查询来统计某些信息,这时为了保证数据总体的一致性,要用只读事务】
数据库的死锁:
死锁的第一种状况
一个用户A 访问表A(锁住了表A),而后又访问表B;另外一个用户B 访问表B(锁住了表B),而后企图访问表A;这时用户A因为用户B已经锁住表B,
它必须等待用户B释放表B才能继续,一样用户B要等用户A释放表A才能继续,这就死锁就产生了。
死锁的第二种状况
用户A查询一条纪录,而后修改该条纪录;这时用户B修改该条纪录,这时用户A的事务里锁的性质由查询的共享锁企图上升到独占锁,
而用户B里的独占锁因为A 有共享锁存在因此必须等A释放掉共享锁,而A因为B的独占锁而没法上升的独占锁也就不可能释放共享锁,因而出现了死锁
死锁的第三种状况若是在事务中执行了一条不知足条件的update语句,则执行全表扫描,把行级锁上升为表级锁,多个这样的事务执行后,就很容易产生死锁和阻塞。相似的情 况还有当表中的数据量很是庞大而索引建的过少或不合适的时候,使得常常发生全表扫描,最终应用系统会愈来愈慢,最终发生阻塞或死锁。参见:https://uule.iteye.com/blog/2422193