面试笔记一

持续更新中……

滴滴go语言开发一面(1~16):

1.mysql有那些存储引擎?

​  常用的是innodb,还有其它不常用的,比如myisam、memory(把数据存储在内存中,生命周期短,一般是一次性的)、archive(主要用于数据归档,压缩比非常高,比较适合用来存储历史数据)之类的。

2.说说innodb和myisam区别?

​   (1)事务:INNODB支持事务,而MyISAM强调的是性能,每次查询具有原子性,不提供事务支持。
​   (2)外键:INNODB支持外键,MyISAM不支持外键。
​   (3)锁机制:innodb是行锁,MyISAM是表锁,如果进行大量的插入、删除操作,使用innodb性能会更高,因为innodb使用的是行锁,只需要锁定操作行就行,而myisam是表锁,整个表都会被锁住,效率会低一些。
  (4)如果只是执行大量的查询, MyISAM的执行速度比innodb快,因为myisam只需要缓存索引块,而innodb要缓存数据块,缓存数据块是比较花费性能的。
   (5)Innodb不保存表的具体行数,而myisam内置了一个计数器,执行没有where条件的count(*)时直接从计数器中读数据,而innodb要进行全表扫描。
   (6)Innodb和Myisam存储数据的格式不一样,innodb用.frm存储表定义,用.ibd存储数据,而myisam用.frm格式存储表定义,用.myd存储数持,用.myi存储索引。
​   (7)存储消耗不同,myisam会进行压缩存储,存储空间较小,而innodb会在内存中开辟缓冲池来缓冲数据和索引,占用空间比myisam大。
​   (8)InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的。在查询时如果不能使用覆盖索引在索引树中找到全量数持,就得做回表扫描,先在索引树中查询到主键,然后再通过主键查询到数据。MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。

3.mysql的事务是什么,有哪些特性?

​  ​ 事务是一系列的数据库操作,是数据库应用的基本单位,主要用于处理操作量大,复杂度高的数据。

​  ACID(A:原子性,C:一致性,I:隔离性,D:持久性)

  原子性(Atomic):要么全部执行,要么全部不执行;

​  一致性(Consistency):事务的执行使得数据库从一种正确状态转化为另一种正确状态;

​  隔离性(Isolation):在事务正确提交之前,不允许把该事务对数据的任何改变提供给其他事务;

​  持久性(Durability):事务提交后,其结果永久保存在数据库中。

4.用过外键吗?用的是逻辑外键还是物理外键?都有什么好处?哪个好?

​  用过,两种外键都用过,物理外键的好处是数据库会帮我们维护两张表之间的关联,不用我们自己在代码里去连接两张表。但是,物理外键的性能是存在很大问题的:

​  a.数据库需要维护外键的内部管理;
​  b.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
​  c.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
​  d.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况

5.说说数据库有哪些索引方式(主要hash索引,b+树),什么时候用hash索引什么时候用b+树,这两个优劣

​  哈希索引只支持等值查询,不支持范围查询,在离散型高、数据基数大的等值查询时,哈希索引有优势。在范围查询、模糊查询、排序、分组的场景下,哈希索引无法满足要求,应该使用B+树索引。

6.简单说说索引怎么实现的(工作室之前讲过),工作中哪些情况用索引,为什么要用到

  B+树索引(范围查询)、哈希索引(非范围查询)

7. '%xxx’会不会走索引,为什么(个人感觉答的不错,有机会以后给大家讲讲),索引什么情况下会失效

  后导模糊查询 like 'xx%'是可以走索引的,前导模糊查询 like '%xx',一般是不走索引的,如果还想走索引就必须把使用覆盖索引,即把要查询的字段改为一次索引查询就能查到的字段,而不用回到聚集索引做回表扫描。
  索引失效的几种情况:
  1.在复合索引中跳过了第一列字段
  2.在复合索引中跳过了中间字段,这样中间字段之前的字段会走索引,中间字段之后的字段不走索引
  3.在索引上进行计算、函数、类型转换
  4.使用范围查询后,该索引之后的索引会失效
  5.使用不等于操作(!=或<>)
  6.使用is not null
  7.使用前导模糊查询
  8.不走索引会有更好的查询性能时索引失效

