❤️连续面试失败后,我总结了57道面试真题❤️,如果时光可以倒流...(附答案,建议收藏)

Posted 哪 吒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❤️连续面试失败后,我总结了57道面试真题❤️,如果时光可以倒流...(附答案,建议收藏)相关的知识,希望对你有一定的参考价值。

金九银十,狂热的招聘季在悄声无息间开始了,小编也去尝试了一波,被杀的体无完肤,面试官问的和我想的根本不在一个节拍,现在就将最近失败的面试经历分享给大家,全搞懂的话,相当于你接到了5个offer,很负责任的告诉大家,这些都是我在面试过程中,面试官问我的,如果我先总结了这篇文章,结果一定会大相径庭。

目录

1、实例化对象有哪几种方式

2、你用过单点登录吗?是如何实现的?

3、说一下什么是Spring IOC和AOP?

4、说一下AOP都有哪些基本理念?

5、再说一下AOP的使用场景

 6、说一下Spring的常用注解都有哪些?

7、Springboot比spring多哪些注解

8、项目中是如何实现权限验证的,权限验证需要几张表

9、谈谈controller,接口调用的路径问题

10、mybatis中resultType和resultMap有什么区别?

 11、myBatis查询多个id、myBatis常用属性

12、Oracle分页sql

13、oracle中如何进行分组排序取top3

14、数据库如何保证主键唯一性

 15、Redis单线程多线程

 16、JVM栈堆概念,何时销毁对象

17、Spring中都应用了哪些设计模式

18、简单介绍一下springboot

19、Spring Boot和Spring MVC有什么区别?

20、websocket应用的是哪个协议

21、Spring Boot如何访问不同的数据库

 22、做过程序设计吗?

23、说一下cookie、session、token有什么区别?

24、如何设计数据库

25、性别是否适合做索引

26、如何查询重复的数据

27、查询网站在线人数

28、Redis取值存值问题

29、mybatis一级缓存、二级缓存

30、concurrentHashMap和HashTable有什么区别

31、hashmap存储的数据结构

32、HasmMap和HashSet的区别

33、synerchronized原理

34、什么是CAS

 35、byte类型127+1等于多少

36、数据库一般会采取什么样的优化方法?

37、说一下事务的隔离级别

38、Object常用方法

39、beanFactory和factoryBean的区别

40、索引怎么定义,分哪几种

41、简单介绍一下Java多线程

42、easyExcel如何实现

43、ArrayList 和 Vector 的区别是什么?

44、Array 和 ArrayList 有何区别?

45、除了 ReetrantLock,你还接触过 JUC 中的哪些并发工具?

46、请谈谈 ReadWriteLock 和 StampedLock。

47、说一下 tcp 粘包是怎么产生的?

48、举一个用 Java 实现的装饰模式(decorator design pattern)?它是作用于对象层次还是类层次?

49、请举例说明如何在 Spring 中注入一个 Java Collection?

50、什么是 Swagger?你用 Spring Boot 实现了它吗?

51、什么是 Spring Profiles?

52、在 hibernate 中使用 Integer 和 int 做映射有什么区别?

53、mysql 的内连接、左连接、右连接有什么区别?

54、Redis支持的数据类型有哪些?

55、详细介绍一下 CMS 垃圾回收器?

56、新生代垃圾回收器和老生代垃圾回收器都有哪些?有什么区别?

57、简述分代垃圾回收器是怎么工作的?


1、实例化对象有哪几种方式

纳尼?这么简单的问题,new一下不就好了?

  • new
  • clone()
  • 通过反射机制创建
//用 Class.forName方法获取类,在调用类的newinstance()方法
Class<?> cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();
  • 序列化反序列化
//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/data.txt"));
//序列化对象
out.writeObject(user1); 
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/data.txt"));
User user2 = (User) in.readObject();
System.out.println("反序列化user:" + user2);
in.close();

2、你用过单点登录吗?是如何实现的?

(1)概念

单点登录SSO,说的是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。

(2)单点登录的要点

①存储信任;

②验证信任;

(3)实现单点登录的三种方式

① 以cookie作为凭证

最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。

