面试笔记

文章目录

C/C++

C++11新特性
  • 右值引用: 调用移动构造函数,减少不必要的拷贝

    • 资源窃取
      • std::move() 语义转换,将参数转换为右值引用类型
      • 利用即将结束生命周期的右值的资源,从而避免临时对象的销毁和拷贝
    • 完美转发
      • std::forward() 保持参数的左右值属性,
      • 模板编程时将参数转发给其他函数
  • 智能指针

    • shared_ptr
      • 内部维护引用计数,到0自动销毁
      • 可复制和赋值
      • 可自定义销毁方法
    • unique_ptr
      • 无法赋值和复制,无引用计数,用于资源独占
      • 生命周期结束自动调用delete释放
      • 支持std::move()移动语义转移资源
      • 可自定义销毁方法
    • weak_ptr
      • 和shared_ptr结合使用,解决shared_ptr相互引用问题
  • lambda表达式

    • 匿名函数
    • 在做安卓开发的时候经常用java里的lambda表达式,java中和c++的区别是java无捕获变量的操作,而是直接可以访问所有外部变量
  • nullptr

    • 解决重载函数匹配问题
宏定义交换两个不确定类型的变量
#define swap(a,b) {a = a ^ b; b = b ^ a; a = a ^ b;}
extern关键字的作用
  • 声明在其他文件中定义的外部变量或函数
  • C++中extern C告诉编译器使用C的标准编译代码
在C++ 程序中调用被 C编译器编译后的函数,为什么被包含 extern “C”?

因为c++中调用同名函数要考虑函数重载,要对函数类型进行声明

头文件卫士的作用
  1. 防止头文件重复包含
C中全局变量 局部变量能同名吗? 如果同名怎么访问全局变量

可以同名,局部变量会屏蔽全局变量,C中无法再在该作用域访问全局变量,C++可以使用域限定符访问全局变量

sizeof与strlen的区别
  • sizeof计算的是实际所占的内存空间的大小
  • strlen计算的是字符串的长度,到'\0'截止,且不包括
struct的作用
  • 把不同的变量整合到一起,方便数据的管理
  • 使多个数据的存储位置连续,把多个数据封装成一个数据包,方便写入文件和网络传送
访问类的私有成员时,友元类和该类的get和set函数哪一个更好

get和set函数,因为使用友元会破坏类的封装性,安全性

socketTCP协议服务器端的编程模型,用到哪些函数

socket,bind,listen,acctep,read,write,recv,send

select函数
前置声明,解决头文件重复包含的问题
  • 前置声明只是告诉编译器这是一个类型,但是无法得知类型的大小,成员,是一种不完整的声明
  • 如果一个文件中只需要用到另一个文件中的类类型的指针或应用,或者用于声明该类型作为形参或返回值类型,只需对该类型进行前置声明,而不需要include,提高编译效率
在抽象类中,如果想增加一个接口,把该接口定义在所有接口之前会有什么问题
C++中三种继承方式的子类对父类三种成员的访问权限
父类成员内部子类外部友元子类对象(public)子类对象(protected)子类对象(private)
public
protected
private
父类成员public继承的子类protected继承的子类private继承的子类
publicpublicprotectedprivate
protectedprotectedprotectedprivate
private不可直接访问不可直接访问不可直接访问
虚函数和纯虚函数的区别
  • 含有纯虚函数的类被称为抽象类,一般用来定义接口,无法实例化
  • 虚函数必须实现,可以直接使用,或被子类覆盖,而纯虚函数在基类中只有声明没有定义,必须在子类中实现才能使用
  • 都可在子类中被重载,以多态形式被调用,是一种运行时的多态(重载:编译时多态)
C和C++中static有什么作用,分别描述一下
  • C++中static修饰成员变量: 使变量属于整个类而不是某个对象
  • C++中static修饰成员函数: 函数失去this指针,只能访问static成员,使函数属于整个类
  • 修饰局部变量: 作用域不变,延长生命周期为全局(整个程序),只初始化一次(默认初始化为0)
  • 修饰函数: 限制作用域为本文件