8.是不是什么情况下都可以建立索引,哪些情况不行,为什么

  适合建立索引的情况:
  1.频繁做为where条件的字段
  2.用做不同表之间关联的字段要建立索引,如做为外键的字段
  3.做为排序的字段
  4.用来分组的字段(分组前一般要先排序)
  5.常用来计数的字段
  不适合建立索引的情况:
  1.频繁更新的字段
  2.where条件用不到的字段
  3.表数据可以确定比较少的字段不需要建立索引
  3.唯一性较差的字段,性别、布尔值
  4.经常要参与运算的字段

9.说说脏读、不可重复读、幻读,怎么解决的

  一种解决方案是使用悲观锁,另一种解决方案是使用乐观锁
  悲观锁:
  当sql第一次读取到数据时,就将这些数据加锁,这样其他事务就无法修改这些数据,解决了不可重复读。但这样无法锁住insert的数据,当事务A先前读取了一些数据,事务B还可以插入数据,这时事务A就会发现莫名其妙多了一条原来没有的数据,这就是幻读,幻读无法通过行锁来避免。需要使用可串行化隔离级别,读用读锁,写用写锁,读锁与写锁互斥,这样可以有效避免脏读、不可重复读、幻读,但会极大降低数据库的并发能力。
  乐观锁
  乐观锁大多是基于数据版本记录实现的,一般通过为数据表增加一个”version“字段来实现。读取数据时将版本号一同读出,在提交更新前对此版本号加一,然后和数据库表对应的版本号进行比对,如果大于数据库当前的版本号则执行提交,否则数据已被其他事务更新过,执行提交失败。

10.分库分表了解过吗,为什么要分(数据量大才要分,要不然会慢),然后问了一个左前缀什么的,这个不会

  为什么要分库分表?

  在数据量很大时通过分库分表可以提升性能、增加可用性。

  什么是分库分表?

  去中心化,不把鸡蛋都放在一个篮子里
  分库:从单个数据库拆分成多个数据库的过程,将数据散落在多个数据库中
  分表:从单张表拆分成多张表的过程,将数据散落在多张表内。

  分库分表有几种方式?

  概括:垂直拆结构、水平拆数据
  垂直拆分:
  分库:根据不同的业务将数据库拆分成不同的库,比如商城数据库可以拆分为会员库、商品库、订单库
  分表:根据业务需求,对一张表的字段拆分成不同的部分,比如用户表,可以拆分成基础表和信息表,基础表只有用户id、用户名和密码字段,主要用户登录业务逻辑;信息表有用户id和用户的联系方式、收货地址等字段,可以用于订单业务
    特点:
    1.每个库(表)的结构都不一样
    2.每两个需要关联的库(表)至少有一列字段是一样的
    3.每个库(表)的并集是全量数据
    优点:
    1.拆分后业务更清晰(专库专用按业务拆分)
    2.数据维护简单、不同的业务放到不同的机器上
    缺点:
    1.如果单表数据量大,读写压力会很大
    2.一个业务往往会成为数据库的瓶颈,比如双十一的订单业务是影响数据库性能的主要瓶颈
    3.增加了开发的难度
  水平拆分:
  数据库或表的结构都不用改变,只需要拆分数据,将结构相同的数据分散到不同的机器上
    特点:
    1.每个库(表)的结构都一样
    2.每个库(表)的数据都不一样
    3.每个库(表)的并集是全量数据
    优点:
    1.单库(表)存的数据量减小了,有助于提高性能
    2.拆分表的结构相同,程序改动较少,比如和数据库对应的类或结构体的属性不需要改动
    缺点:
    1.扩容难度大,比如根据id模2的奇数或偶数将数据拆分到两台机器,如果要多加一台机器,就会面临大量的数据迁移问题
    2.拆分规则很难抽象出来
    3.存在分布式事务的一致性问题

  分库分表带来的问题?

  1.分布式问题
  2.跨库连接查询
  3.分布式全局唯一ID(shardingsphere默认使用雪花算法)
  4.开发成本高,对程序员要求高
  解决方案:使用开源框架
  jdbc直连层:shardingsphere(可以兼容不同的数据库,只要实现jdbc接口即可,但对除java之外的编程语言兼容性不太好)
  proxy代理层:mycat(不支持跨数据库,但支持跨语言)

