略,以及两道接口测试代码题目
索引可以帮助我们快速搜索数据,innodb 存储引擎用的是 b+树索引,叶子节点存放的是索引+数据,非叶子节点只存放索引。
可以按照四个角度来分类索引。
按数据结构分类:B+tree索引、Hash索引、Full-text索引。
按物理存储分类:聚簇索引(主键索引)、二级索引(辅助索引)。
按字段特性分类:主键索引、唯一索引、普通索引、前缀索引。
按字段个数分类:单列索引、联合索引。
show index from table
通过将多个字段组合成一个索引,该索引就被称为联合索引。
创建索引abc ab a,最左前缀原则,如果不遵循最左匹配原则,联合索引会失效,这样就无法利用到索引快速查询的特性了。
a命中,b不命中,c不命中;ab命中;ac命中;bc不命中;abc命中,acb命中。
1. @RestController:用于定义Controller层的类,可以自动将返回结果转换为JSON格式;
2. @RequestMapping:用于定义URI映射,可以将请求路由到对应的Controller方法;
3. @Autowired:用于实现依赖注入,自动装配Bean实例;
4. @Service:用于定义Service层的类;
5. @Component:用于定义普通的Bean对象;
6. @Configuration:用于定义配置类;
7. @Value:用于从配置文件中加载属性;
8. @Transactional:用于实现事务的管理;
9. @ExceptionHandler:用于处理异常;
SpringBoot启动注解
整个spring框架启动分为两部分,构造SpringBootApplication对象和执行run方法
核心注解@SpringBootConfiguration标识启动类为配置类,@EnableAutoConfiguration通过内部@Import注解AutoConfigurationImportSelector.class实现自动装配,@ComponentScan默认扫描当前目录及子目录下的bean。
面试官:我们简单聊一下SpringBoot的启动流程吧。 - 掘金
AOP是OOPs(面向对象编程)的补充,它也提供了模块化。在面向对象编程中,关键的单元是对象,AOP的关键单元是切面,或者说关注点(可以简单地理解为你程序中的独立模块)。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。一个横切关注点是一个可以影响到整个应用的关注点,而且应该被尽量地集中到代码的一个地方,例如事务管理、权限、日志、安全等,使用方式主要通过注解实现。
项目中有很多业务模块,而每一个业务模块都有相同的系统需求,比如对它们做统一的记录日志、权限检查以及事务管理。而使用AOP的时候我们只需要单独定义一个组件,这个组件不会和业务组件发生任何直接的关系,我们不用去业务组件里面调用它,所以我们额外定义了系统组件,就好像这个组件横跨了多个业务组件,横向扩展业务组件的需求,所以为面向方面或者切面编程,变成的角度是面向这个横切组件。
定义了一个pointcut方法,加上注解@Pointcut(),生效范围为Service层下所有的类,编写before方法并加上Before注解。
HashMap底层是基于数组和链表实现的。简单来说,HashMap将key通过hash算法映射到数组中,然后在对应的链表中查找value。当多个key的hash值相同时,会在同一个数组位置上使用链表来存储这些key-value。但是,当链表长度太长时,会影响HashMap的性能,因此在JDK1.8中,当链表长度超过阈值时,会将链表转换为红黑树,以提高查找效率。
HashMap不是线程安全的,因为多个线程同时访问HashMap时可能会导致数据不一致的问题。可以使用ConcurrentHashMap来实现线程安全的Map。
set用于存放不重复的数据,如果需要排序使用TreeSet。
Lambda 表达式 − Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)。
方法引用 − 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
用户登录之后,会给用户创建⼀个ticket,并放⼊cookie返回给浏览器,下⼀次再访问时,浏览器带上 cookie(ticket),服务端可以根据cookie确定用户的登录状态,以及通过ticket查询到用户id,通过用户id,就可以知道当前用户的具体信息了,把user放⼊model,再由模板引擎渲染后,返回HTML给客户端浏览器。
使用Redis存储验证码,当用户点击刷新验证码时,服务端⾸先给当前需要登陆的游客,设置⼀个随机字符串(kaptchaOwner),用于标识 当前这个游客,然后将随机字符串存⼊到cookie中,返回给浏览器,然后服务端的redis保存 key:随机字符串, value:验证码 。
接着用户输⼊用户名,密码,验证码,再次点击登陆时,服务端会从cookie中拿到kaptchaOwner,通过它,可以从 Redis中得到正确的验证码,然后与用户输⼊的验证码做⽐较,看是否⼀致。
Redis将所有的数据都存在内存中,所以它的读写性能⼗分惊⼈。 同时,Redis还可以将内存中的数据以快照或者⽇志的形式保存到硬盘上,以保证数据的安全性。
Redis5及之前的版本使用的是 单线程,也就是说只有一个 worker队列,所有的读写操作都要在这一个队列进行操作,好处是不会有线程安全问题(因为它在读写时就只有一个线程,那对于读写操作肯定没有线程安全问题啊!),但是读写 write、read 这些系统调用在Redis执行期间占用了大部分的 CPU 时间,所以这就是单线程模式的缺点。
Redis6引入了多线程机制,但是不是说有多个worker线程同时并发读写, 而是它有 “一个 worker线程+多个IO子线程”,其实就是在 IO 就绪之后使用多线程提升读写解析数据的效率,而在操作内存数据的时候还是用单线程。
同时,这种机制同样不会产生线程安全问题,因为Redis在针对数据的内存操作时,是在一个公共的worker队列中实现的,先进先出,所以不会有线程安全问题。
面试官:Redis是单线程还是多线程?(你为何怎么说都不对?)_redis5 多线程_啊泽泽泽zz的博客-CSDN博客
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
为了增加效率,搜索引擎会把正向索引变为反向索引(倒排索引)即把“文档→单词”的形式变为“单词→文档”的形式。倒排索引具体机构如下:
单词1→文档1的ID;文档2的ID;文档3的ID…
使用到的分词器为IK分词器,match查询会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。