八股-场景题
场景 相关面试题
工厂方法模式
简单工厂(是编程习惯,不是设计模式)
简单工厂包含以下角色:
抽象产品:定义了产品的规范,描述了产品的主要特性和功能
具体产品:实现或者继承抽象产品的子类
具体工厂:提供了创建产品的方法,调用者通过该方法来获取产品

虽然说减少了 CoffeeStore
和 Coffee
的耦合,但是增加了 CoffeeStore
和 SimpleCoffeeFactory
、SimpleCoffeeFactory
和 Coffee
的耦合
工厂方法模式
完全遵循开闭原则(对扩展开放、对修改关闭)
主要角色:
- 抽象工厂(Abstract Factory):提供创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
- 具体工厂(ConcreteFactory):主要实现抽象工厂中的抽象方法,完成具体产品的创建
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂创建,它与具体工厂之间一一对应

优点:
- 用户仅需知晓具体工厂的名称,即可获取所需产品,无需了解产品的具体创建过程
- 系统新增产品时,仅需添加相应的产品类和对应的工厂类,无需对原有工厂结构进行任何修改,符合开闭原则
缺点:
- 每增加一种产品,就必须增加一个具体产品类及其对应的具体工厂类,这导致系统复杂度的增加
抽象工厂设计模式(企业开发较少使用)
工厂方法模式只考虑生产同等级的产品,抽象工厂可以处理多等级产品的生产
产品族:一个品牌下面的所有产品;例如华为下面的电脑、手机称为华为的产品族
产品等级:多个品牌下面的同种产品;例如华为和小米都有手机电脑为一个产品等级,
抽象工厂模式是工厂方法模式的进阶版本。与仅生产单一等级产品的工厂方法模式不同,抽象工厂模式能够生产多个等级的产品
一个超级工厂负责创建其他工厂,这一超级工厂亦被称为其他工厂的“工厂”

当前咖啡店业务发生转变,不仅生产咖啡,还推出甜点系列。
产品等级(产品分类) :
- 咖啡:拿铁咖啡、美式咖啡
- 甜点:提拉米苏、抹茶慕斯
同一风味对应同一产品族(相当于同一品牌) :
- 美式风味:美式咖啡、抹茶慕斯
- 意大利风味:拿铁咖啡、提拉米苏
优点:
- 当一个产品族中的多个对象被设计成协同工作时,它能确保客户端始终仅使用同一产品族中的对象
缺点:
- 当产品族中需要添加一个新的产品时,所有工厂类均需进行相应的修改
策略模式
该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。算法的变化不会影响使用算法的客户
它通过对算法进行封装,将使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理

优点:
- 策略类之间可自由切换
- 易于扩展
- 避免使用多重条件选择语句(如if-else),充分体现面向对象设计思想
缺点:
- 客户端必须了解所有策略类,并自主选择使用相应的策略类
- 策略模式可能导致产生大量策略类
案例(工厂模式+策略模式)



责任链设计模式
责任链模式:为避免请求发送者与多个请求处理者直接耦合,将所有请求处理者通过前一对象记住其下一个对象的引用,从而串联成一条链。当请求发生时,请求可沿着此链传递,直至有对象能够处理该请求
常见的拦截器和过滤器都是责任链设计模式
抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断是否能够处理本次请求。若能处理,则执行处理;否则,将该请求转给其后的继任者
客户类(Client)角色:构建处理链,并向链首的具体处理者对象提交请求。它不关注处理细节及请求的传递过程
处理订单的操作:

优点:
- 降低对象间的耦合度
- 增强系统的可扩展性
- 提高对象指派职责的灵活性
- 简化对象间的连接
- 责任分担
缺点:
对于较长的职责链,请求的处理可能涉及多个处理对象,这可能会对系统性能产生一定影响
职责链的合理性依赖于客户端的建立,这增加了客户端的复杂性。错误设置职责链可能导致系统出错,例如,可能会引发循环调用
常用:
内容审核(文本、图片、视频)
订单创建
简易流程审批
单点登录
单点登录的英文名称为:Single Sign On(简称SSO),仅需登录一次,即可访问所有受信任的应用系统

JWT 单点登录

权限认证
后台管理系统,更注重权限控制,其中最常见的是采用RBAC模型(基于角色的访问控制)来指导权限实现
RBAC(Role-Based Access Control)即基于角色的访问控制
该模型由三个基础部分组成:用户、角色、权限
具体实现方面:
- 采用5张表:用户表、角色表、权限表、用户角色中间表、角色权限中间表
- 或采用7张表:用户表、角色表、权限表、菜单表、用户角色中间表、角色权限中间表、权限菜单中间表