printf是从左到右打印还是从右到左打印

从右往左计算,从左往右输出

vector自动扩容是如何实现的

内部预置容量大于等于元素数量
当前容器容量无法容纳元素时重新申请更大内存并复制
不同编译器实现扩容方式不同,GCC按2倍扩容
capacity()查看当前可容纳的元素数量
reserve()设置预留元素个数

if(n==10)和if(10==n)哪一种更好,为什么

第二种更好,因为第一种如果少写了一个’=’,则if语句括号中就变成了赋值语句n=10,而这样写能通过编译,编译器无法检测到错误,用第二种写法,若是少些一个’=’,则if语句中就变成了10=n,在C/C++的语法中并没有这样的语法存在,因此无法通过编译,编译器可以直接检测到错误。用第二种写法可以有效降低bug的出现率,是一种良好的编程风格

宏定义如何换行,如何连接字符

反斜杠\换行
##连接字符(串)

float x与“零值”进行比较,为什么使用了0.000001而不是使用0(整型)
中数组名a和&a的区别
  • a表示数组中第一个元素的地址,
  • &a表示整个数组的地址,两者在数值上相同,但对两者+1运算后a+1指向数组第二个元素,&a+1指向整个数组末尾的下一个地址(下一个数组的地址)
多态的原理

在C++类中,一旦成员函数中有虚函数,这个类中就会多一个虚函数表指针,这个指针指向一个虚函数表,表里记录了这个类中所有的虚函数,当这个类被继承,它的子类中也会有一个虚函数表(不管子类中有没有虚函数),如果子类的成员函数中有函数签名与父类的虚函数一样就会用子类中的函数替换它,在虚函数表中的位置,这样就达到了覆盖的效果。当通过类指针或应用调用函数时,会根据对象中实际的虚函数表记录来调用函数,这样就达到了多态的效果

你知道排序算法有哪些吗

冒泡,选择,插入,快速,归并,堆

什么是多态?
  • 运行时多态: 当子类覆盖了父类的虚函数时,通过父类指针指向子类对象时,调用虚函数,会根据具体的对象是谁来决定执行谁的函数
  • 编译时多态: 重载
有了malloc和free为什么用new/delete(我写的是这两个的区别)
malloc/freenew/delete
会自动计算所需内存的大小分配/释放
自动调用类的构造和析构函数
malloc返回void*new返回具备类型的指针
new[]会在地址的前4字节保存数组长度
id[sizeof(unsigned long)]这种写法是正确的吗?为什么?

正确,32位系统中sizeof(unsigned long)的值为4,个人认为正确与否取决于编程者的意图

指针和引用的区别
指针引用
是一个变量是变量的一个别名
定义时可不初始化必须初始化且不可NULL
初始化后可变初始化后不可变
可以有多级只有一级
sizeof得到指针变量的大小得到指数据的大小
有const没有const
C++中有哪些传参方法

指针,引用,值

C++中struct和class区别

struct也能包含成员函数,继承,多态;class和struct也可以相互继承

structclass
默认成员publicprivate
默认对父类的继承方式publicprivate
定义时赋值可用{}(但是如果加入构造或虚函数就不性)不可以用{}
描述一下重载,隐藏,覆盖
  • 重载:在同一作用域下,函数名相同,参数列表不同的函数构成重载
  • 隐藏:不同作用域下,函数名相同,参数列表不同
  • 覆盖:子类的成员函数与父类的虚函数函数名(包括常函数),返回值(可以是父子类)及参数列表(包括const属性)都相同,构成覆盖
  • 子类与父类同名的函数,如果没有构成覆盖,必构成隐藏
有用过二级指针吗?对二级指针有什么理解?

二级指针指向的是一个指针,是指针的指针