用户登录父应用之后,应用返回一个加密的cookie,当用户访问子应用的时候,携带上这个cookie,授权应用解密cookie进行校验,校验通过则登录当前用户。

缺点:

  • cookie不安全

通过加密可以保证安全性,但如果对方掌握了解密算法就完蛋了。

  • 不能跨域实现免登

② 通过JSONP实现

对于跨域问题,可以使用JSONP实现。用户在父应用中登录后,跟session匹配的cookie会存到客户端中,当用户需要登录子应用的时候,授权应用访问父应用提供的JSONP接口,并在请求中带上父应用域名下的cookie,父应用接收到请求,验证用户的登录状态,返回加密的信息,子应用通过解析返回来的加密信息来验证用户,如果通过验证则登录用户。

缺点:

这种方法虽然能解决跨域问题,但是治标不治本,没有解决cookie安全性的问题。

③ 通过页面重定向的方式

最后一种介绍的方式,是通过父应用和子应用来回重定向进行通信,实现信息的安全传递。

父应用提供一个GET方式的登录接口A(此时的父应用接口固定,攻击者无法去伪造),用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个登录页面,用户输入账号密码进行登录,如果用户已经登录了,则生成加密的token,并且重定向到子应用提供的验证token的接口B(此时的子应用接口固定,攻击者无法去伪造),通过解密和校验之后,子应用登录当前用户。

缺点:

这种方式较前面的两种方式,是解决了安全性和跨域的问题,但是并没有前面两种方式简单,安全与方便,本来就是矛盾的。

(4)使用独立登录系统

一般来说,大型应用会把授权的逻辑和用户信息的相关逻辑独立成一个应用,称为用户中心。用户中心不处理业务逻辑,只是处理用户信息的管理以及授权给第三方应用。第三方应用需要登录的时候,则把用户的登录请求转发给用户中心进行处理,用户处理完毕后返回凭证,第三方应用验证凭证,通过后就登录用户。

(5)sso(单点登录)与OAuth2.0(授权)的区别?

① sso(单点登录)

通常处理的是一个公司的不同应用间的访问登录问题,如企业应用有很多子系统,只需登录一个系统,就可以实现不同子系统间的跳转,而避免了登录操作;
通过cookie、jsonp、重定向来实现;

② OAuth2.0(授权)

解决的是服务提供方(如微信)给第三方应用授权的问题,简称微信登录;
是一种具体的协议,只是为用户资源的授权提供了一个安全的、开放的而又简易的标准,OAuth2.0(授权)为客户开发者开发web应用,桌面应用程序,移动应用及客厅设备提供特定的授权流程。

3、说一下什么是Spring IOC和AOP?

(1)什么是AOP?

AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,Struts2的拦截器设计就是基于AOP的思想,是个比较经典的例子。

在不改变原有逻辑的基础上,增加了一些额外的功能。代理也是这个功能,读写分离也是用AOP来实现的。

(2)AOP与OOP

AOP可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

(3)AOP

AOP技术恰恰相反,它利用一种称为“切面”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用的模块,并将其命名为“Aspect”,即切面。所谓“切面”,简单说就是那些与业务无关,却被业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多出,而各处基本相似,比如权限认证、日志、事务。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

4、说一下AOP都有哪些基本理念?

这个问题刚开始听到的时候,有些蒙蔽,AOP基本理念?什么鬼?我就将AOP的一些关键点说了一下,没想到面试官还挺满意,要学会变量的答题,不是面试官说什么就答什么,谁也不能保证都会。

(1)横切关注点

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点;

(2)Aspect(切面)

通常是一个类,里面可以定义切入点和通知。

(3)JoinPoint(连接点)

程序执行过程中明确的点,一般是方法的调用,被拦截到的点。因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。

(4)Advice(通知)

AOP在特定的切入点上执行的增强处理,有before(前置)、after(后置)、afterReturning(最终)、afterThrowing(异常)、around(环绕)。

(5)Pointcut(切入点)

带有通知的连接点,在程序中主要体现在书写切入点表达式。

(6)weave(织入)

将切面应用到目标对象并导致代理对象创建的过程。

