往年面试精选题目(前50道)
- 常用的集合和区别,list和set区别
Map:key-value键值对,常见的有:HashMap、Hashtable、ConcurrentHashMap以及TreeMap等。Map不能包含重复的key,但是可以包含相同的value。
Set:不包含重复元素的集合,常见的有:HashSet、TreeSet、LinkedHashSet等
List:可包含重复元素的集合,常见的有:ArrayList、LinkedList、Stack以及Vector等
- map用过吗,怎么用到,怎么遍历,脚本如何实现
??? tip1:普通的foreach循环,使用keyset()方法,遍历key
Tip2:把所有的键值对装入迭代器中,然后遍历迭代器
3.get和post有什么区别,get为什么比post快
1、get把请求的数据放在url上,其格式为 以?分割URL和传输数据,参数之间以&相连;post把请求的数据放在HTTP的包体内
2、get提交的数据最大是2k,post理论上没有限制
3、get请求会被浏览器主动cache,而post不会(除非手动设置)
4、get请求只能进行url编码,而post支持多种编码方式
5、get请求参数会被完整保留在浏览器历史记录里,而post中的参数不会被保留
6、get只接受ascii字符的参数的数据类型,而post没有限制
7、get产生的url地址可以被bookmark,而post不可以
8、get效率高
5.c3p0和jdbc怎么联系起来的
在jdbc获取连接对象的时候,通过c3p0的工具类来实现
步骤:
导入C3P0库, 配置C3P0连接池, 使用JDBC连接, 关闭连接
6.Springmvc的工作原理
(1)、 ?用户发送请求至前端控制器DispatcherServlet。
(2)、 ?DispatcherServlet(前端控制器)收到请求调用HandlerMapping处理器映射器。
(3)、 ?处理器映射器(HandlerMapping)找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet(前端控制器)。
(4)、 ?DispatcherServlet(前端控制器)调用HandlerAdapter处理器适配器。
(5)、 ?HandlerAdapter(处理器适配器)经过适配调用具体的处理器(Controller,也叫后端控制器)。
(6)、 ?Controller(后端控制器)执行完成返回ModelAndView(模型和视图)。
(7)、 ?HandlerAdapter(处理器适配器)将controller执行结果ModelAndView返回给DispatcherServlet(前端控制器)。
(8)、 ?DispatcherServlet(前端控制器)将ModelAndView(模型和视图)传给ViewReslover视图解析器。
(9)、 ?ViewReslover(视图解析器)解析后返回具体View。
(10)、 ?DispatcherServlet(前端控制器)根据View进行渲染视图(即将模型数据填充至视图中)。
(11)、 DispatcherServlet(前端控制器)响应用户。
4.MVC框架的理解
mvc框架包含View视图,Controller控制器,Model模型三部分。视图用于渲染数据,模型用于处理业务,控制器起纽带作用:把视图和模型联系在一起
工作流程:
2.控制器接收到请求后对数据进行封装,选择模型进行业务逻辑处理;
3.随后控制器将模型处理结果转发到视图或下一个控制器;
4.在视图层合并数据和界面模板生成HTML并做出最终响应。
5.sql优化
???
(1)避免使用*
(2)避免复杂的多表连接
(3)建立有效索引
(4)读写分离
6.String、stringbuffer和stringbuilder的区别
- String类型的字符串对象是不可变的,一旦String对象创建后,包含在这个对象中的字符序列是不可以改变的,直到这个对象被销毁。
- StringBuilder和StringBuffer类型的字符串是可变的,不同的是StringBuffer类型的是线程安全的,而StringBuilder不是线程安全的
3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。
StringBuffer是同步的,StringBuilder不是。
7.简单谈谈Redis
Redis是一种非关系型数据库,存储数据使用K-V形式,有时redis作为缓存来用,搭建redis缓存集群。
Redis的基本数据类型:字符串(String),列表(List),集合(Set),
有序集合(Sorted Set),哈希表(Hash)
8.SSM框架的理解
老师更新:
ssm指spring、springmvc和mybatis三个框架。springmvc属于spring框架的组件,实现了mvc模型,提供前端路由映射、视图解析等功能。spring框架提供了AOP的编程思想,来管理事务。同时通过IoC实现各层的依赖注入。myabtis集成到spring框架,主要作用在持久层,封装了jdbc,提供了一、二 级缓存。
10.ajax的具体实现流程
- 创建一个异步调用对象。
- 创建一个http请求,并指定该请求的方法,url及验证信息。
- 设置http请求状态变化时的响应函数。
- 发送http请求。
- 获取异步调用返回的数据。
第六,使用js或dom实现局部刷新。
11.线程有几种创建方式
(1)继承Thread父类
(2)实现runnable接口
(3)使用线程池技术
(4)使用Callable实现有返回值的线程
12.sleep() 和 wait() 有什么区别?
类的不同:sleep() 来自 Thread类,wait() 来自 Object类。
释放锁:sleep() 不释放锁;wait() 释放锁。
使用的范围是不同的:wait:只能在同步代码块中使用;sleep:可以在任何地方使用
用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。
13.线程的 run() 和 start() 有什么区别?
start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。
run() 可以重复调用,而 start() 只能调用一次。
第二次调用start() 必然会抛出运行时异常
14.在 Java 程序中怎么保证多线程的运行安全?
- 使用安全类,比如 Java. util. concurrent 下的类。
- 使用自动锁 synchronized。
- 使用手动锁 Lock。
15.使用过触发器吗?
触发器属于数据库中的对象,通常绑定在某个表上,封装一定的功能,当对该表记录进行增删改操作时,触发器会自动触发并执行其封装的功能
16.使用static修饰和不使用static的区别
static修饰的属性和方法属于类,供所有类的对象共享
static访问特点:
非静态成员方法
1.能够访问静态的成员变量;
2.能够访问非静态的成员变量;
3.能够访问静态的成员方法;
4.能够访问非静态的成员方法;
静态的成员方法
1.能够访问静态成员变量,但是不能够直接访问非静态成员变量
2.能够访问静态的成员方法,但是不能够直接访问非静态成员方法
当使用static修饰和不使用static时,有以下不同点:(GPT3.5)
1. 内存分配:
使用static修饰的成员在类加载时分配内存,只有一个副本存在于内存中,而不管创建多少类的实例。
不使用static修饰的成员在每个类的实例创建时分配内存,每个实例都有自己的一份成员变量副本。
2. 访问方式:
静态成员可以通过类名直接访问,如ClassName.staticField或ClassName.staticMethod()。
实例成员需要通过创建类的实例来访问,如Object.instanceField或Object.instanceMethod()。
3. 共享性:
静态成员适用于实现全局变量或单例模式,多个类的实例可以共享相同的静态成员。
实例成员用于存储每个类的实例的状态,每个实例拥有独立的成员变量。
4. 生命周期:
静态成员的生命周期与类相同,一直存在于应用程序的整个生命周期。
实例成员的生命周期与类的实例相关联,当实例被销毁时,实例成员也会被销毁。
5. 适用场景:
静态成员适用于存储与类相关的共享信息,如工具类、常量、计数器等。
实例成员适用于存储与类的每个实例相关的状态信息,如对象的属性。
- 登录怎么实现的,密码加密了嘛?使用明文还是暗文,知道怎么加密嘛?
登录过程:
用户提供用户名和密码。
服务器接收到用户名和密码。
服务器查找数据库以获取与提供的用户名相关联的用户记录。
服务器使用存储在数据库中的用户密码的散列值与用户提供的密码进行比较。
如果密码匹配,则用户成功登录;否则,登录失败。
使用jdk自带的工具类通过MD5加密算法加密。
登录功能的密码加密一般使用哈希算法,比如MD5(128位)、SHA-1(160位)、SHA-256(256位)等。在注册时,用户输入的密码经过哈希算法加密后存储到数据库中。在登录时,用户输入的密码再次经过相同的哈希算法加密,与数据库中存储的加密密码进行比较验证。这样可以确保密码不以明文形式存储,增加了安全性。
18.git有几个仓库,冲突之后怎么解决
git属于团队协作的版本控制技术,支持分布式。通常由本地库和远程库构成。同21
先将本地修改的代码缓存起来,git stash,然后是git pull,然后还原暂存的内容git stash pop,git status查看哪些文件冲突了,就vim打开冲突的文件,把文件里面的冲突标识符删掉,然后再git add,git commit即可。
19.接口和抽象类的区别
(1)抽象类中可以包含抽象方法和普通方法,而接口中只可以包含抽象方法,且abstract可省略
(2)接口是公开的,里面不能有私有的方法或变量,而抽象类是可以有私有方法或私有变量的
(3)实现接口时一定要实现接口里定义的所有方法,而继承抽象类可以有选择地重写需要用到的方法
(4)接口可以实现多重继承,而一个类只能继承一个父类
20.说一下快速排序怎么实现
1. 在数组中选一个基准数(通常为数组第一个;
2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边;
3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序。
快速排序的时间复杂度为O(nlogn),是一种常用且高效的排序算法。
- 说一下线程池中使用的类
1.Executor接口:
2.ExecutorService接口:
3.ThreadPoolExecutor类:
4.Executors工厂类:
5.Future接口:
6.CompletionService接口:
7.ScheduledExecutorService接口:
8.ThreadPoolExecutor工厂类:
9.BlockingQueue接口:
往届回答的是Java中Executors工厂类创建线程池的四个常见方法
(1).newCachedThreadPool
(2).newFixedThreadPool
(3).newSingleThreadExecutor
(4).newScheduleThreadPool
22.对象的创建方式
使用new关键字:
使用反射:
使用对象克隆:
使用工厂方法:
使用单例模式:
使用静态工厂方法:
使用序列化/反序列化:
使用依赖注入框架:
23,浅拷贝和深拷贝的区别
1.浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。 简而言之,需要复用现有对象的基本类型的成员变量数据时,浅拷贝即可。
2.复制整个对象(复制前后两个对象完全一样)。 深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。深拷贝相比于浅拷贝速度较慢并且花销较大。
第一点,深拷贝和浅拷贝的解释
深拷贝:复制整个依赖的变量
浅拷贝:复制过程中只复制一层变量,不会复制深层变量所绑定的变量
第二点,深拷贝和浅拷贝的区别
深拷贝生成的新的列表和原列表没有关系
浅拷贝生成的列表如果修改的不是第一层变量,复制的列表会随之改变,但是如果改变的是第一层的变量,新列表不会修改
两个问题
哪里不同?
都是浅拷贝,但实现方式不同。ArrayList基于System.arraycopy,LinkedList主要依靠自己的循环遍历。
为何不同?
很简单,造成ArrayList和LinkedList各种差异的原因,最终都是由于其底层数据结构不同造成的,前者是数组,后者是链表。
24.前后端分离中前端是如何部署,后端是如何部署
1.前端项目通过Vue框架的脚手架和Node.js工具把项目打包部署到Nginx服务器上
2.后端项目通过Maven打包成war包部署到Tomcat服务器上
3.前后端数据的互通是通过Ajax+Json技术实现的
25.equals和==的区别??
1.基本数据类型,==比较的是两边的值是否相等;引用类型的对象,==比较的是两个对象地址是否相同
2.equals只能比较引用类型的对象,默认比较两个对象内存地址是否一致;重写equals方法的话,先比较的是对象类型,类型相同才会比较对象里面的值
26.字符串使用什么拼接,为什么不使用“+”,stringbuffer VS stringbuilder
编译器每次碰到"+"的时候,会new- 个StringBuilder,接着调用append方法,再调用toString方法,生成新字符串。若代码中有很多"+",就会每个"+"生成一次StringBuilder, 这种方式对内存是一种浪费, 效率很不好。由于这样子拼接字符串的低效,我们才需要使用StringBuilder和StringBuffer来拼接。
StringBuffer和StringBuilder二者的区别主要就是StringBuffer是线程安全的,而StringBuilder是线程不安全的。
27.MySQL分组关键字,去重关键字;主键,外键,约束,视图,索引,接口,实现,查询联合主键(了解英文和概念)
SELECT:用于从数据库中检索数据。
INSERT INTO:用于将新数据插入到数据库表中。
UPDATE:用于修改数据库表中的数据。
DELETE FROM:用于从数据库表中删除数据。
DISTINCT:?可以去除重复的数据
CREATE TABLE:用于创建新的数据库表。
ALTER TABLE:用于修改数据库表结构。
DROP TABLE:用于删除数据库中的表。
INDEX:用于创建索引,优化数据库性能。
JOIN:用于将两个或多个表中的数据相关联。
UNION:用于将两个或多个查询结果集合并。
GROUP BY:用于对查询结果进行分组。
HAVING:用于对分组后的数据进行筛选。
ORDER BY:用于对查询结果进行排序。
LIMIT:用于限制查询结果的数量。
主键是一种用于唯一标识表中每一行数据的标识符。在Mysql中,主键可以是一个或多个列的组合,但是必须满足以下条件:
- 主键列的值必须唯一,不能重复。
- 主键列的值不能为空,不能为NULL。
- 一个表只能有一个主键。
外键是一个表中的一列或多列,其值必须匹配另一个表中的主键值或唯一值
约束:约束是对表中数据进行限制的规则。约束可以是列级别或表级别。列级别约束只对单个列起作用,而表级别约束则对整个表起作用。
索引:索引是一种特殊的数据结构,它提供了快速访问表中特定行的方法。索引可以在单个列上创建,也可以在多个列上创建。
28.MySQL常用的引擎(英文)
- InnoDB存储引擎
- MyISAM存储引擎
- Memory存储引擎
- CSV存储引擎
- Archive
29.分组后的聚合函数,最小,最大,平均
30.MySQL子查询关键字
any,all,exist,in
in关键字主要用于查找属性值是否属于指定的集合,属于比较常用的一个
any关键字用来表示父查询满足子查询结果的任意一个值,可以和比较运算符进行
all关键字用来表示父查询满足子查询结果的所有值,可以和比较运算符进行
关键字exists用来判断子查询是否返回结果集
31.Java循环关键字,跳出循环,彻底跳出循环,跳出一层循环
- while循环 2.do-while循环 3.for循环 4.for-each循环
break:跳出当前循环。
continue:跳过当前迭代,继续下一次迭代。
使用标签(label)和break:跳出嵌套循环中的一层循环。
- ?java中常见跳出循环的方式一般有两种,一种是常用的break,continue,return方式;另一种是循环标记的方式。
32.Java异常的描述,finally通常放什么业务代码
Java中的异常分为两大类:编译时异常和运行时异常,也被称为受检异常和非受检异常。所有的RuntimeException类及子类都被称为运行时异常,其他的异常都是编译时异常
编译时异常:必须显示处理,否则程序会发生错误,无法通过编译;
运行时异常:无需显示处理,也可以通过编译时异常一样处理;
finally:一般用于资源释放,断开连接,关闭管道流等
一般搭配try -- catch --finally? 或者 try --- finally
一般来说无论try中是否抛出异常,都会执行finally。
final:
1.final 是一个关键字,用于声明不可变的特性。
2.当应用于类时,final 表示该类不能被继承,即它是一个最终类,不能有子类。
3.当应用于方法时,final 表示该方法不能被子类重写。
4.当应用于变量时,final 表示该变量是一个常量,只能被赋值一次,之后不能再修改
finally:
1.finally 是一个关键字,用于结构化异常处理,通常与 try 和 catch 结合使用。
2.无论是否发生异常,finally 代码块中的代码都会被执行。
3.它通常用于确保资源(如文件、数据库连接等)被正确关闭,以防止资源泄漏。
总结:
final 用于声明不可变性,可以应用于类、方法和变量。
finally 用于结构化异常处理,确保代码块中的代码得到执行,通常用于资源管理和清理。
33.Java基本数据类型,包装类和基本数据类型的区别
34.数据库中空值和null的区别
- 空值是字段值为空,但保留了字段的数据类型。
- NULL是一个特殊的值,表示缺失、未知或不适用的数据。
35.Java4个访问修饰符
public、protected、default(无修饰符,默认)、private
36.JDK VS JRE
JDK用于开发Java应用程序,JRE用于运行Java应用程序。
JDK和JRE都可以单独安装,若不需要开发Java程序,只需要运行的话,那么,只用安装JRE即可。
37.子查询的关键字:exist VS in
- EXISTS关键字用于检查子查询中是否存在结果,返回布尔值。
- IN关键字用于比较一个值是否在子查询的结果集中,返回布尔值。
- EXISTS关键字关注的是结果是否存在,而IN关键字关注的是值是否匹配。
- Servlet生命周期
- web容器加载Servlet类?
- 实例化
- 初始化init
- 处理请求 service 进一步调用doGet/doPost方法
- ?销毁 destory
39.springboot自动装配原理,spring?aop思想,切面是什么
Spring Boot自动装配原理: Spring Boot的自动装配原理是基于Spring的IoC和依赖注入的机制。当引入一个Spring Boot Starter依赖时,它会自动扫描并加载相关的配置类和组件,完成对应的配置和初始化工作。
Spring AOP是一种面向切面编程的思想,用于将横切关注点与核心业务逻辑解耦。它通过切面定义通知和切点,在特定连接点上执行相应的业务逻辑,实现日志记录、事务管理、异常处理等功能。
切面是AOP中的模块化横切关注点,包含一系列通知和切点的定义。切面通过将横切关注点应用到特定连接点上,实现与核心业务逻辑的解耦,提高代码的可重用性和可维护性。
总的来说,Spring Boot的自动装配原理和Spring AOP思想及切面的概念都是为了实现代码的模块化、可重用和易于维护。它们在Spring框架中起到了重要的作用。
40.已知文件名,linux用什么命令查找文件?*代表什么?
在使用linux时,经常需要进行文件查找。其中查找的命令主要有find和grep。两个命令是有区的。
区别:
(1)find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间等。?
? ? ? ? ?(2)grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找。
41.什么是注解
Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。
42.Redis的数据类型,以及对Redis的理解
String,字符串??Hash,散列??List,列表??Set,集合??Sorted set
43、创建多线程的方式
方式一:编写一个类,直接继承Thread类并重写run()方法
方式二:编写一个类,实现Runnable接口并重写run()方法
方式三:实现Callable接口(JDK8新特性)
方式四:使用线程池技术
44.preparestatement和statement的区别
关系:PreparedStatement继承自Statement,都是接口
区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高
45.String、StringBuffer、StringBuilder的区别??
?1、String类型的字符串对象是不可变的,一旦String对象创建后,包含在这个对象中的字符序列是不可以改变的,直到这个对象被销毁。
2、StringBuilder和StringBuffer类型的字符串是可变的,不同的是StringBuffer类型的是线程安全的,而StringBuilder不是线程安全的
3、如果是多线程环境下涉及到共享变量的插入和删除操作,StringBuffer则是首选。如果是非多线程操作并且有大量的字符串拼接,插入,删除操作则StringBuilder是首选。
46.jdbc的使用过程((Java Database connect))?
1、加载JDBC驱动程序;
2、基于JDBC连接的URL,创建数据库的连接;
3、创建数据库操作对象,如Statement对象,执行SQL语句进行CURD操作;
4、关闭JDBC对象,释放资源。
47.MySQL的理解
MySQL是一种开源的关系型数据库管理系统,具有跨平台、高性能、可扩展、数据安全性、多语言支持、强大的功能等优势。它被广泛应用于各种Web应用和企业级应用中。
48.java的反射及应用场景(获取元数据,提高代码通用性)
反射是Java语言提供的一种机制,允许程序在运行时检查和操作类、方法、字段等元数据。通过反射,代码可以在运行时获取类的信息,创建实例,调用方法和访问字段。
反射的应用场景包括:
- 动态加载类:通过反射可以在运行时根据配置文件或用户输入加载类,实现插件化或动态扩展的功能。
- 设计模式:一些设计模式(如工厂模式)利用反射来实例化对象,以减少代码的耦合度。
- 框架开发:框架通常需要在运行时读取类的信息,以便进行自动化配置、依赖注入等操作。
- 测试工具:测试工具可以使用反射来检查类的状态、调用私有方法或修改私有字段,以便进行单元测试。
- 序列化和反序列化:通过反射,可以将对象转化为字节流或将字节流转化为对象,实现对象的存储和恢复。
总体来说,反射提供了一种在运行时操作类和对象的能力,使程序更加灵活和通用,但使用反射也需要注意性能和安全性的问题。
49.解释多线程
多线程:多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务。
50.Java中的锁
总结一下,对于JDK 8版本,在Java中实现锁机制可以使用以下几种方式:
- synchronized关键字:使用synchronized关键字对方法或代码块进行同步,实现对象级别的锁和类级别的锁。
- ReentrantLock类:使用ReentrantLock类来实现锁机制,通过调用lock()方法获取锁,调用unlock()方法释放锁。可以选择公平锁或非公平锁,并支持可重入性和tryLock()方法。
- ReadWriteLock接口:通过ReentrantReadWriteLock实现读写锁机制,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。
- Condition接口:使用Lock对象的newCondition()方法获取与锁关联的Condition对象,实现条件等待或唤醒等待的线程。
这些是在JDK 8版本中常用的锁机制。它们可以用于实现同步和互斥,保证多线程访问共享资源的安全性。在使用锁机制时要注意锁的粒度和避免死锁等问题。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!