第三次面试

it2026-06-07  0

1.JDK1.8的新特性有哪些

速度更快 – 红黑树 代码更少 – Lambda 强大的Stream API – Stream 便于并行 – Parallel 最大化减少空指针异常 – Optional

1.Lambda表达式 2.新的日期API:发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。 新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作 原因:

java.util.Date 是非线程安全的时区处理麻烦设计很差:java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期

3.Base64编码:

base64是网络上最常见的用于传输8bit字节代码的编码方式之一。有时我们需要把二进制数据编码为适合放在URL中的形式。这时采用base64编码具有不可读性,即所编码的数据不会被人直接看出。用于在http环境下传递较长的标识信息。

4.接口的默认方法和静态方法: 允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法 代码实现

5.并行流:

Fork/Join框架: 在必要的情况下,将一个大任务进行必要的拆分Fork成若干个小任务,再将小任务的运算结果进行Join汇总。Fork/Join框架和传统线程池的区别: 采用“工作窃取”模式(Working-stealing),即当执行新的任务时它可以将其拆分分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中并行流将会充分使用多核的优势,多线程并行执行,基数越大,效果越明显。其底层还是Fork/Join框架

6.Optional 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用null 表示一个值不存在,现在Optional 可以更好的表达这个概念。并且可以避免空指针异常。

2.实现多线程的几种方法

1.继承Thread类2.实现Runnable接口3.直接在函数体使用(匿名内部类)

实现RunnabLe接口创建多线程程序的好处:

避免了单继承的局限性 一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类 实现了RunnabLe接口,还可以继承其他的类,实现其他的接口增强了程序的扩展性,降低了程序的耦合性(解耦) 实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦) 实现类中,重写了run方法:用来设置线程任务 创建Thread类对象,调用start方法:用来开启新线程

3.数据结构

4.MySQL数据库

5.SSM项目有什么大坑,怎么解决的

6.Spring的AOP一般用来干嘛

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

采用filter技术对字符集进行处理日志记录性能统计安全控制事务处理异常处理

实现AOP的几种方式

1.方式一
<!--方式一:使用原生Spring API接口--> <!--配置aop:需要导入aop的约束--> <aop:config> <!--切入点 expression:表达式 ,execution(要执行的位置! * * * * )--> <aop:pointcut id="pointcut" expression="execution(* com.whz.service.UserServiceImp.*(..))"/> <!--执行环绕增加--> <aop:advisor advice-ref="log" pointcut-ref="pointcut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> </aop:config> <!--注册bean--> <bean id="userServiceImp" class="com.whz.service.UserServiceImp"></bean> <bean id="log" class="com.whz.log.Log"></bean> <bean id="afterLog" class="com.whz.log.AfterLog"></bean> public class Log implements MethodBeforeAdvice { /*method:要执行的目标对象的方法 args:参数 target:目标对象 */ public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行了 "); } } public class AfterLog implements AfterReturningAdvice { // public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("执行了"+method.getName()+"方法,返回结果为"+returnValue); } }
2.方式二
<!--方式二:自定义类--> <bean id="diy" class="com.whz.diy.DiyPointCut"></bean> <aop:config> <!--自定义切面,ref要引用的类--> <aop:aspect ref="diy"> <!--切入点--> <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImp.*(..))"/> <!--通知--> <aop:before method="before" pointcut-ref="pointcut"></aop:before> <aop:after method="after" pointcut-ref="pointcut"></aop:after> </aop:aspect> </aop:config> public class DiyPointCut { public void before(){ System.out.println("==========之前========="); } public void after(){ System.out.println("==========之后========="); } }
3.方式三
<!--方式三:注解--> <bean id="annotationPointCut" class="com.whz.diy.AnnotationPointCut"/> //方式三:使用注解实现aop @Aspect//标注这个类是个切面 public class AnnotationPointCut { @Before("execution(* com.whz.service.UserServiceImp.*(..))") public void before(){ System.out.println("++++++++++before++++++++++++"); } @After("execution(* com.whz.service.UserServiceImp.*(..))") public void after(){ System.out.println("++++++++++after++++++++++++"); } }
4.Test
//测试类 public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //动态代理代理的是接口 UserService userService = (UserService) context.getBean("userServiceImp"); userService.delete(); userService.add(); } }

7.MySQL的左外连接的执行顺序

左外连接和右外连接查询: (1) 左外连接查询:是将左边表中所有数据都查询出来, 如果在右边表中没有对应的记录, 右边表显示为null即可。 以左侧表为主,不管on条件是否满足条件,左侧表的所有记录都会返回。 换句说:on and后面的条件对左侧表没有过滤作用,即使加上对左侧表的过滤,也不起作用 on后面的条件对右侧表的过滤起作用。where条件则对左连接后的临时表数据进行筛选。 (2) 右外连接查询:是将右边表中所有数据都查询出来, 如果在左边表中没有对应的记录, 左边表显示为null即可。

where和having都用于筛选过滤,但是: (1) where用于在分组之前进行筛选, having用于在分组之后进行筛选 (2) 并且where中不能使用列别名, having中可以使用别名 (3) where子句中不能使用列别名(可以使用表别名), 因为where子句比select先执行

SQL语句的书写顺序和执行顺序: SQL语句的书写顺序: select… from… where… group by… order by… … SQL语句的执行顺序: from… – 确定要查询的是哪张表 (定义表别名) where… – 从整张表的数据中进行筛选过滤 group by… – 根据指定的列进行分组 select… – 确定要显示哪些列 (定义列别名) order by… – 根据指定的列进行排序

8.JDK实现动态代理

1、为接口创建代理类的字节码文件

2、使用ClassLoader将字节码文件加载到JVM

3、创建代理类实例对象,执行对象的目标方法 结合源码分析,JDK如何实现动态代理

自己手写一个底层动态代理

9.Spring 的事务及实现

事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。

在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性

事务有四个特性:ACID

原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

10.Session和Cookie的区别

cookie数据保存在客户端,session数据保存在服务器端存储容量不同 单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。 对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。存储方式不同 cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。 session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。隐私策略不同 cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。 session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。有效期上不同 开发可以通过设置cookie的属性,达到使cookie长期有效的效果。 session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。服务器压力不同 cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。 session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。浏览器支持不同 假如客户端浏览器不支持cookie: cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。 运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。 假如客户端支持cookie: cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。 session只能在本窗口以及子窗口内有效。跨域支持上不同 cookie支持跨域名访问。 session不支持跨域名访问

用cookie和session实现登录功能

11.常用的日志框架

Log4J:日志大炮 Log4J 是 Apache 的一个日志开源框架,有多个分级(DEBUG/INFO/WARN/ERROR)记录级别,可以很好地将不同日志级别的日志分开记录,极大地方便了日志的查看。LogBack:日志火箭 LogBack 其实可以说是 Log4J 的进化版,因为它们两个都是同一个人(Ceki Gülcü)设计的开源日志组件。LogBack 除了具备 Log4j 的所有优点之外,还解决了 Log4J 不能使用占位符的问题。

12.从输入URL到整个网页加载完毕及显示在屏幕上的整个流程

1、首先,在浏览器地址栏中输入url 2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。 3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。 4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。 5、握手成功后,浏览器向服务器发送http请求,请求数据包。 6、服务器处理收到的请求,将数据返回至浏览器 7、浏览器收到HTTP响应 8、读取页面内容,浏览器渲染,解析html源码 9、生成Dom树、解析css样式、js交互 10、客户端和服务器交互 11、ajax查询

最新回复(0)