(7)introduction(引入)

在不修改代码的前提下,引入可以在运行期为类动态地增加一些方法或字段。

(8)AOP代理(AOP Proxy)

AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类。

(9)目标对象(Target Object)

包含连接点的对象,也被称作被通知或被代理对象,POJO。

5、再说一下AOP的使用场景

我去,这面试官和Spring可上了,我服!

1、Authentication 权限
2、Caching 缓存
3、Context passing 内容传递
4、Error handling 错误处理
5、Lazy loading 懒加载
6、Debugging  调试
7、logging, tracing, profiling and monitoring 记录跟踪 优化 校准
8、Performance optimization 性能优化
9、Persistence  持久化
10、Resource pooling 资源池
11、Synchronization 同步
12、Transactions 事务、

客官,你还满意?

当我说到第七个应该场景的时候,面试官说可以了,哈哈,,耳朵起茧子了吧

6、说一下Spring的常用注解都有哪些?

实在太多,小编整理了一个专门的博客。

Spring常用注解

7、Springboot比spring多哪些注解

Spring Boot常用注解

8、项目中是如何实现权限验证的,权限验证需要几张表

我是用SpringSecuriy进行权限验证的,通过gateway进行路径的拦截,权限验证,权限验证大概就是根据roll的值进行判断,1普通用户2VIP用户4管理员,组成了类似于Linux中rwx的权限管理方法。

大概使用五张表,用户、角色、权限、还有用户与角色的关系表、角色和权限的关系表。

9、谈谈controller,接口调用的路径问题

(1)Spring MVC如何匹配请求路径

@RequestMapping是用来映射请求的,比如get请求、post请求、或者REST风格与非REST风格的。该注解可以用在类上或方法上,如果用在类上,表示是该类中所有方法的父路径。

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {
    @RequestMapping("/testRequestMapping")
    public String testRequestMapping(){
        System.out.println("testRequestMapping");
        return SUCCESS;
    }
}

在类上还添加了一个@Controller注解,该注解在SpringMVC中负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个model,然后再把该model返回给对应的view进行展示。

我们可以通过“springmvc/testRequestMapping”这个路径来定位到testRequestMapping这个方法,然后执行方法内的方法体。

RequestMapping可以实现模糊匹配路径,比如:

  • ?表示一个字符;
  • *表示任意字符;
  • **匹配多层路径;

/springmvc/**/testRequestMapping 就可以匹配/springmvc/stu/getStudentInfo/testRequestMapping 这样的路径了。

(2)SpringMVC如何获取请求的参数

@PathVariable

该注解用来映射请求URL中绑定的占位符。通过@PathVariable可以将URL中占位符的参数绑定到controller处理方法的入参中。

@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable(value="id") Integer id){
    System.out.println("testPathVariable:" + id);
    return SUCCESS;
}

@RequestParam

该注解也是用来获取请求参数的,那么该注解和@PathVariable有什么不同呢?

@RequestMapping(value="/testRequestParam")
public String testRequestParam(@RequestParam(value="username") String username, @RequestParam(value="age", required=false, defaultValue="0") int age){
    System.out.println("testRequestParam" + " username:" + username + " age:" +age);
    return SUCCESS;
}

 (3)REST风格的请求

在SpringMVC中业务最多的应该是CRUD了

@RequestMapping(value="/testRest/{id}", method=RequestMethod.PUT)
public String testRestPut(@PathVariable(value="id") Integer id){
    System.out.println("test put:" + id);
    return SUCCESS;
}
     
@RequestMapping(value="/testRest/{id}", method=RequestMethod.DELETE)
public String testRestDelete(@PathVariable(value="id") Integer id){
    System.out.println("test delete:" + id);
    return SUCCESS;
}
     
@RequestMapping(value="/testRest", method=RequestMethod.POST)
public String testRest(){
    System.out.println("test post");
    return SUCCESS;
}
     
@RequestMapping(value="/testRest/{id}", method=RequestMethod.GET)
public String testRest(@PathVariable(value="id") Integer id){
    System.out.println("test get:" + id);
    return SUCCESS;
}

10、mybatis中resultType和resultMap有什么区别?