上传数据的安全性如何控制(网络传输)
使用非对称加密(或对称加密),给前端一个公钥让他把数据加密后传到后台,后台负责解密后处理数据
文件较大时,建议采用对称加密,但不宜用于保存敏感信息。
文件规模较小,且对安全性要求较高,则推荐使用非对称加密
对称加密
文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥

优点:加密速度快,效率高
缺点:相对不太安全(不要保存敏感信息)
非对称加密
两个密钥:公开密钥(publickey)和私有密钥,公有密钥加密,私有密钥解密

优点:与对称加密相比,安全性更高
缺点:加密和解密速度慢,建议少量数据加密
遇到了哪些棘手的问题,怎么解决
背景(技术问题)
解决方案过程
最终实施方案
设计模式
- 工厂
- 策略
- 责任链
- ......
线上 BUG
- CPU 飙高
- 内存泄漏
- 线程死锁
- ......
调优
- 慢接口
- 慢 SQL
- 缓存方案
- ......
组件封装
分布式锁
接口幂等
分布式事务
支付通用
......
日志采集
为什么要采集日志?
- 日志是定位系统问题的重要手段,可根据日志信息迅速定位系统中的问题
采集日志的方式有哪些?
- ELK:即Elasticsearch、Logstash和Kibana,三个软件首字母的缩写。
- 常规采集:按日保存至一个日志文件
Elasticsearch是一款全文搜索与分析引擎,具备对数据存储、搜索及分析的能力
Logstash是一款数据收集引擎,它能动态地收集数据,并支持数据的过滤与分析,将数据存储至指定位置
Kibana是一个数据分析和可视化平台,与Elasticsearch配合使用,实现对数据的搜索、分析及图表化展示

查看日志的命令
目前采集日志的方式:按天保存到一个日志文件
Linux中日志查看与处理:
实时监控日志变化
-
tail -f xx.log
-
tail -n 100 -f xx.log
-
按行号查询日志
-
tail -n 100 xx.log
-
head -n 100 xx.log
-
cat -n xx.log | tail -n +100 | head -n 100
查询 100-200 行的日志
-
按关键字检索日志信息
-
cat -n xx.log | grep "debug"
只能查到行号
-
按日期筛选日志
-
sed -n '/2023-05-18 14:22:31.070/,/2023-05-18 14:27:14.158/p' xx.log
-
日志过多时的处理方式
-
cat -n xx.log | grep "debug" | more
分页查询 -
cat -n xx.log | grep "debug" > debug.txt
筛选过滤后,输出到一个文件
-
生产问题怎么排查
已上线bug排查思路:
- 首先分析日志,通常业务中都会有日志记录,或查看系统日志,或查阅日志文件,进而定位问题
- 进行远程调试(通常公司正式环境(生产环境)不允许远程调试。一般远程调试应用于公司测试环境,便于调试代码)
远程 debug
前提条件:远程的代码和本地的代码要保持一致
步骤:
- 远程代码需要配置启动参数,把项目打包放到服务器后启动项目的参数:
java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 project-1.0-SNAPSHOT.jar
- 在 idea 中设置远程 debug,找到 idea 中的 Edit Configurations...

- idea 中启动远程 debug

- 访问远程服务器,在本地代码中打断点即可调试远程
如何快速定位系统瓶颈
性能测试(压测),在项目上线前对系统进行压力测试
监控工具、链路追踪工具,用于项目上线后的监控
线上诊断工具Arthas(阿尔萨斯),用于项目上线后的监控与排查
压测(性能测试)
- 压测目的:给出系统当前的性能状况;定位系统性能瓶颈或潜在性能瓶颈
- 指标:响应时间、QPS、并发数、吞吐量、CPU利用率、内存使用率、磁盘IO、错误率
- 压测工具:LoadRunner、Apache Jmeter ...
- 后端工程师:根据压测的结果进行解决或调优(接口慢、代码报错、并发达不到要求...)
监控工具、链路追踪工具
- 监控工具:Prometheus+Grafana
- 链路追踪工具:skywalking、Zipkin
线上诊断工具 Arthas
核心功能:
- 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
- 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
- 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到 JVM 的实时运行状态?
- 怎么快速定位应用的热点,生成火焰图?
- 怎样直接从 JVM 内查找某个类的实例?