一、Java基础
1. Java语言的特点?
- 面向对象;
- 可靠性,安全性;
- 支持多线程;
- 跨平台运行;
- 支持网络编程;
- 执行时采用编译+解释的方式;
2. 重写和重载的区别?
重写:重载:发生在子类继承父类时,在子类中重写父类的某个方法用于对父类的方法重新定义。发生在同一个类中,多个方法之间方法名相同除访问权限和异常抛出外,方法的声明和父类某个方法的声明必须一致;方法的参数类型、个数、顺序至少有一项不同。重写的方法返回值范围、抛出的异常范围小于等于父类;方法的重载用于执行不同的处理逻辑。子类的访问权限必须大于等于父类中方法的权限;方法重载的返回值和修饰符可以不相同;父类中被private、final、static修饰的方法不能被重写;构造方法也可以重载;构造方法不能重写。好处:方法名复用好处:实现多态。
3. 抽象类和接口的区别?
接口:抽象类:是一种规范,使用interface来定义的;是一个类,使用abstract来定义的;用于被实现类实现;抽象类用于被子类继承;接口中只能存在抽象方法和常量成员(JDK1.8以后,可以存在默认方法和静态方法);抽象类中可以存在抽象方法,也可以存在非抽象方法;接口没有构造器;抽象类中有构造器接口中的访问权限必须为public。抽象类中的方法的访问权限是任意的;一个类可以实现多个接口一个类只能继承一个类
4. java中操作字符串都有那些类?它们之间有什么区别?
- String
- StringBuffer
- StringBuilder
区别看下面的
5. String、StringBuilder和StringBuffer的区别?
String是final修饰的,不可变,每次对String类型进行修改时,都会产生新的String对象,内存浪费比较大。因为不可变所以线程安全。
StringBuilder可变字符串 方法中没有同步锁所以是非线程安全的 可以直接在字符串对象本身上进行操作。
StringBuffer可变字符串 对其中的方法或者调用的方法加了同步锁所以是线程安全的 可以直接在字符串对象本身上进行操作。
性能:StringBuilder>StringBuffer>String
如何选择:
字符串少量修改:String
单线程频繁修改字符串:StringBuilder
多线程使用共享变量时使用StringBuffer
6. 为什么会用到缓冲流?
实际的IO操作如果不使用缓冲流,就会每读一次,实际写一次。效率比较慢一些。
因为内存读写速度比硬盘读写速度要快,在使用缓冲流后,内存读取到的东西暂时放在缓冲区中,然后硬盘一次性读取完,减少对硬盘的IO操作,降低硬盘的读取次数提高每次读取的内容。
7. 面向过程和面向对象的区别?
面向过程:面向过程性能比面向对象高。因为类调用时需要实例化,开销比较大,比较消耗资源,所以当性能是最重要的考量因素的时候,比如单片机、嵌入式开发、Linux等一般采用面向过程开发。
面向对象:以模块之间相互调用的一个关系为主,易维护、易复用、易扩展。面向对象有封装、继承、多态的特性。设计的系统耦合低。
8. 什么是线程池,数据库连接池和字符串常量池
三者都是为了提高复用性。
- 线程池:主要用于创建并管理线程,相比单一的创建能够降低线程创建和销毁造成的系统开销。提高相应速度,任务达到时,可以直接从线程池中获取线程执行。提高线程的客观理性,线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源还会降低系统稳定性。
- 数据库连接池:为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。重复使用一个现有的数据库连接,而不是再重新建立一个。
- 字符串常量池:JVM为提高性能和减少内存开销,避免字符串对象的重复创建,维护了一块特殊内存空间,用于保护字符串常量,在JDK1.7之后,字符串常量池已经从方法区移到Heap堆区。
9. List、Set、Map接口的区别?
List集合:存储的元素是有序的、可存放重复数据、可排序的集合。
Set集合:存储的元素是无序的、不可存放重复数据,若排序需要使用TreeSet实现。
Map集合:使用键值对(key-value)存储,key是无序的不可重复的,value是可以重复的,每个key映射一个value。
List接口的实现类其数据结构时线性的。Set接口的实现类其数据结构为图,树结构。
10. Collection和Collections的区别?
- Collection是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,所有集合都是它的子类,如List,Set等。
- Collections是操作集合的工具类,包含了很多的静态方法,不能被实例化。
11. List、Set、Map是否继承自Collection接口?
List、Set是,Map不是。Map是键值对映射容器,与List和Set有明显区别,而Set存储的零散的元素且不允许有重复元素,List是线性结构的容器,适用于按数值索引访问元素的情况。
12. HashMap和HashTbale的区别?
- HashMap允许key和value为null,但null做为key只能有一个,而HashTable不允许。
- HashMap是非线程安全的,而HashTable是线程安全的(内部方法都使用synchronized修饰)。
- 因为线程安全问题,HashMap要比HashTable效率高一点。
- HashMap的底层存储结构为数组+链表实现,在jdk8以后,链表高度大于8、数组长度超过64,链表转变为红黑树,元素以内部类Node节点存在,当链表长度低于6时则将红黑树转回链表。
- 在创建时如果不指定容量初始值,HashTable默认的初始大小为11,之后每次扩充,容量变为原来的2n+1;HashMap默认的初始化大小为16,之后每次扩充,容量变为原来的2倍。
- 在创建时给定了容量初始值,那么HashTable会直接使用给定的大小,而HashMap会将其扩充为2的幂次方大小,也就是说HashMap总是使用2的幂作为哈希表的大小。
13. ArrayList和LinkedList的区别?
ArrayList:
- 底层数据结构是动态数组,连续内存存储,适合下标访问。
- 扩容机制:因为数组长度固定,超出长度存数据时需要新建数组进行扩容,每次扩容为原容量的1.5倍,然后将老数组的数据拷贝到新的数组,如果是尾插法插入数据则不会涉及元素的移动。
LinkedList:
- 底层数据结构是链表,可以存储在分散的内存中,适合做数据插入及删除操作,不适合查询,查询只能从头开始遍历。
- 遍历LinkedList尽可能用迭代器,不适用for循环,因为每次for循环体内通过get(i)取得某一个元素时都需要对list重新进行遍历,性能消耗极大。
14. ArrayList和Vector的区别?
- ArrayList是List的主要实现类,适用于频繁的查找工作,线程不安全。
- Vector是List的古老实现类,线程安全。
- 两者都使用动态数组实现数据的存储。
- ArrayList的初始容量为0,第一次扩容会扩容到10;而Vector初始容量默认值为10。
- ArrayList在扩容的时候扩容后的容量为原容量的1.5倍;Vector在原有容量基础上扩容1倍。
- Vector的方法都有同步锁,在方法执行时需要维护锁(进行开锁解锁的操作),所以性能比ArrayList低。
15. 如何创建线程?
- 继承Thread,并重写run()方法。
- 实现Runnable接口,实现run()方法。
- 实现Callable接口,实现call()方法。
- 通过线程池获取线程。
16. 封装、继承、多态
封装:将同一类事物的共性(属性和方法)隐藏在对象内部,外界无法直接操作,将属性私有化,提供共有方法(set、get)访问私有属性。
继承:多个类具有共同的成员变量和成员方法,把这个共同的部分提取出来定义到一个公共的类中,其他的类只需要继承这个类即可。可以减少代码的重复。
多态:同一个对象,在不同时刻表现出来的不同形态;实现多态的三个前提:有继承/实现关系;有方法的重写;有父类引用指向子类对象(向上转型)。
17. Java异常体系和处理机制
体系:
Java中的所有异常都来自顶级父类Throwable。Throwable下有两个子类Exception和Error。
Error是程序无法处理的错误,一旦出现这个错误,则程序将被迫停止运行。
Exception不会导致程序停止,他又分为两个部分一个是RunTimeException运行时异常和CheckedException编译时导致。RunTimeException常常发生在程序编译过程中,会导致程序编译不通过。
处理机制:
java通过try、catch、finally、throw、throws五个关键字处理异常。
- try:用于监控、引发异常,会将可能出现异常的代码放在try中,由try对其中的代码进行监控,如果出现异常就会交给catch处理。
- catch:用于捕获并处理异常,当try快中检测到异常时catch就会捕获到该异常,然后根据不同类型的异常类型对其进行处理。
- finally:表示最终都要执行的代码,无论是否出现异常都会执行finally里面的代码。如果try/catch中有return的话,在执行return之前得先执行fianlly内的代码然后再跳回到try/catch中执行return的代码;如果finally中有return的话就会执行finally中的return不会执行try/catch中的return。
- throw:见下表
- throws:见下表
18. throws和throw的区别
throwsthrow用在方法声明后面,跟的是异常类名用在方法体内,跟的是异常对象表示抛出异常,由该方法的调用者来处理表示抛出异常,由方法体内的语句处理表示出现异常的一种可能性,并不一定会发生这些异常执行throw一定抛出了某种异常
19. Java常见的异常
- NullPointerException 空指针异常
- ArithmeticException 数学运算异常
- ArrayIndexOutOfBoundsException 数组下标越界异常
- ClassCastException 类型转换异常
- NumberFormatException 数字格式不正确异常
- SQLException SQL异常
20. 进程的生命周期
创建(新建了一个线程对象)、就绪(其他线程调用了该对象的strat方法,位于可运行线程池中)、运行(就绪状态获取了CPU)、阻塞(线程因为某种原因放弃CPU使用权,暂停工作)、死亡(线程执行完毕或者异常退出了run方法)
阻塞的情况分为三种:
- 等待阻塞:执行了wait方法,JVM会把该线程放入“等待池”中,进入这个状态后,是不能自动唤醒的,必须依靠其他线程调用notify或者notifyAll方法才能被唤醒。
- 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。
- 其他请求:线程执行了sleep或者join方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态,等执行了方法或者请求超时/完成时线程就会转入就绪状态。
21. ==和equals的区别是什么?
==对比的是栈中的值,基本数据类型比的是两个变量值是否相等,而引用类型比的是两个对象的内存地址是否相等。
equals:再不重写的情况下,object中默认也是采用==比较,如果重写了那就按照重写的规则进行判断。
基本类型不能使用equals方法。
22. 为什么重写equals方法也要重写HashCode方法?
首先hashCode的作用是获取散列码,它实际上会返回一个int整数,这个散列码的作用就是确定该对象在哈希表中的索引位置。
如果两个对象相等,则 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。所以,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。
23. 线程池有哪几种?
- newCachedThreadPool
- newFixedThreadPool
- ScheduledThreadPool
- newSingleThreadExecutor
24. IO流有哪些?
按照流的方向:分为输入流和输出流
按照操作内容划分:分为字节流和字符流
具体的IO流涉及到了很多类,但是这些类都是从一下四个抽象类派生出来的
InputStream/OutputStream:字节输入流和字节输出流
Reader/Writer:字符输入流和字符输出流
25. HashSet和LinkedHashSet和TreeSet
HashSet:Set接口的实现类,底层实现HashMap利用了HashMap的Key进行数据存储,不保证元素的顺序,线程不安全,可以存放null值,值得内容不允许重复。
LinkedHashSet:是HashSet的子类具有HashSet的特性,底层实现链表,线程不安全,元素的顺序与添加顺序一致。
TreeSet:是一个红黑树的结构,录入数据后能进行排序,不能存放null值,非线程安全的。
26. 并发、并行和串行的区别
并发:允许两个任务彼此干扰,统一时间点、只有一个任务运行,交替执行。
并行:在时间上是重叠的,两个任务在统一时刻互不干扰的同时执行。
串行:在时间上不可能发生重叠,前一个任务没搞定,下一个任务就只能等着。
27. Thread中的run和start的区别
start方法是来启动线程的,真正的实现了多线程的运行。start方法来启动一个线程,这时此线程是处于就绪状态,并没有运行,然后通过调用run方法来完成其运行的操作,当run方法运行结束,此线程就终止。
如果直接调用run方法,这只是调用了一个普通方法而已,程序中依然只有主线程。
28. 反射的机制
在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能成为 Java 语言的反射机制。
29. final在java中有什么作用?
- 修饰类:这个类不能被继承
- 修饰成员方法:不能被重写
- 修饰局部变量:变量会变为常量
- 修饰成员变量:变量会变为常量,由于成员变量具有默认值,所以被final修饰后得手动赋值或者使用构造器赋值
30. Object中定义了那些方法?
方法名返回类型解释clone()protected Object创建并返回此对象的一个副本equals(Object obj)boolean比较其他对象是否与此对象相等finalize()protected void当垃圾回收器确定不存在该对象的更多引用时,由对象的垃圾回收器调用此方法getClass()Class<?>返回此Object的运行时类hashCode()int返回该对象的哈希码值notify()void唤醒在此对象监视器上等待的单个线程notifyAll()void唤醒在此对象监视器上等待的所有线程toString()String返回该对象的字符串表示wait()void在其他线程调用此对象的notify()方法或者notifyAll()方法前,导致当前线程等待。wait(long timeout)void在其他线程调用此对象的notify()方法或者notifyAll()方法,或者超过指定的时间量前,导致当前线程等待。wait(long timeout,int nanos)void在其他线程调用此对象的notify()方法或者notifyAll()方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
31. Java中public、private、protected以及默认关键字的访问范围?
- public:表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
- private:表示私有,除了class自己之外,任何人都不可以直接使用,都不可以使用。
- protected:对于子类、本包来说,可以自由使用,而对于其他的外部class,protected就变成private。
- default:对于当前类和本包来说可以自由访问,子孙类和其他包无法使用。
32. continue、break、和return的区别是什么?
- continue :指跳出当前的这一次循环,继续下一次循环。
- break :指跳出整个循环体,继续执行循环下面的语句。
- return:用于跳出所在方法,结束该方法的运行。
33. String s1 = new String("abc");创建了几个字符串对象?
- 一个对象:如果池中已存在字符串常量“abc”,则只会在堆空间创建一个字符串常量“abc”。
- 两个对象:如果池中没有字符串常量“abc”,那么它首先在池中创建,然后在堆空间中创建,因此将创建 总共 2 个字符串对象。
34. 如何停止 一个正在运行的线程?
- 使用退出标志,使线程正常退出。 要定义一个 volatile的布尔类型volatile boolean flag = false ; // 线程执行的退出标记。
- 使用 stop 方法强行终止。
- 使用 interrupt方法中断线程。
35. 值引用和对象引用的区别
一个方法传递的参数如果是基本数据类型,则是对具体值的拷贝;如果是对象数据类型,则是对对象引用地址值的拷贝,而非具体值拷贝。
值引用对象引用作用范围基本数据类型对象存放地址栈对象值在堆里,对象的地址在栈中入参变化情况不会改变原来的值可以改变原来对象的属性值,不能改变原对象的引用地址
36. 浅拷贝和深拷贝
浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝;不拷贝原对象所引用的对象。实现Cloneable接口,重写Clone方法。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容;拷贝原对象所引用的对象。
二、Servlet
1. JSP的九大内置对象是什么?
①:out对象:数据类型是PrintWriter,用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。
②:session对象:从浏览器连接到服务器开始,到关闭浏览器离开服务器结束,在此期间包含多次请求和相应,被成为一个会话。
③:application对象:上下文对象,服务器启动后就产生了这个application对象,一个服务器只有一个application对象,当客户所访问的网站的各个页面之间浏览器时,这个application对象都是同一个。服务器的全局对象
④:request对象:是ServletRequest 类型的对象,接受客户端浏览器的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。
⑤:response对象:是ServletResponse类型的对象。response代表的是对客户端的响应,主要是将 JSP 容器处理过的对象传回到客户端。response对象也具有作用域,它只在当前JSP页面内有效。
⑥:page对象:代表 JSP 本身,只有在 JSP 页面内才是合法的。
⑦:exception对象:java.lang.Throwable 的实例,该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令 page 的 isErrorPage 属性为 true 时,该对象才可以使用。
⑧:config对象:主要作用是取得服务器的配置信息。
⑨:pageContext对象:作用是取得任何范围的参数,通过它可以获取 JSP 页面的 out、request、response、session、application 等对象。
2. 谈谈对Servlet的理解?
Java Servlet 的简称,称为小服务程序或服务连接器,用Java 编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。
Servlet的生命周期为:加载、初始化、服务和销毁。
Servlet接口中的方法:
①:init(ServletConfig):初始化方法,默认第一次请求前执行,完成servlet初始化工作。
②:service(ServletRequest,ServletResponse):执行方法,一次请求执行一次.
③:destroy():销毁方法,Servlet对象应该从服务中被移除的时候,容器会调用该方法进行销毁操作。
④:getServletConfig():获得ServletConfig配置对象,包括初始化参数等。
⑤:getServletInfo():获得Servlet描述,一般没有用。
3. 谈一谈MVC模式
MVC模式中,Model是指业务模型,View是指用户界面,Controller则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使用一个程序可以使用不同的表现形式。
- Model(模型):模型代表一个存取数据的对象,它也可以带有逻辑,在数据变化时更新控制器。
- View(视图):呈现给用户的部分,是用户和程序交互的接口。
- Controller(控制器):用来进行用户的交互,接受到用户的请求,对请求做出相应。控制器中接收了用户与界面交互时传递过来的数据,并根据数据业务逻辑来执行服务的调用和更新业务模型的数据和状态。目的是使得模型和实体分离。
4. JDBC的连接步骤?
加载驱动、获取连接、创建一个预处理对象、执行SQL语句、处理结果集、然后在关闭资源。
//1.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver"); //内容写死的:com.mysql.cj.jdbc.Driver
//2.建立Java和Mysql之间的连接通道
String url = "jdbc:mysql://localhost:3306/student_massage?serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true";
String user = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url, user, password);
//3.产生一个负责传递Sql命令的传令官
String sql = "insert into tbl_student values(null,'亚托克斯','男',33,'艾欧尼亚')";
PreparedStatement ps = conn.prepareStatement(sql);
//4.交给mysql去执行这个命令
int row = ps.executeUpdate();
//5.关闭数据库连接
ps.close();
conn.close();
5. 转发和重定向的区别?
首先两者都是再Servlet中实现页面跳转的。
转发重定向有服务端进行的页面跳转由浏览器进行的页面跳转地址栏不会发生改变,始终显示的是同一个地址栏地址栏显示新的地址请求次数只有一次请求次数是两次请求域中数据不会丢失请求域中的数据会丢失,因为是两次请求
6. 什么是路由?
路由就是把数据从一个地方传送到另一个地方的行为和动作。
7. 什么是Tomcat服务器?
Tomcat是一个web容器,他由两个部分组成。
第一个部分是:HTTP服务器用来解析用户的请求,然后找到用户请求的资源文件,执行完成之后在对对用户进行相应操作。
第二个部分是Servlet容器:如果涉及到了java动态内容,会调用servlet容器去加载这些java类。
三、MySQL
1. 什么是主键,什么是外键?
主键:关系型数据库中的一条记录中有若干个属性,若其中某一个属性组(注意是组)能确定一个信息的唯一标识,不能重复不能为空。
外键:如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。用来连接两个表的那个信息,两个表共同拥有的一个属性 ,可以重复,可以为空。
2. 什么是数据库索引?索引的分类有那些?
索引就像一本字典中的拼音或者偏旁部首部分,我们可以通过它们快速找到想要的内容。索引是为了提升查询效率;索引的数据结构有Hash索引和B+树索引等。在进行单条记录查询的时候,可以选择哈希索引效率相对能快。其他大部分情况选择B+树索引。
普通索引:最基本的索引,没有任何限制。
唯一索引:主键唯一索引加速查找;普通唯一索引:加速查询。索引列的值必须唯一,但允许有空值
组合索引:其实就是普通和唯一索引,只不过可以有多个健来组合到一起生成一个索引
全文索引:用于在文章中搜索的时候,快速定位
空间索引:是指依据空间对象的位置和形状或空间对象之间的某种空间关系按一定的顺序排列的一种数据结构
3. 数据库的事务是什么?
ACID
数据库中的事务是指对数据库执行一批操作,这些操作最终要么全部执行成功,要么全部失败,不会存 在部分成功的情况。
事务的特点:
- 原子性:事务的整个过程如原子操作一样,最终要么全部成功,或者全部失败,这个原子性是从最终结果来看 的,从最终结果来看这个过程是不可分割的。
- 一致性:一个事务必须使数据库从一个一致性状态变换到另一个一致性状态。
- 隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离 的,并发执行的各个事务之间不能互相干扰。
- 持久性:一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。当事务提交之后,数据会持久化到硬盘,修改是永久性的。
4. MySQL优化
- 减少数据访问: 设置合理的字段类型,启用压缩,通过索引访问等减少磁盘IO。
- 返回更少的数据: 只返回需要的字段和数据分页处理减少磁盘IO。
- 减少交互次数: 批量DML操作,函数存储等减少数据连接次数。
- 减少服务器CPU开销: 尽量减少数据库排序操作以及全表查询,减少cpu 内存占用。
- 利用更多资源: 使用表分区,可以增加并行操作,更大限度利用cpu资源。
5. varchar和char的区别
varcharchar长度可变长度固定小于定义长度时,按照实际长度存储如果插入的长度小于定义长度时,用空格填充最多可以存放255个字符最多能存放65532个字符
6. MySQL中in和exists的区别
in是先查询内表,然后再把内表结果与外表匹配。适用于外表数据大于子查询的表数据的场景。
exists将主查询的数据,放在子查询中做条件验证,根据验证结果(TRUE或FALSE)来决定主查询数据结果是否要保留。适用于子查询的表数据大于外表数据的场景。
7. 数据库的悲观锁和乐观锁
悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量。
8. MySQL中的锁
从对数据操作的粒度分 :
- 表级锁:操作时,会锁定整个表。
- 行级锁:操作时,会锁定当前操作行。
- 页面锁:会锁定一部分的数据。
从对数据操作的类型分:
- 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
- 写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁。
9. JOIN和LEFT JOIN的区别
JOIN:两个表中都存在的才查询,如果只有一张表存在则不查询,通过主外键来确定是否两张表都存在
LEFT JOIN:两张表关联,左表全部显示,右表与左表一样的显示,不一样的显示为null
四、数据结构
1. 二分查找和顺序查找的区别?
二分查找法:二分查找法的前提必须时有序的序列,每次都是和中间值(起始下标和末尾下表和的一半)比较,失败的时候只需要修改起始和末尾的下标来将查找范围缩小到一半,进行查找对比。时间复杂度为:O(log 2n)
顺序查找法:从头到尾的遍历然后挨个对比直到找到目标数据为止。时间复杂度为:O(n)
2. 双向链表结构?
是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。插入和删除操作的时间复杂度仅为O(1)。
五、Mybatis
1. #{}和${}的区别?
${}:字符串替换,是拼接的方式;传的什么值,sql语句处理的时候就会显示什么值。
#{}:占位符
2. MyBatis动态SQL标签中循环标签中有哪些属性,各自的作用
if:提供了可选的查找文本功能。如果符合if的条件则执行if标签中的语句,反之不执行。
choose、when、otherwise:类似于java中的switch选择语句一样
trim、where、set:辅助条件判断,用于拼接语句
foreach:对集合进行遍历
bind:元素允许在OGNL表达式以外创建一个变量,并将其绑定到当前的上下文
3. MyBatis动态SQL中使用<where>标签与直接写where关键字有什么区别?
where标签:可以过滤掉条件语句中的第一个and或者or关键字
where:无法去除and关键字,语句拼接会导致语法错误
六、Spring
1. 什么是Spring?
spring是一个一站式的轻量级java开发框架,内部包含了很多技术,核心是控制反转(IOC)和面向切面(AOP),以及其他的,如:依赖注入、spring事务管理、通过spring集成其他框架、springmvc、springboot、springcloud等。
2. 为什么要用Spring框架?
Spring是一个轻量级的应用框架,它提供了IoC和AOP这两个核心的功能,他的核心目的是为了简化企业级的应用开发,使得开发者只需要关心业务的需求不需要关心bean的一些管理,以及通过切面的方式对功能进行增强,从而去减少代码的一个侵入性。
Spring框架的优势:
- 轻量
- Spring通过IoC的容器来去实现Bean的声明周期的一个管理以及通过DI来实现依赖注入,从而实现了对象依赖的松耦合的一个管理
- Spring提供了AOP的面向切面编程的功能,它可以把我们业务逻辑和系统功能之间进行一个切分SpringMVC框架提供了比较强大的功能且更加灵活的一个Web框架的一个支持
- 事务管理:SpringAOP去实现的一个事务的统一管理对应用开发中的事务处理提供了一个非常灵活的一个支持的一个特性
3. 什么是SpringMVC?
SpringMVC是归属于Spring,是在Spring基础之上的一个MVC框架,主要处理web开发的路径映射和视图渲染,属于Spring框架中WEB层开发的一部分。
4. 什么是SpringBoot?
SpringBoot框架相对于SpringMVC框架来说,更专注于开发微服务后台接口,不开发前端视图,同时遵循默认优于配置,简化了插件配置流程,不需要配置xml。
5. 什么是SpringSecurity?
Spring Security是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。提供了完善的认证机制和方法级的授权功能。它的核心是一组过滤器链,不同的功能经由不同的过滤器。
6. 对SpringIOC的理解
控制反转。核心是依赖注入,在之前的编码过程中,都是需要什么对象自己去new对象,有了IOC容器之后,就变成了由IOC容器来控制对象。控制在实现过程中所需要的对象及需要依赖的对象。依赖的对象直接由IOC容器创建后注入对象中,由以前的主动创建变成了被动接受,这就是反转。
7. 对SpringAOP的理解
面向切面编程。它是为解耦而生的,在一个系统中由不同的组件组成,每个组件负责一块特定的功能,如果不使用面向切面编程的话,会出现很多组件是跟业务无关的,这些核心服务组件经常融入到具体的业务逻辑中,如果为每一个具体业务逻辑操作都添加这样的代码,会导致代码冗余态度偶,所以AOP就是通过动态代理的方式,将这些公共的代码逻辑抽象出来变成一个切面,然后注入到所需目标对象中,在进行调用的时候,不需要修改原有业务的逻辑代码,只需要在原有的代码之上做一些增强功能。
8. Bean的生命周期
Bean的定义:通过反射的方式来生成,源码中有一个createBeanInstance方法专门来生成对象。
Bean的初始化:bean对象创建完成后,属性值都是默认值,通过populateBean方法来完成对象属性的填充
Bean的使用:在 web 程序运行期间,发生对某一个 Bean 的调用时,就会使用这个 Bean实例。
Bean的销毁:Bean 实例在程序退出的时候会进行销毁,而在销毁之前会自动调用 destory-method 属性指定名称的方法。
9. 什么是SpringCloud?
SpringCloud是一套分布式微服务的技术解决方案,它提供了快速构建分布式系统的常用的一些组件,(例如:配置管理、服务的注册与发现、服务调用的负载均衡、资源隔离、熔断降级、智能路由等) 它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心。SpringCloud是Spring官方提供的一套标准化的微服务定义,真正的实现目前主流的方案一个是Spring Cloud Netflix和Spring Cloud Alibaba。
10. SpringCloud基于什么协议?
HTTP协议
11. 什么是服务注册?
在服务治理框架中,都会构建一个注册中心,每个服务单元向注册中心登记自己提供服务的详细信息。并在注册中心形成一张服务的清单,服务注册中心需要以心跳的方式去监测清单中的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。
12. 什么是服务发现?
服务调用方法服务注册中心咨询服务,并获取所有服务的实例清单,实现对具体服务实例的访问。
13. 后端跨域的内容?
首先书写了一个config类实现WebMvcConfigurer,再加一个@Configuration注解。
- addMapping:设置对哪种格式的请求路径进行跨域处理。
- allowedHeaders:设置允许的请求头,默认允许所有的请求头信息。
- allowedMethods:设置允许的请求方法,默认是 GET、POST 和 HEAD。这里配置为 * 表示支持所有的请求方法。
- maxAge:设置探测请求的有效期
- allowedOrigins:设置支持的域
14. 什么是跨域?什么是同源策略?
跨域指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。
所谓同源是指,域名,协议,端口均相同。
15. 依赖注入的几种方式有哪些?
- 构造器注入:将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。
- setter方法注入:IoC Service Provider通过调用成员变量提供的setter函数将依赖对象注入给依赖类。
- 接口注入:依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。该函数的参数就是要注入的对象。
16. SpringBoot有哪些注解?
- @SpringBootApplication:用在启动类上,识别这是一个SpringBoot应用。
- @EnableAutoConfiguration:允许SpringBoot自动配置注解,开启这个注解之后,SpringBoot就能根据当前路径下的包后者类来配置SpringBean。
- @Configuration:用于定义配置类,指出该类是Bean配置的信息源。
- @ComponentScan:让SpringBoot扫描到Configuration类并把它加入到程序上下文。
- @Repository:用于标注数据访问组件,DAO组件。
- @Service:修饰service层的组件。
- @RestController:标注Controller层组件,它包含@Controller和@ResponseBody。
- @ResponseBody:表示该方法的返回结果直接写入HTTP response body中。
- @Component:标注Spring管理的Bean,注解到一个类上就表示将此类标记为Spring容器的一个Bean。
- @Bean:相当于XML中的,放在方法的上面,产生一个bean,交给Spring管理。
- @AutoWired:byType方式搜索,把配置好的Bean拿来用,完成属性、方法的组装。
- @Resource(name="",type=""):按名字搜索如果找不到就按类型搜索,如果括号里面没有写东西那就按照名字搜索。
- @RequestMapping:将请求和处理请求的控制器方法关联起来,建立映射关系。
- @RequestParam:将请求参数绑定到控制器的方法参数上。
- @PathVariable:将URL中占位符参数绑定到控制器处理方法的入参中。
17. 设计模式
①.单例模式
他的核心结构中只包含一个被成为单例的特殊类,通过单例模式可以保证系统中,应用该模式的类,一个类只有一个实例,即一个类只有一个对象实例。
Ⅰ.饿汉模式:不管使用还是没有使用,对象都已经创建了。坏处是浪费内存空间。在类加载初始化时就创建好了一个静态的对象供外部使用,除非系统重启,这个对象不会改变,所以本身就是线程安全的。
Ⅱ.懒汉模式:如果未调用,对象不会创建,只在被使用时,创建对象。优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。避免对资源的多重占用。缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
②.工厂模式
使用工厂方法替代new操作的一种模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
Ⅰ.简单工厂模式:简单工厂模式是属于创建型模式,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。优点:能够根据外界给定的信息,决定究竟应该创建那个具体类的对象,明确区分了各自的职责和权力。
Ⅱ.工厂模式:核心的工厂类不在负责所有的产品的创建,而是将具体创建的工作交给子类去做,该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一种产品类应当被实例化这种细节。
Ⅲ.抽象工厂模式:是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
③.代理模式
首先它属于结构性模式,它是为其他对象提供一种代理以控制对这个对象的访问,在某些情况下,一个对象不合适或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。一个类代表另一个类的功能。
④.适配器模式
将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作,在适配器模式定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合。
18. SpringMVC的执行流程
- 用户发送请求到前端控制器DispatcherServlet。
- DispatcherServlet收到请求调用HandlerMapping处理器映射器(维护url到handler的一个映射关系)。
- 处理器映射器找到具体的处理器,根据注解进行查找,然后返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter处理器适配器。
- HandlerAdapter经过适配调用具体的处理器(Controller)
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller返回的ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析成具体的视图
- DispatcherServlet根据View进行渲染视图
- DispatcherServlet相应用户
19. Spring自动装配Bean的几种方式
自动装配,就是在xml配置文件bean中定义autowire的属性
- 如果不写的情况下,就自动配置,通过ref属性手动设定
- byName-就是在这个autowire冒号里面写一个byName,然后就会根据bean的属性名称进行自动装配
- byType-就是在这个autowire冒号里面写一个byType,然后就会根据bean的类型进行自动装配,但是如果有多个bean的话,还得用@Qulifier指定到底注入哪一个。
- constructor-类似byType,只不过是用于构造器的参数,如果一个bean与构造器参数的类型相同的话,则进行自动装配,否则就导致异常。
- autodetect-如果有默认的构造器,就用constructor方式进行自动装配,否则就是用byType的方式进行自动装配。
- @Autowired自动装配bean,可以在字段、setter方法、构造函数上使用。
20. Spring中的bean是线程安全的吗?
Spring中Bean对象默认是单例的。
- 如果bean是有状态的,就需要开发人员自己来保证线程安全的保证,最简单的办法就是改变bean的作用域把singleton改成prototype,这样每次请求bean对象就相当于是创建新的对象来保证线程安全。
- 如果是无状态的话,因为controller,service和dao本身不是线程安全的,只是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制遍历,这是线程安全的。
21. JWT是什么?
json web token是一种用于双方之间传递安全信息的表述性声明规范,盾牌。是由用户以用户名、密码登录、服务器验证后,会生成一个token,返回给客户端,客户端在下次访问的过程中携带找个token,服务端责每次验证这个token。
22. Spring支持的事务管理类型有哪些?
隔离级别:多个并发事务之间的数据要互相隔离,隔离级别就是用来描述并发事务之间隔离程度的大小。如果不考虑隔离性的话,就会出现脏读、不可重复读、幻读。
传播行为:规定了事务方法和事务方法发生嵌套调用时事务如何进行传播,协调已经有事务标识的方法之间的发生调用时的事务上下文的规则。
是否只读:如果将事务设置为只读,表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务。
事务超时:在特定时间内事务如果没有执行完毕,那么就会自动回滚,而不是一直等待其结束。在 TransactionDefinition 中以 int 的值来表示超时时间,默认值是-1,其单位是秒。
回滚规则:回滚规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚。
23. 说明拦截器与过滤器有什么异同点?
过滤器直接实现Filter接口,或者用@WebFilter注解来实现对特定的URL拦截,Filter接口中三个方法。
- init()在容器启动初始化过滤器时调用。
- doFilter():容器中的每一次请求都会调用该方法
- destory():当容器销毁过滤器实例时调用该方法
拦截器是链式调用,一个应用可以同时存在多个拦截器,一个请求也可以触发多个拦截器。首先编写一个简单的拦截器处理类,请求的拦截是通过HandlerInterceptor来实现。HandlerInterceptor接口中定义了三个方法。
perHandle():在请求处理之前进行调用,如果返回值为false,则当前请求结束,自身和其他的拦截器都不会执行。
postHandle():只在perHandle()方法返回值为true时才会执行,在Controller调用之后,DispatcherServlet 返回渲染视图之前被调用。
afterCompletion():只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
过滤器拦截器过滤器和拦截器都体现了AOP的编程思想。过滤器和拦截器都体现了AOP的编程思想。基于函数回调Java反射机制动态代理实现的Filter接口,这个接口在Servlet规范中定义的,所以过滤器的使用依赖于Tomcat等容器,导致它只能在web程序中使用是一个Spring组件,由Spring容器管理,不依赖Tomcat等容器在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后。在请求进入servlet后,在进入Controller之前进行预处理的,Controller 中渲染了对应的视图之后请求结束。Filter执行两次拦截器执行一次24. SpringMVC中的@ResponseBody什么时候使用@PathVariable怎么用?
@ResponseBody:表示该方法的返回结果直接写入HTTP response body中。一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。
@PathVariable:将URL中占位符参数绑定到控制器处理方法的入参中。通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法中入参中,URL中有{XXX}占位符可以通过@PathVariable("XXX")绑定到方法的入参中。
25. Spring AOP 机制都有哪些应用场景?
- 统一日志处理
- 统一幂等性的处理
- spring 中内置的事务处理
26. SpringBoot提供了哪些核心功能?
- jar 包方式运行
- 使用了 starter 依赖 原理是依赖的 Maven 的依赖传递性,使用 starter 来封装依赖,简化项目引入相关依赖的复杂度
- 自动配置spring 中的 @Condition 注解,根据特定的条件来创建相关的 bean自动完成相关框架的自动配置。
27. SpringMVC的常用注解有哪些?
- @RequestMapping:用于映射请求路径,可以定义在类上和方法上。用于类上,则表示类 中的所有的方法都是以该地址作为父路径。
- @RequestBody:注解实现接收 http 请求的 json 数据,将 json 转换为 java 对象。
- @RequestParam:指定请求参数的名称
- @PathViriable:从请求路径下中获取请求参数(/user/{id}),传递给方法的形式参数
- @ResponseBody:注解实现将 controller 方法返回对象转化为 json 对象响应给客户端。
- @RequestHeader:获取指定的请求头数据
28. Spring Boot 常用的 starter 有哪些?
- spring-boot-starter-web (Web启动器)
- spring-boot-starter-data-redis (Redis依赖)
- mybatis-plus-boot-starter (MyBatisPlus依赖)
- mybatis-spring-boot-starter (MyBatis依赖)
- spring-boot-starter-test (启动器测试)
- druid-spring-boot-starter (阿里巴巴druid数据库连接池)
- pagehelper-spring-boot-starter (分页插件依赖)
七、Redis
1. 什么是Redis?
Redis是一个开放源代码的内存中数据结构存储,可用作数据库,缓存和消息代理,是一个基于键值对的NoSQL数据库。
2. Redis的优点有哪些?
速度快、基于键值对的数据结构服务器、丰富的数据结构、客户端语言多、持久化、主从复制。
3. Redis的数据结构及使用场景?
- 字符串:可以用来做最简单的数据缓存,可以缓存某个简单的字符串,也可以缓存某个json格式的字符串。
- 哈希表:可以用来存储一些key-value对,更适合用来存储对象。
- 列表:Redis的列表通过命令的组合,既可以当作栈,也可以当作队列来使用,可以用来缓存类似微信公众号,微博等消息流数据。
- 集合:可以存储多个元素,但是不能重复,集合可以进行交集、并集、差集操作,故可以实现如,我和某人共同关注的人、朋友圈点赞等功能。
- 有序集合:集合是无序的,有序集合可以设置顺序,可以用来实现排行榜功能。
4. Redis缓存如何回收?
- noeviction:缓存写满时Redis不提供服务直接返回错误。
- allkeys-lru:回收最少使用的键。
- volatile-lru:回收最少使用的键;但仅限于在过期集合的键。
- allkeys-random:回收随机的键。
- volatile-random:回收随机的键;但仅限于在过期集合的键。
- volatile-ttl:在过期集合的键中回收,并且优先回收存活时间比较短的键。
- volatile-lfu:在所有配置了过期时间的键中驱逐使用频率最少的键。
- allkeys-lfu:从所有键中驱逐使用频率最少的键。
5. 什么是缓存雪崩?
概念:当大量缓存数据在同一时间失效或者redis故障宕机时,此时有大量的用户请求,无法从redis中处理,所有的请求只能直接访问数据库,从而导致数据库压力过大,导致数据库崩掉。
应对方式:①:均匀设置过期时间;②:互斥锁;③:后台更新缓存。
6. 什么是缓存击穿?
概念:缓存中某个数据过期了,此时大量的请求访问该数据,无法从缓存中读取,直接去访问数据库,从而导致数据库压力过大,导致数据库崩掉。
应对方式:①:给热点数据设置永久不过期,定期对其进行更新操作;②:互斥锁。
7. 什么是缓存穿透?
概念:用户访问的数据,既不在缓存中也不再数据库中,先请求缓存时发现缓存缺失,再去数据库,发现数据库中也没有要访问的数据,最终所有的请求都会落到数据库上处理,当有大量这样的请求时,数据库的压力增大导致数据库崩掉。
应对方式:①:在接口层增加校验;②:设置value的值为null或者默认值;③:使用布隆过滤器快速判断数据是否存在。
8. Redis持久化机制
- RDB:持久化方式能够在指定的时间间隔能对数据进行快照存储。
- AOF:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
9. Redis为什么是单线程的?
Redis基于Reactor模式开发的网络事件处理器,这个处理器叫做文件事件处理器file event handler。这个文件事件处理器是单线程的,所以Redis是单线程的。采用I/O多路复用机制来同时监听多个Socket。
八、Nginx
1. 什么是Nginx?
Nginx是一个轻量级/高性能的反向代理Web服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。它实现非常高效的反向代理、负载平衡,他可以处理2-3万并发连接数,官方检测能支持5万并发。
2. Nginx有哪些优点?
- 跨平台、配置简单。
- 非阻塞、高并发连接:处理2-3万并发连接数,官方检测能支持5万并发。
- 内存消耗小:开启10个Nginx才占150M内存。
- 成本低,且开源。
- 稳定性高,宕机的概率非常小。
- 内置的健康检查功能:如果有一个服务器宕机,会做一个健康检查,在发送的请求接不会发送到宕机的服务器了。重新将请求提交到其他的节点上。
3. Nginx应用场景?
- http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。
- 虚拟主机。可以实现在一台服务器虚拟出多个网站,例如个人网站使用的虚拟机。
- 反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多态服务器集群可以使用Nginx做反向代理。并且多态服务器可以平均分担负载,不会应为某台服务器负载高宕机而某台服务器闲置的情况。
- Nginx中也可以配置安全管理、比如可以使用Nginx搭建API接口网关,对每个接口服务进行拦截。
4. 什么是正向代理?
一个位于客户端和原始服务器之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标,然后代理向原始服务器转交请求并将获得的内容返回给客户端。
客户端才能使用正向代理。正向代理总结就一句话:代理端代理的时客户端
5. 什么是反向代理?
反向代理方式,是指以代理服务器来接受Internet上的连接请求,然后将请求,发给内部网络上的服务器并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
6. Nginx如何实现session共享?
- **ip_hash(ip绑定)**:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。需要修改nginx的配置文件
- tomcat集群实现session的共享:有几个tomcat,就复制了几个session,假如一个tomcat的session发生了改变,其余的tomcat的session也会复制发生改变。
- 使用客户端的cookie作为存放登录信息的媒介
九、JDK、JVM
1. JVM的内存结构
- Java Source(源代码):通过javac命令把源代码编译成Java Class字节码,(字节码的很大应用,跨平台)。
- 在执行类的时候会创建一个main的主线程在JVM Stacks虚拟机栈中分配内存,在遇到一个没有见过的类,在方法区里面没有,就会出现相对应的类加载功能。
- 类加载子系统:把字节码文件读到内存中,方法区(Method Area)。
- Method Area 方法区:存放类的信息包括代码的方法信息。
- Heap 堆:当代码有new对象的操作,就是创建一个类的实例对象时,这个对象所占用的内存就来自于推内存。
- JVM Stacks 虚拟机栈:方法内的局部变量,和方法参数引用还有方法的返回的地址,占用的内存都是当前线程的栈内存。
- 本地方法栈:虚拟机使用到Native方法服务;但在Oracle的HotSpot java虚拟机中并没有分的那么细,不管是普通java方法调用还是本地方法调用,他们的内部都是用的虚拟机栈,没有本地方法栈。
- PC Register 程序计数器:用来记录当前线程执行到第几行代码。(主线程在执行了一些代码后,可能会出现cpu的使用权会交给其他线程来运行,那如果下次又回来执行的时候,需要从哪里开始执行,这个时候就需要程序计数器来记录当前线程执行到第几行)。
- GC 垃圾回收:当对象不在被使用时,就会被当成垃圾,当内存存满的时候就会触发垃圾回收机制,将这些不在使用的对象进行回收,释放资源。
- Interpreter解释器:因为CPU只认机器码,所以Interperter解释器就是把java的字节码翻译成最终适用于各个平台的机器码,对同一行代码可以进行反复解释(调用几遍就会翻译几遍),对于热点代码的话,比较浪费时间和资源。
- JIT Compiler 即时编译器:负责发现热点代码,将热点代码翻译成机器码并存入缓存中,下次使用可以直接在缓存中找到对应的机器码。
2. GC算法
①:标记清除
- 标记阶段:首先找到GC Root对象(跟对象,一般是一些一定不能被回收的对象还有一种是静态变量引用的对象)然后从根对象出发沿着他的引用链看你的当前的对象有没有被跟对象引用,包括直接引用和间接引用。如果引用了就不用标记,如果沿着跟对象引用链找了一圈没有被跟对象引用那就会被清除掉。
- 清除阶段:加标记的对象保留下来,没有标记的就会被清除。
- 缺点:虽然清楚了很大一块内存,但是会造成内存碎片。
②:标记整理
- 标记阶段:同上
- 整理阶段:把清除完之后存活的对象,整理一下,紧挨着不会出现内存碎片,后面空闲的内存是一个连续的内存。
- 缺点:效率比较低
- 比较适合老年代的垃圾回收
③:标记复制
- 把内存分成两部分区域,第一部分用来存对象,第二部分开始是空闲的什么都不存
- 标记阶段:同上
- 复制阶段:没有清除的操作,把标记的对象复制到第二部分的空闲区域,然后将第一部分的所有的对象全部清空。
- 缺点:因为开始时需要专门空闲出来一片内存配合复制来使用。
- 多用于新生代的垃圾回收
3. GC如何判断对象可以被回收
- 引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计 数为0时可以回收,(可能会出现A引用了B,然后B又引用了A,这时候就算他们都不再使用了,但因为相互引用计数器=1永远无法被回收)
- 可达性分析法:从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是不可用的,那么虚拟机就判断是可回收对象。
4. 类的加载过程
JVM的类的加载是由类加载器和它的子类来实现的。分为以下过程:
①:加载
- 将类的字节码加载到方法区中,然后再堆内存中创建.class对象。
- 如果此类的父类没有被加载,得先加载父类;如果类实现了一个接口,得先加载接口。
- 加载时懒惰执行的。
②:链接
- 验证类是不是符合字节码规范,合法性和安全性的检查。
- 为类中的静态变量分配空间并且设置变量的默认值,如果有给静态变量赋值的语句,不在这里执行,在初始化的时候才会执行,只为静态变量分配空间。
- 将常量池的符号引用解析为直接引用。
③:初始化
- 执行静态代码块与非静态变量的赋值。
- 初始化也是懒惰执行的。
5. 双亲委派机制
指优先委派上级类加载器进行加载,
如果上级类加载器能找到这个类,由上级加载。加载后该类对下级加载器是可见的,但是下级加载器加载的类对上次是不可见的,上级的类加载器加载后下级类加载器就不需要重复加载这个类了。
如果找不到这个类,则下级类加载器才有资格执行类的加载。
类加载器的等级关系:
Bootstrap ClassLoader(启动类加载器)>Extension ClassLoader(扩展加载器)>Application ClassLoader(应用程序类加载器)>自定义类加载器
6. JDK1.8有什么特性?
- HashMap底层结构:在jdk8以后,链表高度大于8、数组长度超过64,链表转变为红黑树,元素以内部类Node节点存在,当链表长度低于6时则将红黑树转回链表。
- 接口默认方法:jdk1.8由于要兼容lambda表达式所以允许我们给接口添加一个非抽象方法实现,只需要使用default关键字。
- Lambda表达式:面向函数式编程的lambda表达式,简化了编程。
- 函数式接口:只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。
- Stream API:在一组元素上一次执行的操作序列。
- 一些新的类的诞生:LocalTime 本地时间、clock 时钟、LocalDate 本地日期、LocalDateTime 本地日期时间。
- 支持多重注解:jdk1.8可以把同一个类型的注解使用多次。
- Optional类:是一个容器类,代表一个值存在或不存在。减少空指针异常。
十、前端
1. get与post请求的区别?
GETPOST请求的URL可见请求的URL不可见通过拼接的方式来传递参数通过body的方式来转递参数可以缓存不可以缓存请求页面后退,不产生影响请求页面后退时,会重新提交请求
2. JSP中的四种作用域
page:pageContext,作用域仅限于用户请求的当前页面,离开当前页面后则失效。
request:作用域仅是用户的当前请求内,发送一个请求后Request创建,只要刷新页面,Request对象就会重新创建。
session:作用域为当前会话,session对象是浏览器独享资源。失效情况:浏览器关闭、无服务关闭、存活时间过期、调用了销毁方法。
application:ServeltContext,作用域为全局容器,整个web使用,当前服务器中所有浏览器共享。服务器启动时创建,服务器关闭时销毁。
3. 你所知道的http的相应码及含义
状态码含义200请求成功301永久重定向,转移到其他URL302请求临时重定向304请求被重定向到客户端本地缓存400客户端请求存在语法错误401没有经过授权,没有登录网站403请求被服务器拒绝,没有权限404请求失败,URL不存在500服务器错误
4. 请分别写出vue.js的条件渲染、列表渲染指令
条件渲染:v-if
列表渲染:v-for
5. js的基本数据类型
基本数据类型:数值、字符串、布尔、undefined、null
引用类型:array、function
6. HTTP协议和TCP协议的区别
HTTP协议TCP协议概念超文本传输协议,是应用层的协议,以TCP为基础传输控制协议,是传输层的协议,以IP协议为基础性质简单的请求,响应协议面向连接的、可靠的、基于字节流的传输层通信协议连接方式TCP连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务http通常运行在TCP之上。指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。连接状态无转态的连接有状态的长连接
十一、Linux
1. Linux基本指令
命令解析poweroff关机reboot重启ipconfig显示网卡的IP地址cd /切换到根目录cd..返回上一次mkdir name在当前目录下创建名为name的文件rm 文件删除当前目录下的文件mv name1 name2将目录name1改成name2vi修改文件wq保存并退出tar -zxvf 压缩文件解压到当前文件夹tar -zxvf 压缩文件 -路径解压到指定文件夹中tar -zcvf 文件名.tar.gz file1把file1压缩成文件名.tar.gzpasswd修改密码
版权归原作者 不爱健身的数学子弟不是好程序员 所有, 如有侵权,请联系我们删除。