(1)resultType是直接表示返回类型的(对应着我们的model对象中的实体)

(2)resultMap则是对外部ResultMap的引用(提前定义了db和model之间的隐射key-->value关系),但是resultType跟resultMap不能同时存在。

 11、myBatis查询多个id、myBatis常用属性

myBatis查询多个id(我居然回答用对象来传递...)

Page<UserPoJo>  getUserListByIds(@Param("ids") List<Integer> ids);
<!--根据id列表批量查询user-->
<select id="getUserListByIds" resultType="com.guor.UserPoJo">
    select * from student
    where id in
    <foreach collection="ids" item="userid" open="(" close=")" separator=",">
        #{userid}
    </foreach>
</select>

12、Oracle分页sql

#不带排序的
SELECT * FROM (
SELECT ROWNUM AS rowno, t.* FROM worker t where ROWNUM <=20) table_alias 
WHERE table_alias.rowno > 10;
#带排序的
SELECT * FROM (
SELECT tt.*, ROWNUM AS rowno FROM (  
SELECT t.* FROM worker t ORDER BY wkid aSC) tt WHERE ROWNUM <= 20) table_alias 
WHERE table_alias.rowno >= 10;

13、oracle中如何进行分组排序取top3

SELECT *
  FROM (SELECT ROW_NUMBER() OVER(PARTITION BY prov ORDER BY counts DESC) rn,
               prov,
               kpi,
               counts
          FROM tab_a a)
 WHERE rn < 3

14、数据库如何保证主键唯一性

(1)主键约束

主键列上没有任何两行具有相同值(即重复值),不允许空(NULL);

(2)唯一性约束

保证一个字段或者一组字段里的数据都与表中其它行的对应数据不同。和主键约束不同,唯一性约束允许为null,但是只能有一行;

(3)唯一性索引

不允许具有索引值相同的行,从而禁止重复的索引和键值;

(4)三者的区别

  • 约束是用来检查数据的正确性;
  • 索引是用来优化查询的;
  • 创建唯一性约束会创建一个约束和一个唯一性索引;
  • 创建唯一性索引只会创建一个唯一性索引;
  • 主键约束和唯一性约束都会创建一个唯一性索引。

 15、Redis单线程多线程

Redis是单线程的

Redis 是跑在单线程中的,所有的操作都是按照顺序线性执行的,但是由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务,而 I/O 多路复用就是为了解决这个问题而出现的。

Redis6.0之后引入多线程,Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。

 16、JVM栈堆概念,何时销毁对象

  1. 类在程序运行的时候就会被加载,方法是在执行的时候才会被加载,如果没有任何引用了,Java自动垃圾回收,也可以用System.gc()开启回收器,但是回收器不一定会马上回收。
  2. 静态变量在类装载的时候进行创建,在整个程序结束时按序销毁;
  3. 实例变量在类实例化对象时创建,在对象销毁的时候销毁;
  4. 局部变量在局部范围内使用时创建,跳出局部范围时销毁;

17、Spring中都应用了哪些设计模式

这道题我答的惨不忍睹,设计模式倒是用过几个,你问我spring中都应用了哪些,这有点过分了吧。

(1)简单工厂模式

简单工厂模式的本质就是一个工厂类根据传入的参数,动态的决定实例化哪个类。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象。

(2)工厂方法模式

应用程序将对象的创建及初始化职责交给工厂对象,工厂Bean。

定义工厂方法,然后通过config.xml配置文件,将其纳入Spring容器来管理,需要通过factory-method指定静态方法名称。

(3)单例模式

Spring用的是双重判断加锁的单例模式,通过getSingleton方法从singletonObjects中获取bean。

(4)代理模式

Spring的AOP中,使用的Advice(通知)来增强被代理类的功能。Spring实现AOP功能的原理就是代理模式(① JDK动态代理,② CGLIB字节码生成技术代理。)对类进行方法级别的切面增强。

(5)装饰器模式

装饰器模式:动态的给一个对象添加一些额外的功能。

Spring的ApplicationContext中配置所有的DataSource。这些DataSource可能是不同的数据库,然后SessionFactory根据用户的每次请求,将DataSource设置成不同的数据源,以达到切换数据源的目的。