11.有哪些nosql (redis,mongodb) ,什么情况下用nosql

  常用的有redis、mongodb
  性能对比:redis全部数据在内存,定期与入磁盘,内存不够时使用LRU(Least Recently Used)算法删除数据,mongodb也是把数据存放在内存,但内存不够时,只把热点数据存放在内存,总体上redis的TPS高于mongodb,所以性能上redis优于mongodb。
  可靠性对比:mongodb使用binlog方式持久化,redis一般使用AOF快照方式持久化,将每一条命令追加到磁盘,在处理巨大的写入时,性能会降低,所以可靠性上mongodb优于redis。
  一致性对比:mongodb不支持事务,要靠客户端自身保证,redis支持事务,比较弱,仅能保证事务的操作按顺序执行。
  应用场景:mongodb主要应用于海量数据访问效率的提升,redis主要应用于较小数据量访问效率的提升。
  数据分析:mongodb内置数据分析功能,redis不支持数据分析。
  什么情况下使用
  1.高并发的数据库请求,传统的关系型数据库会成为性能瓶颈,使用nosql可以满足高并发的数据库请求。
  2.海量数据的分布式存储,使用nosql性价比更高。
  3.如果关系型数据库的表字段经常新增,会带来很大的性能开销,比如重建索引,使用nosql可以解决这个问题。
  4.数据库表字段是复杂数据类型时使用nosql,nosql以json方式存储数据,效率远远高于传统关系型数据库。

12.redis数据类型(string, set什么的)

  string、list、set、zset、hash

13.什么情况下用redis(短信验证码,用户session), 为什么要把session存redis

  1.在高并发场景下,可以使用缓存空间换时间,先把数据缓存到redis,然后多线程异步写入数据库,可以防止数据库阻塞。
  2.将用户session存入redis。
  为什么要把session存redis?
  这样可以实现分布式session,当客户端发送一个请求,经过负载均衡后该请求会分配到服务器中的其中一个,这个服务器要访问其他服务器保存的session,就可以通过redis来实现分布式session一致性。

14.简单讲讲redis底层实现

  redis的总体数据结构

  最顶层有一个结构体,这个结构体有好几个字典属性,第一个字典是用来存放键值对数据的,第二个哈字典是用来存放过期时间的,然后还有和阻塞相关的字典。
  我主要讲存放键值对数据的字典,这个字典内部维护了两个hashtable,一个是用来存放数据的,另一个是用来rehash的。hashtable就是一个数组,通过对hashtable长度取模的方式定位到数组中的一个位置,然而在这个位置存放的是一个指针,而不是k-v键值对,这个指针会指向一个k-v存储单元,数据实际存储在在个k-v存储单元中,redis中解决哈希冲突是使用拉链法,就是每个k-v存储单元都有一个指针指向下一个存储单元,在哈希冲突时,redis是采用头插法,将数据插入链表的头部,采用头插法是因为redis希望新插入的数据很快就会被用到,插入到头部方便快速访问。

  redis的rehash

  当数据的个数超过hashtable的大小时,redis会将hashtable成倍地扩容,然后通过rehash将原来的数据散落在新的hashtable里,rehash不是一次性的,而是渐近式的,每get或set某个哈希槽的数据时,会将这个槽的数据搬一部分到新的hashtable里,当所有数据都搬完之后,再把老的hashtable释放掉。