const和static关键字怎么加,加上去有什么作用? 全局函数加上static有什么用?
  • const: 保护变量不被修改
    • 常成员函数可以保护成员变量不被修改
  • static: 限制作用域,改变存储位置
    • static 全局变量/函数:只能在当前文件使用
    • static 局部/块变量:栈->BSS
    • static 局部/块变量(初始化):栈->DATA
c语言中字符串拷贝函数除了strcpy还有什么拷贝函数?

void *memcpy(void *dest, const void *src, size_t n);
int sprintf( char *buffer, const char *format, ... );
char *strncpy(char *dest, const char *src, size_t n);

在C++中指针与引用有什么相同点和不同点?
  • 相同点: 可以优化传参效率,可以跨函数共享变量
  • 不同点
    • 指针是一种数据类型,而引用只是一个别名
    • 引用在定义时必须初始化且不能为空不能改变,指针可以不初始化可以为空可改变
    • 对指针指向的对象操作需要解引用,引用不需要
    • 指针有常量指针和指针常量,引用只有常量引用
面向对象的三个基本特征是什么,并简单叙述之。
  • 封装:将客观事物抽象封装成一个类
  • 继承:子类能继承父类,即子类能成为父类的拓展形态
  • 多态:对应不同的状况,父类能以不同的子类形态运行
内存对齐的规则
  • 对齐:pragma pack 、自身size 取小的
  • 补齐:pargma pack 、最大类型size 取小的
  • 默认pragma pack(8)包括32位
内存对齐的优点和与内存不对齐的区别
  • 提升cpu访问数据的效率
  • 平台(硬件)兼容性
const与指针

const int *p; 常量指针
int const *p; 常量指针
int* const p; 指针常量
const* int p; 错误写法

什么是指针函数与函数指针
  • 指针函数: int* func();返回值是指针的函数
  • 函数指针: int (*p)();指向函数的指针,指向函数的入口地址
volatile的用法

volatile 关键字是一种类型修饰符,告诉编译器该变量表示可以被某些编译器未知的因素更改,防止编译器对齐优化,每次访问都从其内存中读取

char arr[1024*1024*4];是否合理合法,如何修改
  • 不合理,不一定合法: 可能会栈溢出,取决于平台,一般linux的栈空间是8m(未验证,内存是分页的4k)
  • 使用堆内存,使用指针数组
++i/i++的区别 是否是原子操作
  • ++i 是先自增,再赋值
  • i++ 是先赋值,再自增
  • 都不是原子操作
强制类型转换
构造和析构函数可以是虚函数吗
  • 构造函数不可以是虚函数
  • 析构函数可以是虚函数

数据结构和算法

set和map的区别是什么

set中的数据会自动排序,map存储的是键值对键不能重复

有没有使用过迭代器,怎么用
stl知道哪些

list,vector,map,stack,queue,set

map和vector的区别
  • map
    • 红黑树实现的平衡查找二叉树,内存中不连续
    • 键值对,key不重复
  • vector
    • 连续存储
    • 插入删除消耗较大
map的底层数据结构

红黑树

Vector与List的区别
  • Vector为存储的对象分配一块连续的内存,因此随机存取更高效
  • List中对象是离散存储的,插入和删除效率更高
排序算法的复杂度
算法平均时间最好最坏空间稳定性
冒泡O(n^2)O(n)O(n^2)O(1)
直接插入O(n^2)O(n)O(n^2)O(1)
直接选择O(n^2)O(n^2)O(n^2)O(1)
快速O(nlog_2n)O(nlog_2n)O(n^2)
O(nlog_2n)O(nlog_2n)O(nlog_2n)O(1)
归并O(nlog_2n)O(nlog_2n)O(nlog_2n)
知道哪些树的类型

普通树, 二叉树, 完全二叉树, 满二叉树, 查找二叉树, 哈夫曼树

UC