在Spring中有两种表现:

一种是类名中含有Wrapper,另一种是类名中含有Decorator。

(6)观察者模式

定义对象间的一对多的关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

Spring中观察者模式一般用在listener的实现。

(7)策略模式

策略模式是行为性模式,调用不同的方法,适应行为的变化 ,强调父类的调用子类的特性 。

getHandler是HandlerMapping接口中的唯一方法,用于根据请求找到匹配的处理器。

(8)模板方法模式

Spring JdbcTemplate的query方法总体结构是一个模板方法+回调函数,query方法中调用的execute()是一个模板方法,而预期的回调doInStatement(Statement state)方法也是一个模板方法。

 18、简单介绍一下springboot

(1)Spring是什么

Spring框架为开发Java应用程序提供了全面的基础架构支持。它包含一些很好的功能,如依赖注入和开箱即用的模块,如Spring JDBC、Spring MVC、Spring Security、Spring AOP、Spring ORM、Spring Test。这些模块缩短应用程序的开发时间,提高了应用开发的效率。

(2)Spring Boot是什么

Spring Boot是Spring框架的扩展,它消除了设置Spring应用程序所需的XML配置,更快、更高效。

以下是Spring Boot中的一些特点:

  • 嵌入tomcat,而且不需要部署tomcat;
  • 提供的starter来简化maven配置;
  • 创建Spring Boot项目时可以选择Spring应用;
  • 提供外部化配置;
  • 不需要配置xml了;

(3)MVC配置

Spring需要定义调度程序servlet,映射和其它支持配置。我们可以使用web.xml文件或Initializer类来完成此操作。

public class MyWebAppInitializer implements WebApplicationInitializer { 
    @Override 
    public void onStartup(ServletContext container) { 
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); 
        context.setConfigLocation("com.pingfangushi"); 
          container.addListener(new ContextLoaderListener(context)); 
          ServletRegistration.Dynamic dispatcher = container 
          .addServlet("dispatcher", new DispatcherServlet(context)); 
        dispatcher.setLoadOnStartup(1); 
        dispatcher.addMapping("/"); 
    } 
} 

还需要将@EnableWebMvc注释添加到@Configuration类,并定义一个视图解析器来解析从控制器返回的视图:

@EnableWebMvc 
@Configuration 
public class ClientWebConfig implements WebMvcConfigurer {  
   @Bean 
   public ViewResolver viewResolver() { 
      InternalResourceViewResolver bean 
        = new InternalResourceViewResolver(); 
      bean.setViewClass(JstlView.class); 
      bean.setPrefix("/WEB-INF/view/"); 
      bean.setSuffix(".jsp"); 
      return bean; 
   } 
} 

和上述操作相比,Spring Boot只需在application配置文件中配置间隔属性就能完成上述操作:

spring.mvc.view.prefix=/WEB-INF/jsp/ 
spring.mvc.view.suffix=.jsp 

(4)配置模板引擎 Thymeleaf

在Spring中,我们需要为视图解析器添加thymeleaf-spring5依赖项和一些配置:

@Configuration 
@EnableWebMvc 
public class MvcWebConfig implements WebMvcConfigurer { 
 
    @Autowired 
    private ApplicationContext applicationContext; 
 
    @Bean 
    public SpringResourceTemplateResolver templateResolver() { 
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); 
        templateResolver.setApplicationContext(applicationContext); 
        templateResolver.setPrefix("/WEB-INF/views/"); 
        templateResolver.setSuffix(".html"); 
        return templateResolver; 
    } 
 
    @Bean 
    public SpringTemplateEngine templateEngine() { 
        SpringTemplateEngine templateEngine = new SpringTemplateEngine(); 
        templateEngine.setTemplateResolver(templateResolver()); 
        templateEngine.setEnableSpringELCompiler(true); 
        return templateEngine; 
    } 
 
    @Override 
    public void configureViewResolvers(ViewResolverRegistry registry) { 
        ThymeleafViewResolver resolver = new ThymeleafViewResolver(); 
        resolver.setTemplateEngine(templateEngine()); 
        registry.viewResolver(resolver); 
    } 
} 