rehash访问数据的顺序:如果要取数据,先把老的hashtable里取,老的hashtable里没有就去新的hashtable里去,如果要插入新数据,直接往新的hashtable里插入数据

   redis string类型的设计

  redis的键是可以使用任意类型的,不过不管你使用什么数据类型,redis都会把你的键转成字符串,在redis中,字符串和c语言中的字符串是不一样的,redis没有像c语言一样使用\0作为字符串的结束符,redis重新定义了一种叫sds的数据结构,这个数据结构会用一个整型来描述这个字符串有多长,这样即使字符串中间有\0,读取也不会突然中断,当然描述字符串长度的整型,redis没有使用int类型,因为一个int占4个字节,共32位,太浪费空间了,redis的整型有好多类,比如占5位的,占8位的、16位的,每一个存放字符串的结构体内部都有一个字符型变量char来描述数据类型和长度,一个char字符类型虽然只占一个字节,但redis中设计得很精妙,redis把这一个字节的8bit位分成了两半,前三位用来描述数据类型,即到底是占多少位的整型,后五个bit位是用来描述这个字符串有多长,当然如果这5个bit位不够描述,redis还会再使用稍微更大的空间去描述。redis存放字符串的字符数组是支持成倍扩容的,如果字符数组容量不够了,redis会重新开辟一个新增加的长度与原长度之和的两倍大小的字符数组,然后将原来字符数组的内容复制过来。

  zset的底层实现

  当数据比较少时,zset使用ziplist(压缩列表)数据结构来存,当数据元素超过一定数量时,使用skiplist(跳跃表)存储,具体超过多少是可以自己配置的,当单个元素大小超过一定值时,使用skiplist(跳表)存储,单个元素达到多大使用skiplist(跳跃表)可以自己配置。
  ziplist(压缩列表)是一个很紧凑的数据结构,是顺序存储的,类似数组,但和数组又不一样,ziplist每个节点大小不一样,根据实际需要分配,非常节省内存,每个节点记录了必要的偏移量信息,这样可以很方便的跳到上一个节点或下一个节点。
  skiplist(跳跃表)是一种可以进行二分查找的有序链表,跳跃表在原有的有序链表的上面增加了多级索引,使得查找、插入、删除的时间复杂度都是O(logn)的。在大量的新节点插入原链表后,上层的索引就会变得不够用,由于插入和删除节点是不可预测的,很难用一种有效的算法来保证跳跃表索引部分始终均匀,于是跳跃表中采用了一种随机的解决方案,就是一个元素插入到原链表后,通过一定的概率决定这个新节点是否要提拔到上一层,这个概率通常是50%,提拔完后继续随机决定是否要继续往上提拔,直到提拔结束。

15.放大招了,问我如果公司redis挂了怎么办… ,蒙了一下结果蒙对了

  可以使用哨兵集群机制Sentinel解决,哨兵集群会对redis服务器进行监控,如果发现是从服务器挂了,就给它作标记,表示这个从服务器不在了,如果是主服务器挂了,不会马上认定主服务器真的挂了,当超过半数的哨兵服务器认为这台主服务器挂了,才客观认定这台主服务器挂了,这时就要在从服务器中选举出一台主服务器,选举之前先筛选,把挂掉的和经常掉线的服务器去掉,接下来第一轮选举是看剩下的从服务器谁的优先级高,这个优先级是可以手动事先设置的,把优先级最高的设为主服务器,如果优先级相同,进入第二轮选举,看哪个从服务器复制进度最快,然后把复制进度最快的从服务器做为主服务器,如果复制进度都差不多,进入第三轮,由于每台服务器的ID值都是不相同的,第三轮把ID号最小的做为主服务器。
  挂掉的redis在重启后会自动加入到主从架构中成为从服务器,并自动完成数据同步。如果redis在挂掉之前实现了持久化,只需要连接到主服务器,实现增量同步。

  Redis高可用架构图解

  Redis主从复制过程

在这里插入图片描述
在这里插入图片描述
  Redis Sentinel高可用集群
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  Sentinel节点挂了怎么办?
在这里插入图片描述


点击回到目录
###
滴滴go语言开发二面(17~19):

16.给你1mb内存,对1000万个int32数排序,磁盘空间无限大,要求时间复杂度

  bitmap解法:
  申请长度为一千万位的位向量bit[10000000],所有位置为0,顺序读取待排序文件,每读入一个数i,便将big[i]置为1,当所有数据读入完成时,便对bit从头到尾遍历,如果bit[i] = 1,则输出到文件,当遍历完成,文件则已排好序。时间复杂度O(n)。
  归并排序:
  将1000万个数均分为40块,然后对这40块分别排序,排序时可以使用多线程,对这40块文件排好序后开始归并,归并就是取这40块文件中最小的元素写入文件,由于每一块数据都是从小到大排列的,取最小的元素只要对每一块数据的第一个元素进行比较,当所有元素都写入文件时,归并结束,文件里的元素已排好序。

