GitHub:https://github.com/AFITS/TestGuide.git
一、计算机基础 1.1 计算机网络整理内容包含字节、阿里、腾讯等一线大厂的测试、测试开发的常见面试题,同时也是对自我的一种基础总结。
Author : UUT
测试/测试开发工程师最常遇见的知识点就是计算机网络,频率仅次于项目经历。
1.1.1 TCP/IP协议应表会传网数物
-
应用层:HTTP(超文本)、DNS(域名系统)、SMTP(邮件传输)
- HTTP最初是用来发布和接收HTML的
-
表示层
-
会话层
-
传输层:TCP(传输控制协议)、UDP(用户数据协议)
-
网络层:IP
-
数据层
-
物理层:TCP/IP
- 是最常使用的协议
- 但是如果提TCP/IP不仅说的是TCP和IP协议,而是整个协议族
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rWrQ3yWs-1651679328364)(C:\Users\smart\AppData\Roaming\Typora\typora-user-images\image-20220402013919134.png)]
1、特点
-
面向链接:TCP提供面向链接的服务,在传输数据之前必须先建立链接,数据传送结束后要释放链接;UDP是无连接的。
-
传输可靠性:TCP传递之前的三次握手来建立链接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,数据传输完成后,会断开连接来节约资源。
-
传输形式:TCP为字节流、UDP为数据报文段
2、性能
- TCP因为要不断的建立和关闭链接,所以传输效率低
- TCP所需资源多,UDP所需资源少
3、应用场景
-
UDP经常使用在即时通信方向,要求速度快。如:语音、直播等场景
-
TCP经常在文件传输、发送和接收邮件、远程登录,要求可靠性。
换一种问法,为什么是三次握手而不是四次或者两次?
0、三次收发确认双方收发过程正常,两次不满足,四次没必要
1、第一次,客户端发送SYN,什么都无法确认,服务端接受SYN,证明对方发送正常,自己接收正常
2、第二次,服务端发送SYN/ACK,客户端接收到后,知道:自己发送、接受正常,对方发送、接受正常
3、第三次,客户端发送ACK,服务端接受后,知道:自己发送、接受正常,对方发送、接受正常
1.1.4 TCP为什么要四次挥手?1、任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另⼀方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了TCP连接。
- 请求关闭并确认后,进入半关闭状态
- 双方都半关闭,则彻底关闭TCP链接
2、可以理解为打电话,A跟B说A不再说了,但是B可能还会说,A还在接受;只有B也说不说啦,才会结束。(两次结束确认)
3、四次握手过程
-
客户端发送一个FIN,用来关闭客户端到服务端的数据传输
-
服务端收到后,返回ACK,确认序号为收到序号+1
-
服务端关闭链接,服务端发送一个FIN给客户端
-
客户端收到后返回ACK,确认序号为收到序号+1
-
FIN-WAIT1、FINWAIT2、TIME、WAIT、CLOSE
-
CLOSE-WAIT、LAST-ACK、CLOSE
-
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。 -
TCP头部序号的位数
1、 应⽤数据被分割成 TCP 认为最适合发送的数据块。
2、TCP 给发送的每⼀个包进⾏编号,接收⽅对数据包进⾏排序,把有序数据传送给应⽤层。
3、校验和:TCP 将保持它⾸部和数据的检验和。这是⼀个端到端的检验和,⽬的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报⽂段和不确认收到此报⽂段。
4、TCP 的接收端会丢弃重复的数据。
5、流量控制:TCP 连接的每⼀⽅都有固定⼤⼩的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收⽅来不及处理发送⽅的数据,能提示发送⽅降低发送的速率,防⽌包丢失。TCP 使⽤的流量控制协议是可变⼤⼩的滑动窗⼝协议。 (TCP 利⽤滑动窗⼝实现流量控制)
6、拥塞控制: 当⽹络拥塞时,减少数据的发送。
7、ARQ协议:也是为了实现可靠传输的,它的基本原理就是每发完⼀个分组就停⽌发送,等待对⽅确认。在收到确认后再发下⼀个分组。
8、超时重传:当 TCP 发出⼀个段后,它启动⼀个定时器,等待⽬的端确认收到这个报⽂段。如果不能及时收到⼀个确认,将重发这个报⽂段
1.1.6 TCP如何拥塞控制-
慢开始:开始发送时,避免一下大量数据字段涌入导致网路阻塞。由小到大逐渐增大拥塞窗口数值。cwnd(拥塞)初始值为1,每经过⼀个传播轮次,cwnd加倍。
-
拥塞避免:拥塞避免算法的思路是让拥塞窗口cwnd缓慢增⼤,即每经过⼀个往返时间RTT就把发送放的cwnd加1。
-
快重传与快恢复(FRR):没有FRR,当丢包时,TCP会暂停传输;有FRR,当存在不按顺序的数据段,会给发送机发送一个重复确认,若收到三个3个连续确认,则重新传输。
UDP的可靠性传输其实就是借鉴TCP的思路。保证可靠性传输可以围绕以下几个方面:ACK机制、重传机制、序号机制、重排机制、窗口机制。
1、ACK机制:接收到包之后即发送ACK进行确认。
2、重传机制
(1)停等协议
- 退回N帧重传
- 选择性从传
-
1、浏览器查找域名的IP
- 首先在浏览器缓存、路由器缓存、DNS缓存中搜索,若没有找到则去根服务器、COM服务器找对应的IP
-
2、浏览器向WEB服务器发送一个HTTP请求
-
3、WEB服务器处理相应请求
-
4、服务器返回一个HTML相应
-
5、浏览器显示HTML
-
可以理解为打车去买菜:DNS就是车,资源就是菜
- HTTPS经过正规的CA颁发证书的,一般都不会劫持,HTTPS出现的初衷之一就是为了解决这个问题。因为HTTPS涉及到加解密,特别是服务端采用非对称加密方式对秘钥加密。
- HTTPS被劫持的情况,客户端安装有假的CA证书,然后被代理服务器劫持,客户端对服务器相应也信任。
- 话说回来,CA证书贵,共用的CA又少,如果真的劫持,可以考虑以下方式:①不同网络用分离的域名、②限制动态DNS的更新,③对传输区域限制,④删除DNS服务器上不必要的服务。
-
5XX:服务器
- 504
- 502
-
4XX:服务器无法处理请求(客户端)
-
HTTP与HTTPS区别
-
端口
- HTTP为80,HTTPS为443,且请求过程中,前缀分别为http://和https://
-
安全性和资源消耗
- HTTP是运行在TCP上,所有的传输均为明文,客户端和服务端都无法验证对方身份。HTTPS是运行在SSL/TLS协议上的,SSL/TLS运行在TCP之上,传输内容采用对称加密,但是对称加密的秘钥采用了服务器上的证书进行了非对称加密。
- 所以,HTTPS的安全性好于HTTP,但是HTTPS比HTTP耗费了更多的服务器资源
-
-
Https加密的过程
- HTTP(明文)> SSL套接字(加密)> TCP套接字 > 主机 > SSL套接字(解密)> 进程(明文)
- 需要用到对应的证书
- 状态行
- 请求响应头部
- 请求响应体
-
1.1 和 1.0
-
长链接
- 1.1支持一个TCP上有多个HTTP请求,避免建立和关闭链接的耗时,1.1默认开启keep-alive
-
节约带宽
- 1.1支持仅仅发送头部信息,当头部信息满足条件,返回100后,客户端再将请求体给服务端,若返回401,则无需传输body
-
HOST域
- 1.0默认服务器绑定唯一的IP地址,所以没有传递主机名(hostname),但是虚拟机发展,一个物理机上有多个虚拟机,共享一个IP,所以1.1的请求响应均需要加上HOST域,若没有则会报400错误。
-
缓存处理
- 引入更多的缓存处理策略
-
错误通知
- 引入了24个错误状态响应码
-
-
1.1 和 2.0
-
多路复用
- 采用多路复用技术,一个链接并发数量是1.1的多倍,可以建立多次TCP链接
-
数据压缩
- 一般消息主体会经过GZIP压缩,但是头部没有压缩,2.0新增加对头部的HPACK压缩,速度更快
-
服务端推送
- 1.1中的每个HTML、图片等等资源都需要建立请求,但是2.0通过ServerPush技术,允许服务器推送资源给浏览器,客户端可以本地加载,不用再次请求(预推送)
-
-
短连接
- 客户端与服务端每发起一次HTTP *** 作,就建立一次HTTP链接,如访问浏览器中HTML的资源或者其他WEB页面,每次请求资源都需要重新建立一个会话
-
长链接
- 长链接情况下,打开一个网页后,客户端与服务端的传输HTTP数据的TCP链接不会关闭,再次访问服务器会一直用这个链接
- HTTP1.1之后默认使用长链接,使用长链接会默认加入Connection:keep-alive
- 设置连接保持时间,如服务器Apache中设置,实现长链接需要客户端和服务端都支持。
-
怎么实现
- HTTP的长链接与短连接是基于TCP的长链接与短连接,HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。
- 无状态(Stateless)HTTP协议自身不对请求和响应之间的通信状态进行保存
-
token
- 服务端生成的一串随机字符串,作为客户端的令牌,第一次登录后,将token返回给客户端,之后带上token请求即可,无需带上用户名和密码
- Token可以存储在Cookie中,如存储在localStorage里面
-
cookie
-
类型
- 临时cookie,浏览器关闭即失效,cookie不设置时间即表示临时cookie,存储在内存中
- 永久cookie,设置了失效时间,存储在硬盘中,直到过期时间
-
用法
- 通常用来<客户端>(浏览器)保存用户信息
-
格式
-
-
session
-
定义
-
Session(会话):用来在<服务端>记录用户状态
-
Session会有一定的时间限制
- 如何设置Session时间限制?
-
-
理解
-
Session机制的存在就是为了解决HTTP无状态问题
-
在添加商品到购物车时,系统不知道是哪个用户 *** 作的,因为HTTP是无状态的,所以服务端给特定用户添加Session可以表示并跟踪用户。
- HTTP无状态:每次请求都是独立的,上次失败不会影响下一次 *** 作。
-
-
-
安全性问题
- Cookie存储在客户端,Session存储在服务端,Session相对来说安全性更高,如果在Cookie中写入一些敏感信息,可以加密后写入,然后在服务端进行解密,保证安全性。
-
如果禁用cookie会怎样?
- Cookie被禁用之后,大多数网站都会访问不了
- 解决:最常用就是在URL中把SessionID附加在URL路径后面
- Socket的流程
- Socket之后一定要断开连接么?什么时候会断开连接
- https://blog.csdn.net/wwd0501/article/details/52412396
- socket和websocket的区别
-
隐藏通信细则,无需直接处理Socket和HTTP
-
RPC和HTTP的差异
-
协议
- RPC可以基于HTTP也可以基于TCP
- HTTP是基于HTTP协议的
-
效率
- 极大减少了无效报文,报文体积更小
-
-
物理层
- 什么是全双工的工作模式
-
多个线程共享进程的堆和方法区(JDK1.8后),但是每个线程有自己的程序计数器、虚拟机栈和本地方法栈
- 所以系统在线程之间切换的成本要小的多,线程也被称作轻量级的进程。
-
线程是进程划分的更小运行单位,一个进程在执行过程中可以产生多个线程。
-
进程和线程最大区别是,进程运行是独立的,但是线程运行则不一定,因为同一进程中的线程极有可能会相互影响。线程开销小, 但是不利于资源的管理和保护,进程正相反。
-
初始、运行、阻塞、等待、超时等待、终止态
-
创建、就绪、运行、阻塞、结束
- 通过协议约定,如TCP/IP,采用Socket通信
- 具有亲缘关系的父子或者兄弟进程间通信(在内存中)
- 不同匿名管道只能亲缘通信,采用磁盘文件FIFO的方式,实现任意两个进程通信(在磁盘中)
- 强大,支持任意顺序访问,存在内核中,只有系统重启\显式删除时才会消失。(在内核中)
- 让进程知道某件事情已经发生
- 计数器,使用在多线程对共享资源的访问,避免竞争
- 多进程看到共享内存中的数据更新, *** 作需要依赖信号量或者互斥机制。
- 所有volatile修饰的变量一旦被某个线程更改,必须立即刷新到主内存
- 所有volatile修饰的变量在使用之前必须重新读取主内存的值
- 具备可见性和有序性,可见性方便进程见通信
- 一个线程通过join调用另一个线程时,此线程阻塞,直到执行完成后。
- 更像线程内部通信。当前线程和map绑定,可以存取任意值,节省方法间参数传递。
1、先到先服务
2、短作业优先
3、时间片轮转调度
4、多级反馈队列调度
1.2.6 产生死锁的条件锁分为线程锁&分布式锁。线程锁常考问题为:产生死锁条件、避免死锁、实现锁;分布式锁常考问题为:什么是分布式锁、如何实现分布式锁。
1、互斥
2、不可剥夺
3、请求保持
4、循环等待
1.2.7 如何避免死锁 1、预防死锁-对死锁的必要条件进行预防 2、避免死锁-在分配资源前判断是否会出现死锁 涉及算法:银行家算法 1.2.8 如何实现锁 1、Synchronize 2、Lock 1.2.9 什么是分布式锁 什么是虚拟内存 引用 map和set区别 1.3 Linux1.3.1 top命令有什么? 1.3.2 tcpdump的了解 1.3.3 netstat 1.3.4 找到一个目录下的a文件并删除 1.3.5 退出文本编辑的命令 二、Java 2.1 JVM 2.1.1 类加载机制 1、定义面了几家大厂中,基本问的很少,当然这也看面试官的喜好。把常用的命令记住就可以了,列出几道题作参考。
运行时,编译源码(.java)为字节码(.class),虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转化解析和初始化,最终形成虚拟机可以用的java类型,这就是虚拟机的类加载机制。
2.1.2、类加载机制/生命周期1、加载加验准解初使卸,类加载机制必须包含:加载、验证、准备、解析、初始化五步
-
字节流:通过全限定类名来获取定义此类的二进制字节流。
-
数据结构:将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
-
数据入口:在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。
- 确保 Class 文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
- 为类变量分配内存并设置类变量初始值,这些变量所使用的内存都将在方法区中进行分配。
- 类装载器装入类所引用的其他所有类
-
为类的静态变量赋予正确的初始值(上述过程中的静态变量都是虚拟机设置的默认值,此处赋予的才是程序员真正赋予的值),执行静态代码块
到初始化阶段,才真正开始执行类中定义的 Java 程序代码,此阶段是执行 () 方法的过程。
JVM提供3种类加载器(Class Loader),还可以用户自定义加载UserClassLoader
1、应用:(AppClassLoader)
- 加载应用程序主函数类
2、扩展(ExtClassLoader)
- 负责加载jar、lib、ext目录下的扩展类
3、启动:Bootstrap ClassLoader
- 加载核心类的库,如java.lang.*等
4、用户自定义:UserClassLoader
- 自定义加载器
1、自底向上看是否加载过
- 首先查看AppClassLoader是否加载过,如果没有加载,则查看父类ExtClassLoader是否加载,若还未加载则查看BootstrapClassLoader是否加载。
2、自顶向下依次加载
- 若都未加载,则从上到下以此查看是否可以加载,若加载不成功,则抛出ClassNotFoundException
1、安全性,避免用户定义的类替换了核心类,如String类的替换(阿里面试题)
2、避免限定命名的类重复加载,findLoadClass(),判断当前类是否已经加载
如何自己写一个String类,并进行替换?
2.1.6 创建类的三种方式- new
- 反射
- 反序列化
1、程序计数器JDK1.6和JDK1.8的内存结构是不一样的,主要体现在方法区的变化。
网吧网管,记录游戏存档,对应的也是记录线程执行位置。
为了线程切换后能恢复到正确的执⾏位置,每条线程都需要有⼀个独⽴的程序计数器,各 线程之间计数器互不影响,独⽴存储,我们称这类内存区域为“线程私有”的内存。
从上面的介绍中我们知道程序计数器主要有两个作⽤:
- 字节码解释器通过改变程序计数器来依次读取指令,从⽽实现代码的流程控制,如:顺序执 ⾏、选择、循环、异常处理。
- 在多线程的情况下,程序计数器⽤于记录当前线程执⾏的位置,从⽽当线程被切换回来的时 候能够知道该线程上次运⾏到哪儿了。
1、虚拟机栈又称作栈,用于存基础类型,如boolean、byte、char、integer等等类型。
2、在线程共享中的堆中,用来存储新建的对象,如String或者是其他class生成的对象,堆中的对象会调用虚拟机栈中的基础类型(堆调用栈)。
当然还有如变量表、 *** 作数栈、常量引用池等等信息,从发发调用直到引用完成。
- 执行java方法
本地方法的栈,包含其他语言编写的,被Native修饰的方法
本地方法栈用来存储一些Native定义的方法,之前在JVM中,在1.8之后被放在内存中
转换为元空间之后,其上限就是计算机内存的大小,但是同时可以用参数限制,如
- Native方法
- 存放对象实例
存放方法区常量和类元数据信息等等
- 子主题 1
说明
- 线程私有的:程序计数器、虚拟机栈、本地方法区
- 线程共享:堆、方法区、直接内存
栈是线程私有的,栈的最小单位是栈帧,栈帧中包含,局部变量表、 *** 作数栈、动态链接栈、方法出口
-
局部变量表
- 数组结构
存放基本类型,引用类型在堆中的地址,或者方法返回地址等
- 数组结构
-
*** 作数栈
- 栈结构( *** 作数据)
存放计算过程中的中间结果,同时作为计算过程中变量临时的存储空间
- 栈结构( *** 作数据)
-
动态链接
- 一个运行时常量池中该栈帧所属方法的引用
- 通俗:当你需要调用那个方法,可以通过动态链接找到方法在哪里
-
方法出口
- 正常和退出出口,记录方法后,继续运行哪一行代码(正常结束后该调用哪一行代码)
-
为何要有栈帧
-
类似于页面切换,每个方法作为一个帧,有利于资源及时释放,并且对 *** 作记录,方法为单位
-
分配策略
-
1、对象优先在Eden区分配
- 如果Eden没有足够空间分配,则会产生一次 Minor GC。
-
2、大对象直接进入老年代
- 大的对象需要连续的内存空间,
-
3、长期存活的对象将进⼊老年代
-
作用
- 静态变量(实例所有对象访问)、静态方法(工具类)、静态代码块(类成员变量初始化)、静态导包
-
优点
- 可以提高程序的运行性能,优化程序的结构
-
存储
- 静态成员变量确实存放在方法区;但JDK8之后就取消了“永久代”,取而代之的是“元空间”,永久代中的数据也进行了迁移,静态成员变量迁移到了堆中
GC的模式
-
分代式
-
YoungGC
- 当eden的区域分配满的时候触发,注意youngGC有部分存活的对象直接晋升到OldGC,所以youngGC之后,old gen的使用占比提升。
-
Full GC
-
频繁FullGC的原因
- 1、系统并发高,执行耗时长,数据量过大,导致youngGC频繁,且survivor放不下,导致进入老生代
- 2、程序一次性加载过多对象到内存,导致频繁有大对象进入老年代,导致频繁GC
- 3、老年带驻留大量释放不掉的对象,只要有一点对象进入老年代,则出现溢出,导致GC
- 4、元空间中加载的信息过多,也会导致FullGC
- 5、恶意代码调用System.gc()
-
-
-
准确分类
-
Partial GC
- Young GC:只收集youngGen的GC
- Old GC:只收集oldGen的GC
- MixedGC:收集整个youngGG和部分oldGend的GC
-
Full GC
- 收集整个堆
-
-
Collection中包含
-
常见的容器类
- 子主题 2
-
map和haspmap以及并发安全性
-
继承
-
封装
-
多态
-
定义
-
我们在程序中定义的引用变量所指向的具体类型和通过该引用变量的方法调用在编程的时候并不确定,当处于运行期间才确定。就是这个引用变量究竟指向哪一个实例对象,在编译期间是不确定的,只有运行期才能确定,这样不用修改源码就可以把变量绑定到不同的类实例上,让程序拥有了多个运行状态,这就是多态。
- 编译不确定,运行才确定
-
-
实现
-
继承父类
- 多个子类对同一个方法重写
-
实现接口
- 实现接口并覆盖同一方法
-
-
优点
- 拓展性和维护性
-
字节特别喜欢考的SQL
2.1 事务1、什么是事务,事务的四大特征
-
事务:是逻辑上的一组 *** 作,要么都执行,要么都不执行
- 如转账 *** 作,小明扣1000同时小红要+1000,要保证两个 *** 作同时成功,同时失败
2、并发事务带来的问题?
-
1、脏读
- 事务T1对数据修改,修改后的数据未提交,另一个数据访问此数据并,此时读到的数据为脏数据,可能引起 *** 作不正确
-
2、丢失修改
- 事务T1修改了数据,并发事务T2也修改数据,导致第一次修改的数据结果丢失,如20做-1,读取20又做-1,期望值为18,实际为19
-
3、不可重复读
- 一个事物多次读取同一个数据,由于并发事务T2对数据修改,导致两次读取数据不一致
-
4、幻读
- 事务T1读取数据,并发事务T2插入一些数据,导致事务T1在随后查询中发现一些原本不存在的数据,如同幻觉,称为幻读
-
举个项目中的例子说明事务,如银行转账
- 子主题 1
- 在学生当中查询至少有两门课大于80分的学生
- 数据库是统计一个学生的总分在总平均分之上的人数 这个我是三句写成,他问我能不能缩成一句,当然能,我就加括号缩成一句,他看着我比三句还多了几个括号的一句沉默了一会问我能不能精简,我说那肯定能
-
1、左连接、右链接、全连接、内连接
-
on 和 where
- where 的本质是过滤
- 1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。
- 2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。
-
驱动表(主表)
- left join … on,左表为主表,右表为被驱动表
-
-
链接
-
内连接
-
外连接
- 左外链接
- 右外连接
- 全链接
-
-
2、order by desc/asc
- 如:SELECT * FROM aaa ORDER BY num DESC // 降序
-
3、distinct
- 去重
-
limit 1,1
- 从第二行开始取,只取一个
- select distinct salary from Employee order by salary desc limit 1,1
-
常见函数
-
ifNull()
- 若不为空则返回第一个参数,若为空则返回第二个
- SELECT IFNULL(NULL, “RUNOOB”);
- 子主题 2
-
- IOC 控制反转
-
核心技术
- 依赖注入 DI
- AOP
- 事件
- 资源
- i18n
-
测试
- Spring MVC 的测试
-
数据访问
- 事务
- DAO支持
- JDBC
- ORM
- 子主题 5
-
Web支持
- 1、Spring AOP和IOC的理解
- IOC是一种思想,程序中由手动创建改为Spring框架管理
- IOC的容器本质就是Map,Map中存储的是各种对昂
- IOC容器就像一个工厂,需要创建对象时,只要配置好配置文件/注解即可,不需要考虑对象如何创建出来(一个项目的Service可能由几百个类作为底层)
- 2、Controller和RestController的区别
- Controller+ResponseBody=RestController
- 页面、XML或者JSON格式
- 3、SpringAOP和AspectJ AOP有什么区别
- AspectJ是静态织入,编译时
- SpringAOP是动态织入,运行时
- SpringAOP已经集成了AspecJ,而AspectJ又是java生态中最完整的AOP框架,所以SpringAOP更强大且更简单
- 性能,AspectJ更强大,切面多使用AspectJ
- 4、Spring Bean的作用域
- 5、Spring Bean的生命周期
- 6、将一个类声明为Spring的bean的注解有哪些
- Spring框架中用了那些设计模式
- Spring中的事务的方式有几种?
- 编程式事物,在代码中硬编码(不推荐)
- JPA,如何使用JPA在数据中非持久化一个字段
- Spring常用注解
- Spring注解原理
- 缓存有哪些?
- 缓存雪崩、缓存击穿
- 设置key失效时间的命令
- 子主题 4
-
为什么用消息中间件?
- 解耦、异步、削峰
-
用MQ不用RPC的原因
-
MQ解耦
- 上游执行时间缩短
- 物理解耦,上下游逻辑解耦
- 下游修改代码,上有只要增加Topic订阅即可
-
RPC响应
- 实时依赖下游返回,如登录
-
-
MQ测试点(字节)
-
中间件的测试要根据他的特点来测试,RocketMQ具有发布和订阅消息的
-
消费场景
-
正常的参数是否可以推送到指定TOPIC下
-
异常逆向参数是否有处理
-
多次发送消息,是否重复消费
-
pull和push的消费类型
- pull消费者决定什么时候发,push则为生产者决定
-
-
消费顺序
- 推送到不同broker是否有消费顺序问题
-
消费可靠
-
查看数据存储,数据持久化时间
-
数据丢失过程中的消息补发机制(网络等)
-
消费堆积,验证可用性
- 大的人群包
-
集群中一个Broker挂掉,验证可用
-
-
-
1、Kafka是什么?主要应用场景
-
是一个分布式流式处理平台
-
关键功能
- 1、消息队列:发布和订阅消息流,功能那个类似于消息队列,所以kafka被归类为消息队列
- 2、容错的持久方式存储记录消息流:kafka会把消息持久化到磁盘,避免了消息丢失的风险
- 3、流式处理平台:在消息发布的时候后进行处理,Kafka提供了一个完整的流式处理类库
-
应用场景
- 1、消息队列:建立实时流数据管道,以可靠地在系统或应用程序之间获得数据
- 2、数据处理:构建实时的流数据处理程序来转换或处理数据流
-
-
2、与其他消息队列相比,kafka的优势?
- 与RocketMQ或者RabbitMQ相比较
- 1、极致的性能:设计中使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息
- 2、生态系统兼容性无可匹敌:kafka与周边生态系统的兼容性是最好的没有之一,尤其是在大数据和流计算领域
- 早起kafka不可靠,但是现在短板都被修复
-
3、队列模型了解么?kafka的消息模型知道么?
-
1、队列模型
-
使用队列(Queue)作为消息通信载体,满足生产者消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留到直被超时。
- 所有的消息一定都能被消费?
- 超时的逻辑是多少?
-
队列模型问题
- 如果需要将生产者产生的消息分发给多个消费者,并且每个消费者都能接收到完整的消息内容。此时,队列模型就不好解决,当然
- 当然,如果与每个消费者之间都建立一个队列,则违背了消息队列的目的。
-
-
2、kafka消息模型
-
kafka使用的是发布-订阅模型
-
使用主题(Topic)作为消息通信的载体,类似于光布,发布一条消息,消息通过主题传递给所有订阅者(未订阅是受不到的)
- 如何设置订阅?
-
可以兼容队列模型,当只有一个订阅者时,在功能层面与队列模型相同
-
-
-
4、什么是Product、Consumer、Broker、Topic、Partition?
-
broker(代理),单独的kafka实例,多个kafka Broker组成一个kafka Cluster。
-
partition(分区),Partition属于Topic的一部分,一个topic可以有多个partition,并且同一个Topic下的Partition可以分布在不同的Broker下,也就表明一个Topic可以横跨多个Broker。
- Partition可以理解为消息队列的队列
-
-
5、kafka多副本机制解么?有什么好处
-
kafka为分区partition引入了多副本(Replica)机制。区分Partition中的多个副本之间会有一个leader跟多个其他副本follower,为我们发送的消息会被发送到leader副本,然后follower拉取leader副本中的消息同步。
-
生产者和消费者至于leader副本交付,其他副本为leader副本的拷贝。当leader发生故障时,会从follower中选取一个leader。
-
多分区(Partition)、多副本(Replica)机制好处
- 多个Partition分布在不同的Broker上,并发提升
- Partition指定对应的Replica的个数,提高消息存储的安全性,提升容灾能力,但是存储增加。
-
-
6、zookeeper中的kafka中的作用
-
1、需要自己搭建一套
-
主要事情
- Broker注册
- Topic注册
- 负载均衡等等
-
-
8、kafka如何保证消息的消费顺序
-
如何保证消息不丢失
-
如何保证消息不重复消费
-
1、什么是Netty
-
1、是一个基于NIO的Client-Server(客户端服务端)框架,可以快速简单开发网络应用程序
-
2、它极大的优化了TCP和UDP套接字服务器等网络编程,并且性能以及安全性很多方面更好
-
3、支持多协议 如FTP、SMTP、HTTP以及各种二进制和基于文本的传统协议
-
总结:Netty成功的找到了一种在不妥协可维护性和性能的情况下易于开发、性能、稳定性和灵活性的方法。
- 开源项目:如常用的Dubbo、RocketMQ、Elasticsearch、gRPC都用到Netty
-
-
子主题 2
分布式
- TCC
- AT
-
主流程
-
边界值
-
混合参数
-
异常场景
- 幂等,多次 *** 作唯一
- 并发
- 事务测试
- 环境异常
- 对数据库等 *** 作是
-
性能测试
-
RPC接口和HTTP接口
-
12306买票系统,查处车次,车站,车站名称和地点不能相关
-
微信红包的测试用例设计
-
定义
- 同一 *** 作发起一次或者多次请求结果是一致的
-
场景
- 接口超时重试
- 表单重复提交
- MQ消息重复读取
-
避免方式
-
token机制
- 放置页面重复提交,通过token生成一个随机数放在session中,然后将token发送给客户端
- 当然也可以用redis的方式来替代
-
唯一索引
- 给请求加唯一索引,如用户ID
-
删除delete
-
查询Select
-
悲观锁
-
乐观锁
- 更新数据一瞬间锁表,其他时间不锁表,相对于悲观锁的效率更高
-
分布式锁
- 子主题 1
-
- 回文
- LC52
- map和set区别
- 三数之和
- 最大子序列和
- TOP K
- TOP K最小的K个数字,三种方法
- 括号匹配
- 如何判断链表中有环,环的起点,双指针
- 最长回文
- 无重复最长子串
- 归并排序
- 合并两个有序数组
- 合并两个有序链表
- 统计词频率
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)