用一段代码来判断机器是16位的还是32位的?
int* a;
switch(sizeof(a)){
	case 2: printf("16\n"); break;
	case 4: printf("32\n"); break;
}
编译过程
  1. 预处理
    gcc -E code.c 会把预处理的结果显示在屏幕上
    gcc -E code.c -o code.i 把预处理的结果保存再.i文件中
  2. 汇编
    gcc -S code.i 会生成以.s结尾的汇编文件
  3. 编译
    gcc -c code.s 会生成以.o结尾的目标文件(二进制指令)
  4. 链接
    gcc code.o 把若干个.o文件合并成一个可执行文件elf
使用过gdb吗
  • 之前学习的时候通过命令的形式使用过gdb(run, next, list, break, continue, print, quit),后来基本都用IDE的调试工具了
  • ubuntu下使用gdb不会产生core文件,要用ulimit -c unlimited修改设置
用户态和内核态是什么,什么时候进入内核态
  • 运行低特权级的用户代码时是用户态
  • 运行高特权级的内核代码时是内核态,进行系统调用的时候会进入内核态
  • 保护系统资源不被用户程序随意访问和修改
进程和线程之间哪些数据是共享的
  • 线程除栈外其他资源都共享: 代码段,数据段,bss段,堆(没有栈),环境变量表,命令行参数,文件描述符,信号处理函数,工作目录,用户ID,组ID等资源
  • 子进程除共享代码段外复制父进程其他: 数据段,bss段,堆,栈,IO流(共享文件指针和文件描述符),缓冲区拷贝
如何保证对共享资源的操作为原子操作?
  • mutex互斥锁
  • C++11原子类型
静态库和共享库的区别
  • 静态库: 程序编译的时候连接到目标代码中,运行时不需要,更新库需要重新编译
  • 动态库: 程序运行时被载入,运行时需要库存在
  • 对比
    • 静态库: 浪费内存,执行速度快,集成度高
    • 动态库: 更节省适合算法库和功能库,方便更新和升级
进程间通信有哪几种方式?各有什么特点?
  • 简单进程通信:命令行参数,环境变量表,信号,文件
  • 传统:有名管道(fifo),无名管道(pipe,亲缘进程间)
  • XSI:共享内存(最快),消息队列,信号量(控制对共享资源的访问)
  • 网络 socket(不同设备进程之间)
知道共享内存吗?说一下原理?有用过吗?
  • 内核中开辟的一块由IPC对象管理的内存,进程A和进程B将自己的虚拟地址与其映射
  • 特点:不需要复制数据,是最快的一种进程间通信;需要考虑同步问题(信号量)
  • 编程模型
进程A进程B
生成IPC键值ftok生成IPC键值ftok
创建IPC对象(共享内存)shmget创建IPC对象(共享内存)shmget
映射共享内存shmat映射共享内存shmat
使用共享内存*ptr使用共享内存*ptr
取消映射shmdt取消映射shmdt
删除共享内存shmctl
用过多线程吗?怎么样防止多个线程同时访问?

互斥量(互斥锁mutex),条件变量(cond),信号量
一般互斥锁和条件变量一起使用互斥锁用来锁定资源,条件变量用来阻塞线程

死锁产生的条件
  • 互斥
  • 不可剥夺
  • 请求保持
  • 环路等待
避免死锁的方法

构成死锁的四个条件只要破坏其中一个就构不成死锁,死锁一旦形成,就无法消除,因此最好的方法就是避免产生死锁

  • 破坏互斥条件,让资源能够共享,但缺点是不通用,因为有些资源不能共享,如打印机
  • 破坏请求并保持条件,采用预先分配的方法,在进程运行前一次性申请好它所需要的所有资源,缺点是浪费资源
  • 破坏不可剥夺条件,对已占用资源的线程发送取消请求,但实现比较复杂,而且还会破破坏业务逻辑.
  • 破破坏循环等待条件,为每一个资源进行编号,采用顺序的资源分配方法,规定每个线程必须按照递增的顺序请求资源,缺点是编号必须相对稳定,而且增加新的资源时会比较麻烦,而且有些特殊的业务逻辑不能完全按照指定的顺序分配资源