17.10个数字,给出一个数字判断是不是在这十个里面,用map好还是数组遍历的好(10个肯定是数组的好)问我时间复杂度(因为固定长度了,都是常数),聊到了map,问我知不知道c++的map底层是什么(红黑树),说到go的map (哈希),开始比较红黑树和哈希了(感觉讲的还行),Linux底层epoll为什么用红黑树而不是哈希,还有写别的挺细的

  红黑树与哈希的区别:
  1.红黑树是有序的,哈希是无序的,可以根据是否需要排序来选择用哪个。
  2.红黑树占用的内存小(仅需要为其存在的节点分配内存),而哈希事先应该分配足够的内存存储散列表,即便有些哈希槽可能弃用,可以根据内存限制情况选择用哪个。
  3.红黑树查找和删除的时间复杂度都是O(logn),哈希查找和删除的时间复杂度都是O(1),但哈希并不一定就比红黑树快,因为哈希还有哈希函数耗时,还可能产生哈希冲突。
  Linux底层epoll为什么用红黑树而不是哈希:
  1.哈希表是不容易缩容的,如果某个时刻,有大量的网络请求通过哈希来记录,触发哈希表扩容,之后这个哈希表很难缩容回去,这也是为什么一些go程序 oom 的问题,都是go map太大了无法gc。
  2.哈希表虽然是o(1)时间复杂度,但网络连接数相当大时,底层需要那么多哈希运算,不一定有long(n)红黑树快。

18.tcp三次握手四次挥手,最后面试官都夸我了解的深

  常见标志位:
  ACK标志:确认标志。通常称携带ACK标志的TCP报文段为确认报文段。
  SYN标志:表示请求建立一个链接。通常称携带SYN标志的TCP报文段称为同步报文段。
  FIN标志:关闭标志,通常称携带FIN标志的TCP报文段为结束报文段。

  三次握手过程:

  1、发送端发送连接请求,带上同步标志位(SYN)和自己的序号。

  2、接收端同意发送端的连接请求,也带上同步标志位(SYN)和自己的序号,同时带上确认标志位(ACK)和确认序号,确认序号为发送端序号加1。

  3、发送端同意接收端的连接请求,带上确认标志位(ACK)和确认号,确认号为接收端序号加1。

  此时实现了全双工通信,即三次握手完成。

  涉及到的问题:为什么需要三次握手,而不是四次或两次?

  为什么不是四次?

  四次的过程如下:

发送方:我要连你了。
接收方:好的。
接收方:我准备好了,你连吧。
发送方:好的。

  显然,接收方同意连接并准备好是可以合并的,这样可以提高连接效率。
  为什么不是两次?

  两次的过程如下:

发送方:我要连你了。
接收方:好的。

  假设发送方是客户端,接收方是服务器,客户端发送完连接请求,服务器发出确认信息,此时连接就建立了,这样会导致单方面连接,客户端连上了服务器,但服务器没有连接上客户端,也就是客户端可能收不到服务器发出的确认信息,如果客户端没有收到服务器的确认信息,就会不断的重新发送建立连接请求,不断地建立连接是会浪费资源的,如果采用三次握手,在服务器收到了客户端发出的确认信息后才会真正建立连接,如果服务器收不到客户端的确认,服务器就会重新发送确认信息,直到得到客户端的回复。

  四次挥手过程:

  1、发送方发送关闭请求,带上关闭标志位(FIN)和自己的序号。

  2、接收方回复确认标志位(ACK)和确认序号,确认序号为发送方序号加1。

  3、接收方回复关闭标志位(FIN)和自己的序号,以及确认标志位(ACK)和确认序号,确认序号和上次相同。

  4、发送方回复确认标志位(ACK)和确认序号,确认序号和接收方的序号加1。

  涉及到的问题:为什么需要四次握手,而不是三次?

  三次的过程是这样的:

发送方:我不再给你发送数据了。
接收方:好的,我也不给你发了。
发送方:好的,拜拜。

  当接收方收到关闭的请求后,能立马响应的就是确认关闭,这里的确认关闭是关闭“发送方发给接收方”这条通道,而接收方是否需要关闭“接收方发给发送方”这条通道由操作系统决定,操作系统通常要sleep个几秒再关闭,如果合并成三次,可能造成发送方不能及时收到确认请求,超时后会重新发送关闭请求(“发送方重试发送:我不再给你发送数据了”)。

  为什么需要有 TIME_WAIT 状态存在?

简单来说有两点原因如下:
a. 在最后发送方发出确认信息后,仍然不能保证接收方能收到信息,万一没收到,那接收方就会重试,而此时发送方已经真正关闭了,就接受不到重试请求了。
b. 为了保证信道中已经没有还在途中的消息。如果途中还有消息,且发送方继续发送连接请求,由于消息在途中跑的速度不一样,可能会出现刚连接完又收到了确认关闭的消息,导致乱套了。

  为什么时长是 2MSL 呢?