Spring Boot直接添加spring-boot-starter-thymeleaf依赖就行了。

(5)Spring Security 配置

Spring需要依赖spring-security-web和spring-security-config 模块。

接下来, 我们需要添加一个扩展WebSecurityConfigurerAdapter的类,并使用@EnableWebSecurity注解:

@Configuration 
@EnableWebSecurity 
public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { 
 
    @Autowired 
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { 
        auth.inMemoryAuthentication() 
          .withUser("admin") 
            .password(passwordEncoder() 
            .encode("password")) 
          .authorities("ROLE_ADMIN"); 
    } 
 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
        http.authorizeRequests() 
          .anyRequest().authenticated() 
          .and() 
          .httpBasic(); 
    } 
 
    @Bean 
    public PasswordEncoder passwordEncoder() { 
        return new BCryptPasswordEncoder(); 
    } 
} 

Spring Boot添加spring-boot-starter-security依赖就行了。

(6)Spring支持传统的web.xml,SpringBoot使用嵌入式容器来运行程序,Spring Boot使用main

法来启动嵌入式web服务器,它还负责将servlet、filter、ServletContextInitializer bean从应用程序上下文绑定到嵌入式servelet容器。

(7)打包和部署

Spring和Spring Boot都支持maven和Gradle通用打包管理技术。

Spring Boot相对Spring的一些优点:

  • 提供嵌入式容器支持;
  • 使用命令java -jar独立运行jar;
  • 部署时可以灵活指定配置文件;

19、Spring Boot和Spring MVC有什么区别?

Spring框架有很多衍生产品,例如Spring Boot、Spring MVC、Spring Security等等,但是他们的基础都是Spring的IOC和AOP。

IOC提供了依赖注入的容器,AOP提供了面向切面编程,然后在这两者的基础上实现了其它延伸产品的高级功能。

Spring MVC是一种松耦合的方式开发web应用的框架。

通过Dispatcher Servlet, ModelAndView 和 View Resolver,开发web应用变得很容易。解决的问题领域是网站应用程序或者服务开发--url路由、session、模板引擎、静态web资源等等。

Spring Boot实现了自动配置,降低了项目搭建的复杂度。

Spring Boot主要为了解决Spring框架需要大量配置太麻烦的问题。同时集成了很多第三方库(例如JDBC、Redis等),Spring Boot中的第三方库基本都是零配置的开箱即用。

对于我们来说,换成Spring Boot之后,项目初始化方法变了,配置文件变了,不需要安装tomcat了,maven打包jar就能直接部署运行了,但你最核心的业务逻辑实现与业务流程实现没有任何变化。

20、websocket应用的是哪个协议

WebSocket是一个允许Web应用程序(通常指浏览器)与服务器进行双向通信的协议。HTML5的WebSocket API主要是为浏览器端提供了一个基于TCP协议实现全双工通信的方法。

WebSocket优势: 浏览器和服务器只需要要做一个握手的动作,在建立连接之后,双方可以在任意时刻,相互推送信息。同时,服务器与客户端之间交换的头信息很小。

21、Spring Boot如何访问不同的数据库

针对这个问题,我专门写过博客,这道题答得我最满意。

【Spring Boot 27】Springboot配置两个数据库(附代码+源码分析)

 22、做过程序设计吗?

这道题我答的并不是很好

  1. 先进行系统设计,思考实现这个项目都需要什么技术,技术的选择很重要,既要考虑性能,又要考虑组员的学习成本。
  2. 进行概要设计,设计一下系统都有哪些模块,模块间是否需要通信。
  3. 进行数据库设计
  4. 进行API设计

也不知道我答得对不对,先这样吧。

23、说一下cookie、session、token有什么区别?

(1)session

session是服务端存储的一个对象,主要用来存储所有访问过该服务端的客户端的用户信息(也可以存储其他信息),从而实现保持用户会话状态。但是服务器重启时,内存会被销毁,存储的用户信息也就消失了。

