Java 面试题
- 1、Java 基础
- 1.JDK 和 JRE 有什么区别?
- 2.== 和 equals 的区别是什么?
- 3.final 在 java 中有什么作用
- 4.java 中的 Math函数常用方法
- 5.数据类型(四类八种)
- 6.java 中操作字符串都有哪些类?它们之间有什么区别?
- 7.String 类的常用方法都有那些?
- 8.接口和抽象类有什么区别?
- 9.Java 中 IO 流分为几种?字符流和字节流的区别?
- 10.Files的常用方法都有哪些?
- 11.List、Set、Map 之间的区别是什么?
- 12.HashMap 和 Hashtable 有什么区别?
- 13.ArrayList 和 LinkedList 的区别是什么?
- 14.迭代器 Iterator 是什么
- 2、多线程
- 3.深拷贝和浅拷贝区别是什么
- 4.网络
- 5.Spring Boot
- 6.Mybatis
- 7.mysql
1、Java 基础
1.JDK 和 JRE 有什么区别?
JDK
JDK是Java开发工具包,JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
JRE
JRE是运行基于Java语言编写的程序所不可缺少的运行环境。JRE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。JRE是Java运行环境,并不是一个开发环境
2.== 和 equals 的区别是什么?
一、对象类型不同
1、equals():是超类Object中的方法。
2、==:是操作符。
二、比较的对象不同
1、equals():用来检测两个对象是否相等,即两个对象的内容是否相等。
2、==:用于比较引用和比较基本数据类型时具有不同的功能。
三、运行速度不同
1、equals():没有==运行速度快。
2、==:运行速度比equals()快,因为==只是比较引用。
3.final 在 java 中有什么作用
final修饰类的时候
如果java中的类被final关键字修饰,那么这个类是不能够被继承的.
final修饰属性的时候
如果java中的属性被final关键字修饰,那么这个属性是不能够被修改的.
final修饰方法的时候
如果java中的方法被final关键字修饰,那么这个方法是不能够被重写的也就是不能被覆盖
4.java 中的 Math函数常用方法
/取整,返回小于目标函数的最大整数,如下将会返回-2
Math.floor(-1.8);
//取整,返回发育目标数的最小整数
Math.ceil()
//四舍五入取整
Math.round()
//计算平方根
Math.sqrt()
//计算立方根
Math.cbrt()
//计算乘方,下面是计算3的2次方
Math.pow(3,2);
//计算自然对数
Math.log();
//计算绝对值
Math.abs();
//计算最大值
Math.max(2.3,4.5);
//计算最小值
Math.min(,);
//返回一个伪随机数,该数大于等于0.0并且小于1.0
Math.random
5.数据类型(四类八种)
整 型: byte、 short 、int、 long
浮点型:float、double
字符型:char
布尔型:boolean
引用数据类型 : string
6.java 中操作字符串都有哪些类?它们之间有什么区别?
String、StringBuffer、StringBuilder
String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对象,对字符串的修改操作都会生成新的对象。
StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。
StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。
7.String 类的常用方法都有那些?
String 类的常用方法:
equals:字符串是否相同
compareTo:根据字符串中每个字符的Unicode编码进行比较
indexOf:目标字符或字符串在源字符串中位置下标
lastIndexOf:目标字符或字符串在源字符串中最后一次出现的位置下标
valueOf:其他类型转字符串
charAt:获取指定下标位置的字符
isEmpty:字符串长度是否为0
format:格式化字符串
toCharArray:获取字符串的字符数组
length:字符串字符数
replace:字符串替换
split:以某正则表达式分割字符串
substring:截取字符串
toLowerCase:字符串转小写
toUpperCase:字符串转大写
8.接口和抽象类有什么区别?
接口和抽象类有什么区别
他们都不能实例化对象,都可以包含抽象方法,而且抽象方法必须被继承的类全部实现。
区别:
1、抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。
2、抽象类要被子类继承,接口要被类实现。
3、接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现
4、接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。
5、抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。
6、抽象方法只能申明,不能实现,接口是设计的结果 ,抽象类是重构的结果
7、抽象类里可以没有抽象方法
8、如果一个类里有抽象方法,那么这个类只能是抽象类
9、抽象方法要被实现,所以不能是静态的,也不能是私有的。
10、接口可继承接口,并可多继承接口,但类只能单根继承。
9.Java 中 IO 流分为几种?字符流和字节流的区别?
分类:
•按照流的流向分,可以分为输入流和输出流;
•按照操作单元划分,可以划分为字节流和字符流;
•按照流的角色划分为节点流和处理流。
字符流和字节流的区别
字符流:用于处理文字和字符的 流。操作完成后不关闭流,数据无法传递。
字节流:文字以外的都可以用。操作完成后不需关闭流,也可以传递数据。
字符流有缓冲区,将数据接受于缓冲区,达到区的极限(通过手动 1.colse 2.flush)就会进入文件中,打开文件次数少。
字节流:每传一次数据就会打开一次文件,打开数据次数多。占用内存。
缓冲流只在文件输出数据时存在。
10.Files的常用方法都有哪些?
Files.exists():检测文件路径是否存在。
Files.createFile():创建文件。
Files.createDirectory():创建文件夹。
Files.delete():删除一个文件或目录。
Files.copy():复制文件。
Files.move():移动文件。
Files.size():查看文件个数。
Files.read():读取文件。
Files.write():写入文件。
11.List、Set、Map 之间的区别是什么?
List:有序集合,元素可重复
Set:不重复集合,LinkedHashSet按照插入排序,SortedSet可排序,HashSet无序
Map:键值对集合,存储键、值和之间的映射;Key无序,唯一;value 不要求有序,允许重复
12.HashMap 和 Hashtable 有什么区别?
HashTable 使用 synchronized 来进行同步,线程安全。
HashMap 可以插入键为 null 的 Entry。
HashMap 的迭代器是 fail-fast 迭代器。
HashMap 不能保证随着时间的推移 Map 中的元素次序是不变的。
13.ArrayList 和 LinkedList 的区别是什么?
共性:ArrayList与LinkedList都是List接口的实现类,因此都实现了List的所有未实现的方法,只是实现的方式有所不同。
区别:List接口的实现方式不同
ArrayList实现了List接口,以数组的方式来实现的,因此对于快速的随机取得对象的需求,使用ArrayList实现执行效率上会比较好。
LinkedList是采用链表的方式来实现List接口的,因此在进行insert和remove动作时效率要比ArrayList高。适合用来实现Stack(堆栈)与Queue(队列)。
14.迭代器 Iterator 是什么
迭代器(也是一种设计模式),通常被称为轻量级对象。
它是一个对象,它的工作是遍历并选择序列中的对象,而客户端的程序员不必知道或关心该序列底层的结构。
Java的Iterator只能单向移动,它能用来:
(1)使用方法Iterator()要求容器返回一个Iterator。Iterator将准备好返回序列的第一个元素。
(2)使用next()获得序列中的下一个元素
(3)使用hasNext()检查序列中是否还有元素。
(4)使用remove()将迭代器新近返回的元素删除。
Iterator的一个很强的用处:能够将遍历序列的操作与序列底层的结构分离。1
2、多线程
1.并行和并发有什么区别?
并发性两个或多个任务可以在重叠时间内启动、运行和完成。这并不一定意味着他们将永远在同一时刻运行。例如,多任务在一台单核机器上。
平行性是当任务字面上同时运行,例如在多核处理器上运行。
(借鉴例子:并发就像有一个杂耍者在玩很多球。不管看上去如何,这个杂耍手一次只能一只手接一只球/投一个球。并行是有多个杂耍者同时杂耍球。)
2、线程和进程的区别?
概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程。当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程。
进程是指处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个单位。当程序进入内存运行时,即为线程。
进程的特点:
1:独立性:进程是系统中独立存在的实体,它可以独立拥有资源,每一个进程都有自己独立的地址空间,没有进程本身的运行,用户进程不可以直接访问其他进程的地址空间。
2:动态性:进程和程序的区别在于进程是动态的,进程中有时间的概念,进程具有自己的生命周期和各种不同的状态。
3:并发性:多个进程可以在单个处理器上并发执行,互不影响。
3、创建线程有哪几种方式?
线程的创建和启用:
java使用Thread类代表线程,所有的线程对象都必须是Thread或者其子类的实例,每个线程的作用是完成一定任务,实际上是就是执行一段程序流(一段顺序执行的代码)
1.继承Thread类型重写run 方法
public class ThreadDemoTest extends Thread{
@Override
public void run() {
System.out.println("通过继承Thread类重写run方法实现接口!");
}
public static void main(String[] args) {
ThreadDemoTest threadDemoTest = new ThreadDemoTest();
threadDemoTest.run();
}
2.实现Runnable接口
public class RunnableDemoTest implements Runnable{
public void run() {
System.out.println("实现Runnable开启线程!");
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableDemoTest());
thread.start();
}
}
3.实现Callable接口
public class CallableDemoTest implements Callable {
public Object call() {
return "HelloCallable!";
}
@Test
public void test() throws ExecutionException, InterruptedException {
CallableDemoTest callableDemoTest = new CallableDemoTest();
FutureTask futureTask = new FutureTask(callableDemoTest);
Thread thread = new Thread(futureTask);
thread.start();
//获取返回值
futureTask.get();
}
}
4.线程有哪些状态?
1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。
5.sleep() 和 wait() 有什么区别?
sleep()方法是使线程停止一段时间的方法。
wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。
6.线程的 run()和 start()有什么区别?
调用 start() 方法是用来启动线程的,轮到该线程执行时,会自动调用 run();直接调用 run() 方法,无法达到启动多线程的目的,相当于主线程线性执行 Thread 对象的 run() 方法。
一个线程对线的 start() 方法只能调用一次,多次调用会抛出 java.lang.IllegalThreadStateException 异常;run() 方法没有限制。
7.创建线程池有哪几种方式?
newSingleThreadExecutor
创建一个单线程的线程池。
newFixedThreadPool
创建固定大小的线程池。
newCachedThreadPool
创建一个可缓存的线程池。
newScheduledThreadPool
创建一个大小无限的线程池。
8.怎么防止死锁?
什么是死锁:
当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,称为死锁。
如何防止死锁:
·尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。
·尽量使用 Java. util. concurrent 并发类代替自己手写锁。
·尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
·尽量减少同步的代码块。
3.深拷贝和浅拷贝区别是什么
1.浅拷贝
对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
2.深拷贝
对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
4.网络
1.http 响应码
1xx(临时响应)
100: 请求者应当继续提出请求。
101(切换协议) 请求者已要求服务器切换协议,服务器已确认并准备进行切换。
2xx(成功)
200:正确的请求返回正确的结果,如果不想细分正确的请求结果都可以直接返回200。
201:表示资源被正确的创建。比如说,我们 POST 用户名、密码正确创建了一个用户就可以返回 201。
202:请求是正确的,但是结果正在处理中,这时候客户端可以通过轮询等机制继续请求。
203:请求的代理服务器修改了源服务器返回的 200 中的内容,我们通过代理服务器向服务器 A 请求用户信息,服务器 A 正常响应,但代理服务器命中了缓存并返回了自己的缓存内容,这时候它返回 203 告诉我们这部分信息不一定是最新的,我们可以自行判断并处理。
3xx(已重定向)
300:请求成功,但结果有多种选择。
301:请求成功,但是资源被永久转移。比如说,我们下载的东西不在这个地址需要去到新的地址。
303:使用 GET 来访问新的地址来获取资源。
304:请求的资源并没有被修改过。
308:使用原有的地址请求方式来通过新地址获取资源。
4xx(请求错误)
400:请求出现错误,比如请求头不对等。
401:没有提供认证信息。请求的时候没有带上 Token 等。
402:为以后需要所保留的状态码。
403:请求的资源不允许访问。就是说没有权限。
404:请求的内容不存在。
406:请求的资源并不符合要求。
408:客户端请求超时。
413:请求体过大。
415:类型不正确。
416:请求的区间无效。
5xx(服务器错误)
500:服务器错误。
501:请求还没有被实现。
502:网关错误。
503:服务暂时不可用。服务器正好在更新代码重启。
505:请求的 HTTP 版本不支持
2.get 和 post 请求有哪些区别
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。
3.如何实现跨域
跨域,是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript实施的安全限制。
1.jsonp方式:
2. 跨域资源共享CORS:
3. nginx代理跨域
...
5.Spring Boot
1.什么是 spring boot?
springboot就是Spring开源框架下的子项目,是Spring的一站式解决方案,主要是简化了spring的使用难度,降低了对配置文件的要求,使得开发人员能够更容易得上手。
SpringBoot有很多得优点:
简化了Spring配置文件,
没有代码和XML文件的生成
内置TomCat
能够独立运行
简化监控
2.spring boot 配置文件
1.application.properties
2.application.yml(或者是yaml)
eg:
server:
port: 8989
mybatis:
mapperLocations: classpath:mapper/*/*.xml
spring:
application:
name: appmember
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip/test?useUnicode=true&characterEncoding=UTF-8
username: root
password:root
dbcp2:
min-idle: 5
initial-size: 5
max-total: 5
max-wait-millis: 200
3.springboot常用注解
@SpringBootApplication
包含@Configuration、@EnableAutoConfiguration、@ComponentScan通常用在主类上。
@Repository
用于标注数据访问组件,即DAO组件。
@Service
用于标注业务层组件。
@RestController
用于标注控制层组件(如struts中的action),包含@Controller和@ResponseBody
@ResponseBody
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上 @responsebody后返回结果不会被解析
@ComponentScan
组件扫描。
@Configuration
指出该类是 Bean 配置的信息源,相当于XML中的<beans></beans>,一般加在主类上。
@AutoWired
完成自动装配的工作。
@RequestMapping
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。
@PathVariable
路径变量
4.spring boot 有哪些方式可以实现热部署
1.spring-boot-devtools
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
2.JRebel
Jrebel是Java开发最好的热部署工具,对Spring Boot 提供了极佳的支持,JRebel为收费软件,试用期14天。,可直接通过插件安装。
6.Mybatis
1.mybatis 中 #{}和 ${}的区别是什么
(1)#{} 占位符 ,能防止sql 注入
(2)${} 拼接符,不能防止sql 注入
2.mybatis 分页相关
链接: https://editor.youkuaiyun.com/md/?articleId=106121964.