为什么用到线程

同进程一样可以进行并行运算,避免阻塞,提高CPU利用率,但是进程间的切换非常耗费资源和时间,为了进一步提高操作系统的并发性,引入了线程,进程是资源分配的基本单位,线程是系统调度的基本单位

linux下的命名知道哪些
ls,cd,mkdir,cp,rm,rmdir,ipconfig,ps,strace,vim,g++,gcc,sudo,su,apt-get,cat,vi,reboot,grep,find...
打开文件的函数是什么?
  • UNIX系统调用open
  • 标准C库函数fopen
进程映像:
  • 进程是正在执行的程序
  • 进程映像就是进程的资源在内存的分布情况,地址从低到高:
代码段/只读段二进制指令/字符串字面值/具有const属性且被初始化过的全局变量/静态变量
数据段初始化过的全局变量/静态变量
bss段没有被初始化过的全局变量/静态变量,进程加载成功清理为0
动态的分配,管理,需要程序员手动操作
非静态的局部变量,包括函数的参数,返回值(从高地址向低地址使用,和堆内存存在一段空隙,防止相互影响)
命令行参和环境变量表命令行参数/环境变量表
栈和堆的空间区别,为什么用堆?
  • 栈的内存空间较小且固定,Linux下8/10m,堆的内存空间可以自己扩展,理论上是虚拟内存用户空间的大小(3G)
  • 栈中内存空间是编译器自动分配,堆中内存空间是程序员手动申请分配的c中函数是malloc/free,c++中是new/delete
  • 栈中内存访问速度也比堆中内存访问速度较快
你会遇到内存泄漏吗?
  • 遇到过,在avt项目中遇到过
  • 大部分都通过我们内部的工具检测出来了,我们内部对malloc和free封装成了一个工具类memtrace,可以检测到申请后没有被释放的内存并打印出文件名,行号,内存大小
  • 还遇到过一次显存的泄露,在GL线程里,无法用工具检测到,通过使用高通的工具snap dragon profile发现一张纹理图大量重复,最终定位到代码中一个textureID没有被释放
用什么分配内存,重复释放是什么结果

new,malloc分配内存,重复释放会造成程序崩溃,可使用shared_ptr解决(自动释放,无须显式调用free)

两个线程访问一个变量有什么问题

一个变量在同一时间段只能被一个线程访问,两个线程会竞争访问变量的顺序
而且如果两个线程访问这个变量的时候是不只是读取变量的时候,就会出现数据不一致的问题,产生脏数据

有哪几种锁

互斥量,线程的信号量,条件变量

Makefile
高速缓冲区的作用
  • 缓冲:io设备和内存之间速度不匹配
  • 减少io设备的频繁读写,减少损耗

Qt

Qt中signal和slot
  • 信号和槽通常用于对象间的通信,类似于回调和软中断的概念
    类型安全:只有参数匹配的信号与槽才可以连接成功(信号的参数可以更多,槽会忽略多余的参数)。
  • 线程安全:通过借助QT自已的事件机制,信号槽支持跨线程并且可以保证线程安全。
  • 松耦合:信号不关心有哪些或者多少个对象与之连接;槽不关心自己连接了哪些对象的哪些信号。这些都不会影响何时发出信号或者信号如何处理。信号与插槽建立了强大的组件编程机制。
  • 信号与槽是多对多的关系:一个信号可以连接多个槽,一个槽也可以用来接收多个信号。
  • 使用这套机制,类需要继承QObject并在类中声明Q_OBJECT

网络

三次握手和四次挥手
AB
3次握手
1听得到吗(SYN)->B知道A可到B
2A知道A能到B,B能到A<-(SYN+ACK)我听得到,你呢
3我听得到(ACK)->B知道了B也能到A
4次挥手
1发送关闭请求->
2<-发送请求响应
检查是否还有未发送数据
3<-可以关闭
4发送关闭信息->
三次握手(服务器没收到最后一次ACK会怎么样)