不同的用户访问服务端的时候会在session对象中存储键值对,“键”用来存储开启这个用户信息的“钥匙”,在登录成功后,“钥匙”通过cookie返回给客户端,客户端存储为sessionId记录在cookie中。当客户端再次访问时,会默认携带cookie中的sessionId来实现会话机制。

① session是基于cookie的。

cookie的数据4k左右;
cookie存储数据的格式:字符串key=value
cookie存储有效期:可以自行通过expires进行具体的日期设置,如果没设置,默认是关闭浏览器时失效。
cookie有效范围:当前域名下有效。所以session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上(前后端项目协议、域名、端口号都一致,即在一个项目下)

② session持久化

用于解决重启服务器后session消失的问题。在数据库中存储session,而不是存储在内存中。通过包:express-mysql-session。

当客户端存储的cookie失效后,服务端的session不会立即销毁,会有一个延时,服务端会定期清理无效session,不会造成无效数据占用存储空间的问题。

(2)token机制

适用于前后端分离的项目(前后端代码运行在不同的服务器下)

请求登录时,token和sessionid原理相同,是对key和key对应的用户信息进行加密后的加密字符,登录成功后,会在响应主体中将{token:“字符串”}返回给客户端。

客户端通过cookie都可以进行存储。再次请求时不会默认携带,需要在请求拦截器位置给请求头中添加认证字段Authorization携带token信息,服务器就可以通过token信息查找用户登录状态。

24、如何设计数据库

(1)数据库设计最起码要占用这个项目开发的40%以上的时间

(2)数据库设计不仅仅停留在页面demo的表面

页面内容所需字段,在数据库设计中只是一部分,还有系统运转、模块交互、中转数据、表之间的联系等等所需要的字段,因此数据库设计绝对不是简单的基本数据存储,还有逻辑数据存储。

(3)数据库设计完成后,项目80%的设计开发都要存在你的脑海中

每个字段的设计都要有他存在的意义,要清楚的知道程序中如何去运用这些字段,多张表的联系在程序中是如何体现的。

(4)数据库设计时就要考虑效率和优化问题

数据量大的表示粗粒度的,会冗余一些必要字段,达到用最少的表,最弱的表关系去存储海量的数据。大数据的表要建立索引,方便查询。对于含有计算、数据交互、统计这类需求时,还有考虑是否有必要采用存储过程。

(5)添加必要的冗余字段

像创建时间、修改时间、操作用户IP、备注这些字段,在每张表中最好都有,一些冗余的字段便于日后维护、分析、拓展而添加。

(6)设计合理的表关联

若两张表之间的关系复杂,建议采用第三张映射表来关联维护两张表之间的关系,以降低表之间的直接耦合度。

(7)设计表时不加主外键等约束关联,系统编码阶段完成后再添加约束性关联

(8)选择合适的主键生成策略

数据库的设计难度其实比单纯的技术实现难很多,他充分体现了一个人的全局设计能力和掌控能力,最后说一句,数据库设计,很重要,很复杂。

 25、性别是否适合做索引

区分度不高的字段不适合做索引,因为索引页是需要有开销的,需要存储的,不过这类字段可以做联合索引的一部分。

26、如何查询重复的数据

(1)查询重复的单个字段(group by)

select 重复字段A, count(*) from 表 group by 重复字段A having count(*) > 1

(2)查询重复的多个字段(group by)

select 重复字段A, 重复字段B, count(*) from 表 group by 重复字段A, 重复字段B having count(*) > 1

(3)删除所有重复的数据

-- 慎重考虑后执行,后悔记得及时回滚。
 
delete from table group by 重复字段 having count(重复字段) > 1

27、查询网站在线人数

通过监听session对象的方式来实现在线人数的统计和在线人信息展示,并且让超时的自动销毁。

对session对象实现监听,首先必须继承HttpSessionListener类,该程序的基本原理就是当浏览器访问页面的时候必定会产生一个session对象,当关闭该页面的时候必然会删除session对象。所以每当产生一个新的session对象就让在线人数+1,当删除一个session对象就让在线人数-1。

还要继承一个HttpSessionAttributeListener,来实现对其属性的监听。分别实现attributeAdded方法,attributeReplace方法以及attributeRemove方法。