发送确认信息到达接收方,到达时间最长是 MSL,而接收方如果没接受到,会再重试,时间最长也是 MSL,那发送方等 2MSL,如果还没收到请求,证明接收方已经正常收到了。


点击回到目录
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一些 Spring Boot 面试时可能会涉及的重要知识点和面试建议: 1. 什么是 Spring Boot? Spring Boot 是 Spring 框架的一个子项目,它基于 Spring 框架,简化了 Spring 应用的配置和开发过程,使得开发者可以更加便捷地创建独立、生产级别的 Spring 应用。Spring Boot 提供了自动化配置、开箱即用的组件和快速启动的能力,使得开发者可以更加专注于业务逻辑的实现。 2. Spring Boot 有哪些优点? - 简化了 Spring 应用的配置和开发过程。 - 集成了众多常用的第三方库,可以快速地搭建项目。 - 提供了自动化配置和开箱即用的组件,使得开发者可以更加专注于业务逻辑的实现。 - 与 Spring Framework 完美集成,可以很方便地使用 Spring 的各种功能。 - 支持多种开发方式,包括传统的 WAR 包部署、嵌入式服务器部署、Docker 容器化部署等。 3. Spring Boot 的核心注解有哪些? - @SpringBootApplication:用于标记 Spring Boot 应用的主类,它包含了 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三个注解,可以简化应用的配置和启动过程。 - @Controller、@Service、@Repository、@Component:用于标记 Spring Bean,可以自动扫描并注册到 Spring 容器中。 - @Autowired、@Resource、@Inject:用于依赖注入,可以自动装配 Spring Bean。 4. Spring Boot 的配置文件有哪些? Spring Boot 支持多种配置文件格式,包括 properties、yml、json 等。其中,application.properties 或 application.yml 是 Spring Boot 默认的配置文件,它可以放在项目的 classpath 下,也可以通过指定 spring.config.location 属性来指定配置文件的路径。 5. Spring Boot 的自动配置原理是什么? Spring Boot 的自动配置基于条件注解和条件判断,它会根据应用的上下文环境和 classpath 中的依赖库来自动配置 Spring Bean。例如,当 classpath 中存在 HikariCP 库时,Spring Boot 会自动配置一个 HikariCP 数据源,而不需要手动配置。 6. Spring Boot 如何处理异常? Spring Boot 提供了统一的异常处理机制,可以通过 @ControllerAdvice 和 @ExceptionHandler 注解来处理应用中的异常。在异常处理类中,可以通过 @ExceptionHandler 注解和方法参数来定义需要处理的异常类型和异常处理逻辑。 7. Spring Boot 如何实现 AOP? Spring Boot 集成了 Spring Framework 的 AOP 功能,可以通过 @Aspect 和 @Around 注解来实现切面编程。在切面类中,可以定义需要拦截的方法和拦截逻辑,以实现日志记录、权限控制等功能。 8. Spring Boot 如何实现事务管理? Spring Boot 集成了 Spring Framework 的事务管理功能,可以通过 @Transactional 注解来实现事务控制。在需要进行事务控制的方法上添加 @Transactional 注解,即可开启事务。 9. Spring Boot 如何集成数据库? Spring Boot 支持多种数据库,包括 MySQL、Oracle、MongoDB 等,可以通过在 pom.xml 中添加相应的依赖库来实现数据库的集成。同时,Spring Boot 也提供了多种数据库访问方式,包括 JDBC、JPA、MyBatis 等,可以根据实际需求选择合适的方式。 10. Spring Boot 如何实现缓存? Spring Boot 集成了多种缓存框架,包括 Ehcache、Redis、Caffeine 等,可以通过在 pom.xml 中添加相应的依赖库来实现缓存功能。同时,Spring Boot 也提供了多种缓存注解,包括 @Cacheable、@CachePut、@CacheEvict 等,可以方便地实现缓存功能。 面试建议: - 对于 Spring Boot 的基本原理和使用方法要有深入了解,并能够熟练使用 Spring Boot 搭建项目。 - 对于 Spring Boot 中常用的注解和配置文件要熟练掌握。 - 对于 Spring Boot 中的高级功能(如自动配置、AOP、事务管理、缓存等)要有一定的了解,并能够根据实际需求进行应用。 - 在面试中要注意表达清楚自己的观点和思路,可以通过实际项目经验来证明自己的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值