基础
1.JDK 和 JRE 有什么区别
JRE(Java Runtime Enviroment)是Java的运行环境;
JDK(Java Development Kit)又称J2SDK(Java2 Software Development Kit),是Java开发工具包,它提供了Java的开发环境(提供了编译器javac等工具,用于将java文件编译为class文件)和运行环境(提 供了JVM和Runtime辅助包,用于解析class文件使其得到运行)。JDK是整个Java的核心,包括了Java运行环境(JRE),一堆Java工具tools.jar和Java标准类库 (rt.jar)。
2.== 和 equals 的区别是什么
==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同。
==是指对内存地址进行比较 , equals()是对字符串的内容进行比较。
==指引用是否相同, equals()指的是值是否相同。
3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?
两个对象的hashCode()相同,equals()不一定为true;
两个对象的equals为true,则两个对象的hashcode一定为true;
hashCode的存在主要是用于查找的快捷,比如我们常用的HashMap等集合,hashCode用来在散列的存储结构中确定对象的存储地址。
java中所有的对象都有一个父类Object,而Object有一个hashCode方法,Java的所有类都有hashcode方法。
4.final 在 java 中有什么作用?
最终的:
final在java中是修饰符关键字
修饰类:表示类不可以被继承
修饰方法:表示方法不可被子类覆盖,但是可以重载
修饰变量:表示变量一旦被赋值就不可以改变它的值
如果修饰成员变量:在声明的时候就要赋值 或者静态代码块赋值
如果修饰局部变量:局部变量必须程序员显示初始化,使用之前必须赋值。
如果修饰的是基本数据类型:一旦初始化之后就不能更改
如果是引用类型变量:对其初始化之后便不能再让其指向另一个对象,但是引用的值是可以改变的。
为什么局部内部类和匿名内部类只能访问局部final变量:
编译之后会生成两个class文件,Test.class Test1.class
内部类和外部类是同一个级别,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁,就产生一个问题,
外部类的方法结束时,局部变量会被销毁,但内部类对象可能还存在。未解决这种问题就局部变量复制一份作为内部类里的成员变量,当局部变量死亡后,内部类仍然可以访问它,这样就好像延长了局部变量的生命周期。将局部变量复制为内部变量必须为一样的,所以就将局部变量设置为final,对它初始化后,就不让再去修改这个变量,就保证了内部类的成员变量和方法的局部变量一致,这实际上也是一种妥协,使得局部变量与内部类建立的拷贝保持一致。
5. java 中的 Math.round(-1.5) 等于多少?
Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)=-1,如果是Math.round(1.5)则结果为2
6.String 属于基础的数据类型吗
在Java中,数据类型分为引用类型和基本类型,基本类型分为八种
整型:byte,short,int,long
浮点型:float,double
字符型:char
Boolean型:boolean
String不是基本的数据类型,是final修饰的java类,是引用类型。
java引用:强弱软虚引用:
强引用,默认new的都是强引用,不会被回收,内存不足会报异常oom(outofmemoryerror),想回收则将该值复制null
弱引用,用weakreference类表示,jvm清楚一次弱引用清楚一次,弱引用缓存中使用较多
7.java 中操作字符串都有哪些类?它们之间有什么区别?
8.String str="i"与 String str=new String(“i”)一样吗?
内存的分配方式不一样。String str="i"的方式,Java 虚拟机会将其分配到常量池中;而 String str=new String(“i”)方式,则会被分到堆内存中。
堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。
9.如何将字符串反转?
1)StringBuilder(str).reverse()
2)将字符串转为 char[]数组,逐个循环 char[]数组,使用 temp 变量进行值交换
10.String 类的常用方法都有那些?
版本 | 返回类型 | 方法名 | 作用 | 关系 |
---|---|---|---|---|
int | length() | 得到一个字符串的字符个数 | 和长度有关 | |
byte[] | getByte() | 将一个字符串转换成字节数组 | 和数组有关 | |
char[] | toCharArray() | 将一个字符串转换成字符数组 | ||
String | split(String) | 将一个字符串按照指定内容劈开 | ||
boolean | equals() | 判断两个字符串的内容是否一样 | 和判断有关 | |
boolean | equalsIsIgnoreCase(String) | 忽略太小写的比较两个字符串的内容是否一样 | ||
boolean | contains(String) | 判断一个字符串里面是否包含指定的内容 | ||
boolean | startsWith(String) | 判断一个字符串是否以指定的内容开头 | ||
boolean | endsWith(String) | 判断一个字符串是否以指定的内容结尾 | ||
String | toUpperCase() | 将一个字符串全部转换成大写 | 和改变内容有关 | |
String | toLowerCase() | 将一个字符串全部转换成小写 | ||
String | replace(String,String) | 将某个内容全部替换成指定内容 | ||
String | replaceAll(String,String) | 将某个内容全部替换成指定内容,支持正则 | ||
String | repalceFirst(String,String) | 将第一次出现的某个内容替换成指定的内容 | ||
String | substring(int) | 从指定下标开始一直截取到字符串的最后 | ||
String | substring(int,int) | 从下标x截取到下标y-1对应的元素 | ||
String | trim() | 去除一个字符串的前后空格 | ||
char | charAt(int) | 得到指定下标位置对应的字符 | 和位置有关 | |
int | indexOf(String) | 得到指定内容第一次出现的下标 | ||
int | lastIndexOf(String) | 得到指定内容最后一次出现的下标 |
11.抽象类必须要有抽象方法吗?
1.如果一个类使用了abstract关键字修饰,那么这个类就是一个抽象类。
2.抽象类可以没有抽象方法
3.一个类如果包含抽象方法,那么这个类必须是抽象类,否则编译就会报错。
4.最关键的一点就是如果一个类是抽象类,那么这个类是不能被实例化的,抽象类只能用其子类(该子类不能是抽象类)去创建新对象,抽象类可写抽象方法声明,但不用实现,抽象类不能被final修饰
1)抽象类主要是用来进行类型隐藏
2)抽象体派生扩展模块的行为功能
12.接口和抽象类有什么区别?
抽象类和接口都不能直接实例化。如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
抽象类要被子类继承,接口要被类实现。
接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现。
接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
接口可以继承接口,并且可多继承接口,但类只能单—继承。
接口可以通过匿名内部类实例化。接口是对动作的抽象,抽象类是对根源的抽象。抽象类表示的是,这个对象是什么。而接口表示的是,这个对象能做什么。
抽象方法要被实现,所以不能是静态的,也不能是私有的。
13.java 中 IO 流分为几种?
流是从一端到另一端,连接了源头和目的地。IO流可以理解为连接程序与文件/数组/网络连接/数据库。
(1)按流向分类:
输入流
输出流
(2)按处理数据不同分类:
字节流:二进制,可以处理一切文件,包括:纯文本、doc、音频、视频等。
字符流:文本文件,只能处理纯文本。
(3)按功能不同分类:
节点流:包裹源头。
处理流:增强功能,提高性能。
方式分类:
对象分类:
14.BIO、NIO、AIO 有什么区别?
BIO(同步阻塞)
服务端需要对客户端的每个请求处理完成后 才会继续接受客户端的请求
客户端也会等待服务端处理完请求后才会发送请求
通常会使用多线程去处理 因为BIO每个连接一个单独的线程
NIO(同步非阻塞)
NIO使用单线程或者只使用少量的多线程,一个请求一个线程,多个连接共用一个线程。
(即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。)
(可以使用资源池或者队列等手段实现异步的处理)
AIO(异步非阻塞)
AIO的读写方法都是异步的 完成后会主动调用回调函数
15.Files的常用方法都有哪些?
Files.exists():检测文件路径是否存在。
Files.createFile():创建文件。
Files.createDirectory():创建文件夹。
Files.delete():删除一个文件或目录。
Files.copy():复制文件。
Files.move():移动文件。
Files.size():查看文件个数。
Files.read():读取文件。
Files.write():写入文件。
容器
1.java 容器都有哪些?
-Collection大类
--List字类
ArrayList
LinkedList
Vector
Stack
--Set字类
HashSet
LinkedHashSet
TreeSet
-Map大类
HashMap(线程不安全的)
LinkedHashMap(线程不安全的,按输入顺序的)
TreeMap(线程不安全的)
ConcurrentHashMap(线程安全的)
Hashtable(线程安全的)
2.Collection 和 Collections 有什么区别?
Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。
Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
3.List、Set、Map 之间的区别是什么?
List和Set是存储单列数据的集合,Map是存储键值对这样的双列数据的集合;
List中存储的数据是有顺序的,并且值允许重复;Map中存储的数据是无序的,它的键是不允许重复的,但是值是允许重复的;Set中存储的数据是无顺序的,并且不允许重复,但元素在集合中的位置是由元素的hashcode决定,即位置是固定的(Set集合是根据hashcode来进行数据存储的,所以位置是固定的,但是这个位置不是用户可以控制的,所以对于用户来说set中的元素还是无序的)。
4.HashMap 和 Hashtable 有什么区别?
HashMap 基于 hash 表的 Map 接口实现,非线程安全,高效,支持 null 值和 null键;
Hashtable 线程安全,低效,不支持 null 值和 null 键;
5.如何决定使用 HashMap 还是 TreeMap?
HashMap是通过hashcode()对其内容进行快速查找的;元素是没有顺序的;用于插入,删除,定位元素
TreeMap基于红黑树实现的,所有的元素都是有某一固定顺序的,适用于按自然顺序或自定义顺序遍历键(key)
6.说一下 HashMap 的实现原理?
HashMap是采用链表解决Hash冲突,因为是链表结构,那么就很容易形成闭合的链路,这样在循环的时候只要有线程对这个HashMap进行get操作就会产生死循环。
hashMap扩容:
扩容就是重新计算容量,向hashMap不停的添加元素,当hashMap无法装载新的元素,对象将需要扩大容量,以便装入更多的元素。
这里将其设置为长度为 8,扩容临界点 8 * 0.75 = 6 主要是为了画图 (hashMap默认容量是16)
initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader factor)默认为0.75, 如果暂时无法确定初始值大小,请设置为16(即默认值)
7.说一下 HashSet 的实现原理?
HashSet的本质是一个"没有重复元素"的集合,它是通过HashMap实现的。
8.ArrayList 和 LinkedList 的区别是什么?
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动。
9.如何实现数组和 List 之间的转换?
1)For循环,放入集合里
2)Arrays.aslist(array1);
3)Collections.addAll(list,array1);
10.ArrayList 和 Vector 的区别是什么?
ArrayList 是线程不安全的,Vector是线程安全的,默认ArrayList 扩容1.5,Vector扩容2倍,ArrayList 默认创建ArrayList长度是0,初始化长度为10
11.Array 和 ArrayList 有何区别?
数组和集合区别:
Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
Array大小是固定的,ArrayList的大小是动态变化的。
ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator等等。
迭代器遍历:
12.在 Queue 中 poll()和 remove()有什么区别?
remove() ,如果队列为空的时候,则会抛出异常,而poll()只会返回null
同理,add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。
peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element()方法会抛出NoSuchElementException异常。
13.Iterator 和 ListIterator 有什么区别?
14.怎么确保一个集合不能被修改?
Collections.unmodifiableCollection(Collection c)
Java Web
1.jsp 和 servlet 有什么区别?
servlet是Java编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。
jsp是servlet的扩展,更善于展示页面,没有内置对象,通过httpServletRequest,httpServletResponse,httpServlet对象,编译后是servlet,
servlet 更适合做逻辑处理,完全与html分离开来,用来做控制器
jsp是java+html的jsp文件
2.jsp 有哪些内置对象?作用分别是什么?
3.jsp的四大作用域分别是
1、application 作用域
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。整个应用是指从应用启动,到应用结束。我们没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。 application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
Object getAttribute(String name) //从application中获取信息;
void setAttribute(String name,Object value) //向application作用域中设置信息。
2、session作用域
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。
Object HttpSession.getAttribute(String name) //从session中获取信息。
void HttpSession.setAttribute(String name,Object value)//向session中保存信息。
HttpSessionHttpServletRequest.getSessio() //获取当前请求所在的session的对象。
session从浏览器发出第一个HTTP请求即可认为会话开始。但结束就不好判断了,因为浏览器关闭时并不会通知服务器,所以只能通过如下这种方法判断:如果一定的时间内客户端没有反应,则认为会话结束。Tomcat的默认值为120分钟,但这个值也可以通过HttpSession的setMaxInactiveInterval()方法来设置:
void setMaxInactiveInterval(int interval)
如果想主动让会话结束,例如用户单击“注销”按钮的时候,可以使用 HttpSession 的 invalidate()方法,用于强制结束当前session:void invalidate()
Session删除的时间是:
Session超时:超时指的是连续一定时间服务器没有收到该Session所对应客户端的请求,并且这个时间超过了服务器设置的Session超时的最大时间。
程序调用HttpSession.invalidate()
服务器关闭或服务停止
注意:
访问*.html的静态资源因为不会被编译为Servlet,也就不涉及session的问题。
当JSP页面没有显式禁止session的时候,在打开浏览器第一次请求该jsp的时候,服务器会自动为其创建一个session,并赋予其一个sessionID,发送给客户端的浏览器。
由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。
session不会应该浏览器的关闭而删除,只能通过以上三种方式删除。
session存放在哪里?-----------服务器端的内存中。
3、Request作用域
request里的变量可以跨越forward前后的两页。但是只要刷新页面,它们就重新计算了。
请求转发:servlet. getRequestDispatcher("new.jsp").forward(req,resp);
注意:
1、转发是服务器行为,而重定向是客户端行为。
2、无论在服务器上如何转发,浏览器地址栏中显示的仍然是最初那个Servlet的地址。
4、page作用域
page对象的作用范围仅限于用户请求的当前页面
request和page的生命周期都是短暂的,它们之间的区别:一个request可以包含多个page页(include,forward及filter)。
4.Session和Cookie的区别?
1、数据存储位置:cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、安全性:cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3、服务器性能:session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、数据大小:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、信息重要程度:可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
5.说一下 session 的工作原理?
1.session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。
一般默认情况下,在会话中,服务器存储 session 的 sessionid 是通过 cookie 存到浏览器里。
2.如果浏览器禁用了 cookie,浏览器请求服务器无法携带 sessionid,服务器无法识别请求中的用户身份,session失效。
但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。
通过url重写,把 sessionid 作为参数追加的原 url 中,后续的浏览器与服务器交互中携带 sessionid 参数。
服务器的返回数据中包含 sessionid,浏览器发送请求时,携带 sessionid 参数。
通过 Http 协议其他 header 字段,服务器每次返回时设置该 header 字段信息,浏览器中 js 读取该 header 字段,请求服务器时,js设置携带该 header 字段。
6.spring mvc 和 struts 的区别是什么?
spring mvc入口servlet,属于基于方法设计
struts是filter过滤器,基于类实现,
性能上mvc更快,处理ajax的请求mvc方便 @ResponseBody ,配置文件mvc更少一点,感觉除非是项目版本特别要求,mvc比struts更主流一些,相应学习成本也低一些。
7.如何避免 sql 注入?
使用mybatis用#{}预编译,替代${},
设计上过滤关键词,隐匿数据库命名及作用关联性,对于常用的方法加以封装,避免直接暴露sql语句,打开magic_quotes_gpc=off,默认是关闭的,它打开后自动把用户提交的sql语句进行转换(加上\转义),这对防止sql注入有很大作用;on
8.什么是 XSS 攻击,如何避免?
即跨站脚本攻击,也就是代码注入攻击,攻击者往 web 页面里插入恶意的 HTML 代码(Javascript、css、html 标签等),当用户浏览该页面时,嵌入其中的 HTML 代码会被执行,从而达到恶意攻击用户的目的.
XSS主要分为两大类:非持久型攻击、持久型攻击。
- 非持久型攻击(反射型XSS, DOM-based 型):经过后端,不经过数据库;
- 持久型攻击(存储型XSS):经过后端,经过数据库。
常见的 XSS 攻击有三种:反射型、DOM-based 型、存储型。
避免:在web页面上,将用户输入的数据都进行转译:对用户的输入进行过滤,如对& < > " ' /等进行转义;
获取用户的输入,不用innerHtml,用innerText
9.什么是 CSRF 攻击,如何避免?
CSRF:Cross-Site Request Forgery(中文:跨站请求伪造),可以理解为攻击者盗用了你的身份,以你的名义发送恶意请求,比如:以你名义发送邮件、发消息、购买商品,虚拟货币转账等。
防御手段:
验证请求来源地址;
关键操作添加验证码;
在请求地址添加 token 并验证。
异常
1. throw 和 throws 的区别?
共同点
两者在抛出异常时,他们只管把异常抛出,并不处理异常,由调用者负责处理。
区别
(1)throw语句总是出现在方法体里面,用来抛出一个异常,表示在这个地方就有一个异常出现,程序会在throw后面立即终止,它后面的语句将执行不到。
而throws是出现在方法名的后面,用来把方法中出现的异常抛出去给调用者处理。
当方法中出现了异常自己不想处理,那么可以使用throws在方法名后面将异常抛出
去给调用者处理。
(2)throw只能抛出一个异常对象。
而throws可以在方法名后面一次性抛出多个异常,多个异常对象以逗号分隔。
(3)throw抛出异常时,调用它的方法时可以不声明或不捕获,虽编译器不会报错,但是从开发角度说还是要使用try-catch来处理这个异常。
而throws抛出异常时,调用它的方法时也要声明抛出异常或者进行try-catch捕获,否则编译会报错。
2.final、finally、finalize 有什么区别?
final 用于申明属性,方法和类,表示属性不可变,方法不可以被覆盖,类不可以被继承。
finally 是异常处理语句结构中,表示总是执行的部分。
finallize
表示是object类一个方法,在垃圾回收机制中执行的时候会被调用被回收对象的方法。允许回收此前未回收的内存垃圾。所有object都继承了finalize()方法
3.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
https://blog.csdn.net/qq_36484670/article/details/105735458
4.常见的异常类有哪些?
*(1)NullPointerException 当应用程序试图访问空对象时,则抛出该异常。
*(2)SQLException 提供关于数据库访问错误或其他错误信息的异常。
*(3)IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
*(4)NumberFormatException当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
*(5)FileNotFoundException当试图打开指定路径名表示的文件失败时,抛出此异常。
*(6)IOException当发生某种I/O异常时,抛出此异常。此类是失败或中断的I/O操作生成的异常的通用类。
(7)ClassCastException当试图将对象强制转换为不是实例的子类时,抛出该异常。
(8)ArrayStoreException试图将错误类型的对象存储到一个对象数组时抛出的异常。
*(9)IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
(10)ArithmeticException当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
(11)NegativeArraySizeException如果应用程序试图创建大小为负的数组,则抛出该异常。
*(12)NoSuchMethodException无法找到某一特定方法时,抛出该异常。
*(13)SecurityException由安全管理器抛出的异常,指示存在安全侵犯。
(14)UnsupportedOperationException当不支持请求的操作时,抛出该异常。
(15)RuntimeExceptionRuntimeException 是那些可能在Java虚拟机正常运行期间抛出的异常的超类。
网络
1.http 响应码 301 和 302 代表的是什么?有什么区别?
301 永久重定向,302临时重定向,多用301,302容易出现网址URL 劫持
2.forward 和 redirect 的区别?
- 从地址栏显示来说:
1)forword是服务器内部的重定向,服务器直接访问目标地址的 url网址,把里面的东西读取出来,但是客户端并不知道,因此用forward的话,客户端浏览器的网址是不会发生变化的。
2)redirect是服务器根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,所以地址栏显示的是新的地址。
2。 从数据共享来说:
1)由于在整个定向的过程中用的是同一个request,因此forward会将request的信息带到被重定向的jsp或者servlet中使用。即可以共享数据
2)redirect不能共享
- 从运用的地方来说
1)forword 一般用于用户登录的时候,根据角色转发到相应的模块
2) redirect一般用于用户注销登录时返回主页面或者跳转到其他网站
4。 从效率来说:
1)forword效率高,而redirect效率低,forword只有一次请求;而redirect有两次请求,
- 从本质来说:
forword转发是服务器上的行为,而redirect重定向是客户端的行为。
3.简述 tcp 和 udp的区别?
https://zhuanlan.zhihu.com/p/24860273/
4.说一下 tcp 粘包是怎么产生的?
现象:发送方发送的多个数据包,到接收方缓冲区首尾相连,粘成一包,被接收。
原因:TCP 协议默认使用 Nagle 算法可能会把多个数据包一次发送到接收方。应用程读取缓存中的数据包的速度小于接收数据包的速度,缓存中的多个数据包会被应用程序当成一个包一次读取。
处理方法:发送方使用 TCP_NODELAY 选项来关闭 Nagle 算法,数据包增加开始符和结束,应用程序读取、区分数据包。在数据包的头部定义整个数据包的长度,应用程序先读取数据包的长度,然后读取整个长度的包字节数据,保证读取的是单个包且完整。
5.OSI 的七层模型都有哪些?
OSI中的上面4层(应用层、表示层、会话层、传输层)为高层,定义了程序的功能;下面3层(网络层、数据链路层、物理层)为底层,主要是处理面向网络端到端的数据流。
6.get和set请求区别?
7.如何实现跨域
jsonp/nginx/cors
vue前端使用axios实现跨域,后端使用nginx代理,cors策略
8.jsonp原理
简单点说,jsonp是一种跨域通信的手段,它的原理其实很简单:
首先是利用script标签的src属性来实现跨域。
通过将前端方法作为参数传递到服务端,然后由服务的注入参数之后再返回,实现服务器向客户端通信。
由于使用script标签的src属性,因此只支持get方法。
设计模式
1.说一下你熟悉的设计模式?
创建型模式共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
1、简单工厂模式
主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类。使用简单工厂模式,我们只需要知道具体的产品型号就可以创建一个产品。
缺点:工厂类集中了所有产品类的创建逻辑,如果产品量较大,会使得工厂类变的非常臃肿。
4、单例模式
单例模式顾名思义,保证一个类仅可以有一个实例化对象,并且提供一个可以访问它的全局接口。实现单例模式必须注意一下几点:
单例类只能由一个实例化对象。
单例类必须自己提供一个实例化对象。
单例类必须提供一个可以访问唯一实例化对象的接口。
单例模式分为懒汉和饿汉两种实现方式。
2.简单工厂和抽象工厂有什么区别?
Spring/Spring MVC
1.为什么要使用 spring?
Spring是一个轻量级的控制反转和面向切面的容器框架
2.解释一下什么是 aop?
AOP即面向切面编程,是OOP编程的有效补充。
使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。
从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
3.解释一下IOC
IOC控制反转
是spring的核心,贯穿始终,所谓IOC ,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。所有的类都会在spring容器中登记,告诉spring你是个什么,你需要什么,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
DI依赖注入
ioc就是容器,di就是注入这一行为,那么di确实就是ioc的具体功能的实现。而ioc则是di发挥的平台和空间。所以说。ioc和di即是相辅相成的拍档。他们都是为了实现解耦而服务的
4.spring模块
1、核心模块
SpringCore模块是Spring的核心容器,它实现了IOC模式,提供了Spring框架的基础功能。此模块中包含的BeanFactory类是Spring的核心类,负责JavaBean的配置与管理。它采用Factory模式实现了IOC即依赖注入。
2、Context模块
SpringContext模块继承BeanFactory(或者说Spring核心)类,并且添加了事件处理、国际化、资源装载、透明装载、以及数据校验等功能。它还提供了框架式的Bean的访问方式和很多企业级的功能,如JNDI访问、支持EJB、远程调用、集成模板框架、Email和定时任务调度等。
3、AOP模块
Spring集成了所有AOP功能。通过事务管理可以使任意Spring管理的对象AOP化。Spring提供了用标准Java语言编写的AOP框架,它的大部分内容都是基于AOP联盟的API开发的。它使应用程序抛开EJB的复杂性,但拥有传统EJB的关键功能。
4、DAO模块
DAO是DataAccessObject的缩写,DAO模式思想是将业务逻辑代码与数据库交互代码分离,降低两者耦合。通过DAO模式可以使结构变得更为清晰,代码更为简洁。DAO模块提供了JDBC的抽象层,简化了数据库厂商的异常错误(不再从SQLException继承大批代码),大幅度减少代码的编写,并且提供了对声明式事务和编程式事务的支持。
5、ORM映射模块
SpringORM模块提供了对现有ORM框架的支持,各种流行的ORM框架已经做得非常成熟,并且拥有大规模的市场,Spring没有必要开发新的ORM工具,它对Hibernate提供了完美的整合功能,同时也支持其他ORM工具。注意这里Spring是提供各类的接口(support),目前比较流行的下层数据库封闭映射框架,如ibatis,Hibernate等。
6、Web模块
此模块建立在SpringContext基础之上,它提供了Servlet监听器的Context和Web应用的上下文。对现有的Web框架,如JSF、Tapestry、Structs等,提供了集成。Structs是建立在MVC这种公认的好的模式上的,Struts在M、V和C上都有涉及,但它主要是提供一个好的控制器和一套定制的标签库上,也就是说它的着力点在C和V上,因此,它天生就有MVC所带来的一系列优点,如:结构层次分明,高可重用性,增加了程序的健壮性和可伸缩性,便于开发与设计分工,提供集中统一的权限控制、校验、国际化、日志等等。
7、MVC模块
https://www.jianshu.com/p/8b8fe1ec57e5
SpringWebMVC模块建立在Spring核心功能之上,这使它能拥有Spring框架的所有特性,能够适应多种多视图、模板技术、国际化和验证服务,实现控制逻辑和业务逻辑的清晰分离。实践证明,MVC模式为大型程序的开发及维护提供了巨大的便利。
5.spring有哪些注入方式?
构造方法注入
set方法注入
注解注入
构造方法注入和set注入都是通过java的反射技术得以实现的。
6.spring 中的 bean 是线程安全的吗?
1、在@Controller/@Service等容器中,默认情况下,scope值是单例-singleton的,也是线程不安全的。
2、尽量不要在@Controller/@Service等容器中定义静态变量,不论是单例(singleton)还是多实例(prototype)他都是线程不安全的。
3、默认注入的Bean对象,在不设置scope的时候他也是线程不安全的。
4、一定要定义变量的话,用ThreadLocal来封装,这个是线程安全的
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 自动装配 bean 有哪些方式?
spring 配置文件中 节点的 autowire 参数可以控制 bean 自动装配的方式
default - 默认的方式和 “no” 方式一样
no - 不自动装配,需要使用 节点或参数
byName - 根据名称进行装配
byType - 根据类型进行装配
constructor - 根据构造函数进行装配
9.spring 事务实现方式有哪些?
(1)编程式事务管理对基于 POJO 的应用来说是唯一选择。我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。
(2)基于 TransactionProxyFactoryBean的声明式事务管理
(3)基于 @Transactional 的声明式事务管理
(4)基于Aspectj AOP配置事务
10.说一下 spring 的事务隔离?
https://blog.csdn.net/jiahao1186/article/details/122023924
11.说一下 spring mvc 运行流程?
https://www.jianshu.com/p/8b8fe1ec57e5
11.spring mvc 有哪些组件?
12.常用注解
https://www.jianshu.com/p/5efda4f58bcf
Spring Boot
1.什么是springboot
全新框架,其设计目的是用来简化Spring应用的创建、运行、调试、部署等。使用Spring Boot可以做到专注于Spring应用的开发,而无需过多关注XML的配置。
1、 可独立运行的Spring项目:Spring Boot可以以jar包的形式独立运行。
2、 内嵌的Servlet容器:Spring Boot可以选择内嵌Tomcat、Jetty或者Undertow,无须以war包形式部署项目。
3、 简化的Maven配置:Spring提供推荐的基础 POM 文件来简化Maven 配置。
4、 自动配置Spring:Spring Boot会根据项目依赖来自动配置Spring 框架,极大地减少项目要使用的配置。
5、 提供生产就绪型功能:提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查。
6、 无代码生成和xml配置:Spring Boot不生成代码。完全不需要任何xml配置即可实现Spring的所有配置。
2.Spring Boot 的核心配置文件
Spring Boot 的核心配置文件是 application 和 bootstrap 配置文件。
application 配置文件这个容易理解,
主要用于 Spring Boot 项目的自动化配置。
bootstrap 配置文件有以下几个应用场景。
使用 Spring Cloud Config 配置中心时,
这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性
来加载外部配置中心的配置信息;
3.Spring Boot 的配置文件有哪几种格式?
主要有.properties 和 .yml格式,它们的区别主要是书写格式不同。另外,.yml 格式不支持 @PropertySource 注解导入配置。
4.spring boot 有哪些方式可以实现热部署?
引入spring-boot-devtools依赖,idea的热部署功能,Jrebel热部署插件
5. JPA与Hibernate 的区别
JPA和Hibernate之间的最大的区别是:
- JPA是一个规范,不是框架
- Hibernate是JPA的实现
也可以简单的理解为JPA是标准接口,Hibernate是实现。
Spring Data JPA是什么?以及相关概述
其次Spring也想要做持久化相关工作,并且已有Spring-data-**这一系列包(Spring-data-jpa,Spring-data-template,Spring-data-mongodb等)。
其中Spring-data-jpa即代表着,Spring框架对JPA的整合。
Spring Data JPA是在JPA规范的基础下提供了Repository层的实现。
Mybatis
1.mybatis 有几种分页方式?
一.借助数组进行分页(逻辑分页)
二.借助Sql语句进行分页(物理分页)
三.拦截器分页 (物理分页) 通过拦截器给sql语句末尾加上limit语句来查询,一劳永逸最优
四.RowBounds实现分页 (逻辑分页)
2.mybatis 有哪些执行器(Executor)?
1、SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
2、ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。
3、BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。
3.mybatis 分页插件的实现原理是什么?
PageHelper插件
在MyBatis内部定义了一个拦截器接口
所有的插件都要实现该接口,来,我们看看这个接口的定义
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
那么其中一个关键的方法就是intercept,从而实现拦截
分页插件的原理就是使用MyBatis提供的插件接口,实现自定义插件,在插件的拦截方法内,拦截待执行的SQL,然后根据设置的dialect(方言),和设置的分页参数,重写SQL ,生成带有分页语句的SQL,执行重写后的SQL,从而实现分页
所以原理还是基于拦截器
4. mybatis sql 动态标签总结
https://blog.csdn.net/m0_59259076/article/details/122597408
RabbitMQ
Zookeeper
1.zookeeper 是什么?
Zookeeper是一个分布式协调服务;
管理其他框架;
Zookeeper集群的角色: Leader 和 follower (Observer)
只要集群中有半数以上节点存活,集群就能提供服务
2.zookeeper 都有哪些功能?
数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列 等功能
https://www.cnblogs.com/z-dk/p/14674358.html
3.zookeeper 有几种部署模式?
单机模式、伪集群模式、集群模式。
4.zookeeper 怎么保证主从节点的状态同步?
Zookeeper 的核心是原子广播机制,这个机制保证了各个 server 之间的同步。 实现这个机制的协议叫做 Zab 协议。Zab 协议有两种模式,它们分别是恢复模 式和广播模式。
恢复模式
当服务启动或者在领导者崩溃后, Zab 就进入了恢复模式,当领导者被选举出 来,且大多数 server 完成了和 leader 的状态同步以后,恢复模式就结束了。状 态同步保证了 leader 和 server 具有相同的系统状态。
广播模式
一旦 leader 已经和多数的 follower 进行了状态同步后,它就可以开始广播消息 了,即进入广播状态。这时候当一个 server 加入 ZooKeeper 服务中,它会在 恢复模式下启动, 发现 leader ,并和 leader 进行状态同步。待到同步结束,它也参与消息广播。 ZooKeeper 服务一直维持在 Broadcast 状态,直到 leader 崩溃了或者 leader 失去了大部分的 followers 支持。
5.集群中为什么要有主节点?
有些场景只需要一台服务执行,可使用主节点完成;其他机器共享数据,减少重复计算,提高集群性能。也有集群是主写从读(写入少的情况,可提高整体性能)
采用奇数个的节点:防止由脑裂造成的集群不可用。在容错能力相同的情况下,奇数台更节省资源。
6.集群中有 3 台服务器,其中一个节点宕机,这个时候 zookeeper 还可以使用吗?
超过半数是正常的就可以使用
7.说一下 zookeeper 的通知机制?
客户端端会对某个 znode 建立一个 watcher 事件,当该 znode 发生变化时,这些客户端会收到 zookeeper 的通知,然后客户端可以根据 znode 变化来做出业务上的改变。
MySql
1.数据库的三范式是什么?
1、第一范式(确保每列保持原子性)
2、第二范式(确保表中的每列都和主键相关)
3、第三范式(确保每列都和主键列直接相关,而不是间接相关)
2.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几?
一般情况下,我们创建的表的类型是InnoDB,如果新增一条记录(不重启mysql的情况下),这条记录的id是8;但是如果重启(文中提到的)MySQL的话,这条记录的ID是6。因为InnoDB表只把自增主键的最大ID记录到内存中,所以重启数据库或者对表OPTIMIZE操作,都会使最大ID丢失。
但是,如果我们使用表的类型是MylSAM,那么这条记录的ID就是8。因为MylSAM表会把自增主键的最大ID记录到数据文件里面,重启MYSQL后,自增主键的最大ID也不会丢失。
3.说一下 ACID 是什么?
数据库事务的ACID
原子性 > 整个事务的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节
一致性 > 在事务开始和事务结束以后,数据库的一致性约束没有被破坏
隔离性 > 数据库允许多个并发事务同时对数据进行读写和修改能力,访问数据不受未提交事务影响
持久性 > 事务处理结束后对数据的修改就是永久的,即便系统故障也不会丢失
4.char 和 varchar 的区别是什么?
1、char 的长度是不可变的,varchar的长度是可变的。
2、定义一个char[10]和varchar[10],如果存进去的是‘abcd’,那么char所占的长度依然为10,除了字符‘abcd’外,后面跟六个空格,而varchar就立马把长度变为4了,取数据的时候,char类型的要用trim()去掉多余的空格,而varchar是不需要的,
3、char的存取数度还是要比varchar要快得多,因为其长度固定,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以难免会有多余的空格占位符占据空间,可谓是以空间换取时间效率,而varchar是以空间效率为首位的。
4、char的存储方式是,对英文字符(ASCII)占用1个字节,对一个汉字占用两个字节;varchar的存储方式是,对每个英文字符占用2个字节,汉字也占用2个字节,两者的存储数据都非unicode的字符数据。
5.float 和 double 的区别是什么?
float属于单精度型浮点数据。
double属于双精度型浮点数据。
2、指数范围不同
float的指数范围为-127~128。
double而double的指数范围为-1023~1024
3、表达式指数位不同
float的表达式为1bit(符号位)+8bits(指数位)+23bits(尾数位)
double的表达式为1bit(符号位)+ 11bits(指数位)+ 52bits(尾数位)
4、占用内存空间不同
float占4个字节(32位)内存空间,其数值范围为3.4E-38~3.4E+38。
double占8 个字节(64位)内存空间,其数值范围为1.7E-308~1.7E+308。
5、有效位数不同
float只能提供七位有效数字。
double可提供16位有效数字。
7.mysql 的内连接、左连接、右连接有什么区别?
8.mysql 索引是怎么实现的?
9.怎么验证 mysql 的索引是否满足需求?
explain select * from tablename where type =1
https://blog.csdn.net/weixin_34255793/article/details/92359315
10.说一下数据库的事务隔离?
以 MySQL 为例,数据库的事务隔离是在 MySQL. ini 配置文件里添加的,在文件的最后添加:
transaction-isolation = REPEATABLE-READ
1、READ-UNCOMMITTED:未提交读
最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)。
2、READ-COMMITTED:提交读
一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)。
3、REPEATABLE-READ:可重复读
默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)。
4、SERIALIZABLE:序列化
代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
脏读 :表示一个事务能够读取另一个事务中还未提交的数据。比如,某个事务尝试插入记录 A,此时该事务还未提交,然后另一个事务尝试读取到了记录 A。
不可重复读 :是指在一个事务内,多次读同一数据。
幻读 :指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录,但是第二次同等条件下查询却有 n+1 条记录,这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。
11.说一下 mysql 常用的引擎?
一 、Innodb
支持事务,是事务安全的,提供行级锁与外键约束,有缓冲池,用于缓冲数据和索引。
适用场景:用于事务处理,具有ACID事物支持,应用于执行大量的insert和update操作的表。
二 、MyISAM
不支持事务,不支持外键约束,不支持行级锁,操作时需要锁定整张表,不过会保存表的行数,所以当执行select count(*) from tablename时执行特别快。
适用场景:用于管理非事务表,提供高速检索及全文检索能力,适用于有大量的select操作的表,如 日志表
三 、MEMORY
使用存在于内存中的内容创建表,每一个memory只实际对应一个磁盘文件。因为是存在内存中的,所以memory访问速度非常快,而且该引擎使用hash索引,可以一次定位,不需要像B树一样从根节点查找到支节点,所以精确查询时访问速度特别快,但是非精确查找时,比如like,这种范围查找,hash就起不到作用了。另外一旦服务关闭,表中的数据就会丢失,因为没有存到磁盘中。
适用场景:主要用于内容变化不频繁的表,或者作为中间的查找表。对表的更新要谨慎因为数据没有被写入到磁盘中,服务关闭前要考虑好数据的存储
四、 MERGE
MERGE存储引擎把一组MyISAM数据表当做一个逻辑单元来对待,让我们可以同时对他们进行查询。构成一个MERGE数据表结构的各成员MyISAM数据表必须具有完全一样的结构。每一个成员数据表的数据列必须按照同样的顺序定义同样的名字和类型,索引也必须按照同样的顺序和同样的方式定义。
除了便于同时引用多个数据表而无需发出多条查询,MERGE数据表还提供了以下一些便利。
MERGE数据表可以用来创建一个尺寸超过各个MyISAM数据表所允许的最大长度逻辑单元
你看一把经过压缩的数据表包括到MERGE数据表里。比如说,在某一年结束之后,你应该不会再往相应的日志文件里添加记录,所以你可以用myisampack工具压缩它以节省空间,而MERGE数据表仍可以像往常那样工作
12.说一下 mysql 的行锁和表锁?
https://wenku.baidu.com/view/54212dd7f405cc1755270722192e453611665b49.html
13.说一下乐观锁和悲观锁?
https://zhuanlan.zhihu.com/p/31537871