sessionCreated//新建一个会话的时候触发,也可以说是客户端第一次喝服务器交互时触发。

sessionDestroyed//销毁会话的时候,一般来说只有某个按钮触发进行销毁,或者配置定时销毁。

HttpSessionAttributeListener有三个方法需要实现

  • attributeAdded//在session中添加对象时触发此操作 笼统的说就是调用setAttribute这个方法时候会触发的
  • attributeRemoved//修改、删除session中添加对象时触发此操作  笼统的说就是调用 removeAttribute这个方法时候会触发的
  • attributeReplaced//在Session属性被重新设置时

28、Redis取值存值问题

(1)先把Redis的连接池拿出来

JedisPool pool = new JedisPool(new JedisPoolConfig(),"127.0.0.1");
 
Jedis jedis = pool.getResource();

(2)存取值

jedis.set("key","value");
jedis.get("key");
jedis.del("key");
//给一个key叠加value
jedis.append("key","value2");//此时key的值就是value + value2;
//同时给多个key进行赋值:
jedis.mset("key1","value1","key2","value2");

(3)对map进行操作

Map<String,String> user = new HashMap();
user.put("key1","value1");
user.put("key2","value2");
user.put("key3","value3");
//存入
jedis.hmset("user",user);
//取出user中key1 
List<String> nameMap = jedis.hmget("user","key1");
//删除其中一个键值
jedis.hdel("user","key2");
//是否存在一个键
jedis.exists("user");
//取出所有的Map中的值:
Iterator<String> iter = jedis.hkeys("user").iterator();
while(iter.next()){
    jedis.hmget("user",iter.next());
}

29、mybatis一级缓存、二级缓存

(1)一级缓存:指的是mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入sqlSession中,再次查询的时候,先去sqlSession中查询,有的话直接拿出,当sqlSession消失时,mybatis的一级缓存也就消失了,当调用sqlSession的修改、添加、删除、commit()、close()等方法时,会清空一级缓存。

(2)二级缓存:指的是mybatis中的sqlSessionFactory对象的缓存,由同一个sqlSessionFactory对象创建的sqlSession共享其缓存,但是其中缓存的是数据而不是对象。当命中二级缓存时,通过存储的数据构造成对象返回。查询数据的时候,查询的流程是二级缓存 > 一级缓存 > 数据库。

(3)如果开启了二级缓存,sqlSession进行close()后,才会把sqlSession一级缓存中的数据添加到二级缓存中,为了将缓存数据取出执行反序列化,还需要将要缓存的pojo实现Serializable接口,因为二级缓存数据存储介质多种多样,不一定只存在内存中,也可能存在硬盘中。

(4)mybatis框架主要是围绕sqlSessionFactory进行的,具体的步骤:

定义一个configuration对象,其中包含数据源、事务、mapper文件资源以及影响数据库行为属性设置settings。
通过配置对象,则可以创建一个sqlSessionFactoryBuilder对象。
通过sqlSessionFactoryBuilder获得sqlSessionFactory实例。
通过sqlSessionFactory实例创建qlSession实例,通过sqlSession对数据库进行操作。

(5)代码实例

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  
"http://mybatis.org/dtd/mybatis-3-c

以上是关于❤️连续面试失败后,我总结了57道面试真题❤️,如果时光可以倒流...(附答案,建议收藏)的主要内容,如果未能解决你的问题,请参考以下文章

必知必会面试10多家中大厂后的两万字总结——❤️JVM篇❤️(建议收藏)

面试10多家中大厂后的万字总结——❤️集合篇❤️(精心打磨,建议收藏)

爆肝一周面试10多家中大厂后的万字总结——❤️JavaWeb篇❤️(建议收藏)

❤️思维导图整理大厂面试高频数组15: 介绍Entry类和海象运算符, 哈希表解决最短连续子数组, 力扣697❤️

❤️思维导图整理大厂面试高频数组15: 介绍Entry类和海象运算符, 哈希表解决最短连续子数组, 力扣697❤️

阿里美团面试拿下美团offer后,熬夜总结出大厂常问680道面试真题及解析