服务器会重发上一次的SYN+ACK

C++中的socket吗?说一下服务端跟客户端的编程模型?
  • TCP
ServerClient
创建socket套接字创建socket套接字
准备地址(sockaddr_in,本机地址)准备地址(服务端地址)
绑定(bind)
监听(listen)
等待连接(accept,fork)连接(connect)
接收请求(read/recv)发送请求(write/send)
响应请求(write/send)接收响应(read/recv)
关闭(close)关闭(close)
  • UDP
ServerClient
创建套接字(socket)创建套接字(socket)
准备地址(本机地址sockaddr_in)准备地址(目标机地址> sockaddr_in)
绑定(bind(sockfd+addr))
接收请求(recvfrom)发送请求(sendto)
响应请求(sendto)接收响应(recvfrom)
关闭套接字(close)关闭套接字(close)
知道TCP/IP模型吗?你比较熟悉那一层?
OSITCP/IP数据单位
应用层应用层主要是为用户提供针对性的服务,HTTP,SMTP,FTP,SENMP,TELNET,DNS报文
表示层
会话层
传输层传输层机器之间建立用于会话的端到端连接(用于数据传输,TCP,UDP传输协议分组
网络层网络层选择,流量控制,网络拥塞,IP,ICMP,ARP,RIPip数据报
数据链路层VLAN,MAC
物理层网络接口层负责通信网络收发数据包IEEE802.3比特
Socket网络通信中阻塞与不阻塞的区别?
    • 阻塞: 接收缓冲区无数据时一直阻塞,直到读取到数据返回
    • 非阻塞: 接收缓冲区无论有无数据都会立即返回
  • 等待连接

  • 建立连接

写出TCP协议与UDP协议特点。
  • TCP:

    1. TCP是面向连接的传输层协议;
    2. 每一条TCP连接只能有两个端点(即两个套接字),只能是点对点的;
    3. TCP提供可靠的传输服务。传送的数据无差错、不丢失、不重复、按序到达;
    4. TCP提供全双工通信。允许通信双方的应用进程在任何时候都可以发送数据,因为两端都设有发送缓存和接受缓存;
    5. 面向字节流。虽然应用程序与TCP交互是一次一个大小不等的数据块,但TCP把这些数据看成一连串无结构的字节流,它不保证接收方收到的数据块和发送方发送的数据块具有对应大小关系,例如,发送方应用程序交给发送方的TCP10个数据块,但就受访的TCP可能只用了4个数据块久保收到的字节流交付给上层的应用程序,但字节流完全一样。
  • UDP:

    1. UDP是无连接的传输层协议;
    2. UDP使用尽最大努力交付,不保证可靠交付;
    3. UDP是面向报文的,对应用层交下来的报文,不合并,不拆分,保留原报文的边界;
    4. UDP没有拥塞控制,因此即使网络出现拥塞也不会降低发送速率;
    5. UDP支持一对一 一对多 多对多的交互通信;
    6. UDP的首部开销小,只有8字节.
TCPUDP
可靠传输不可靠传输
面向连接无连接
传输数据有序不保证数据的有序性
不保存数据边界保留数据边界
传输速度相对较慢相对较快
有流量控制和拥塞控制没有
重量级协议是轻量级协议
首部较长20字节首部较短8字节
TCP拥有哪些机制?
  • 确认重传
  • 数据校验
  • 流量控制
  • 拥塞控制
  • 数据合理分片和排序
TCP拥塞控制机制
  • 慢启动(指数上升)
  • 拥塞避免(线性上升)
  • 快重传
  • 快恢复
ping使用了哪个协议

ICMP

数据库

编程中连接数据库
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一些 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、事务管理、缓存等)要有一定的了解,并能够根据实际需求进行应用。 - 在面试中要注意表达清楚自己的观点和思路,可以通过实际项目经验来证明自己的能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值