2025.07.09
一个页面需要请求三个不同的域名服务器(图片服务器、API服务器、当前页面服务器),这样会产生跨域问题吗?如何解决?
解答:
肯定会产生跨域问题,因为浏览器的同源策略限制,只要协议、域名、端口任何一个不同就算跨域。
跨域产生的原因:
浏览器的同源策略是一种安全机制
同源指:协议、域名、端口完全相同
例如:
https://www.example.com访问https://api.example.com就是跨域
解决方案:
CORS(推荐):后端设置响应头允许跨域
代理:开发环境用webpack代理,生产环境用nginx反向代理
JSONP:只支持GET请求,利用script标签不受同源策略限制
什么是反向代理?一个反向代理服务器可以代理多个后端服务吗?
解答:
反向代理是代理服务器的一种,客户端请求反向代理服务器,代理服务器再转发给后端服务器,然后将结果返回给客户端,可以配置多个后端服务。
反向代理特点:
客户端不知道实际服务的存在
服务端的代理,对客户端透明
与正向代理相反(正向代理是客户端代理)
反向代理的优势:
负载均衡:将请求分发到多个服务器
缓存加速:缓存静态资源,提高访问速度
SSL终止:统一处理HTTPS加密解密
隐藏服务器:保护后端服务器安全
路径分发:根据不同URL路径转发到不同服务
Vue2中有哪些路由钩子?它们执行顺序是什么?
解答:
Vue2的路由钩子分为三类:全局钩子,路由独享钩子,组件内钩子。
全局钩子:
BeforeEach:全局前置守卫,每次路由切换前执行BeforeResolve:全局解析守卫,在导航被确认前执行afterEach:全局后置钩子,路由切换完成后执行
路由独享钩子:
beforeEnter:在路由配置中定义,只对该路由生效
组件内钩子:
beforeRouteEnter:进入组件前调用,此时组件实例还没创建beforeRouteUpdate:路由改变但组件被复用时调用beforeRouteLeave:离开组件前调用,可以阻止用户离开
执行顺序: beforeEach → beforeEnter → beforeRouteEnter → beforeResolve → afterEach
前端菜单权限系统的实现流程是什么?如何处理菜单权限和按钮权限?
说明解释
完整实现流程:
后台配置阶段:
管理员配置菜单信息(路由路径、组件路径、菜单名称、图标等)
配置按钮权限(增删改查等操作权限)
将菜单和按钮权限分配给不同角色
用户登录阶段:
用户登录后,后端根据用户角色返回可访问的菜单列表
包含菜单信息和按钮权限标识
前端处理阶段:
动态生成路由配置并添加到路由器
构建菜单树结构用于侧边栏显示
根据权限标识控制按钮的显示和启用状态
权限控制层级:
路由级别:控制页面是否可访问
菜单级别:控制菜单是否显示
按钮级别:控制操作按钮是否可用
要点:理解权限系统的分层设计,掌握动态路由的实现原理。
JavaScript中数组去重有哪些方法?如何将数组转换为逗号分隔的字符串?
解答
数组去重:1) [...new Set(array)] 2) filter + indexOf 3) reduce方法 数组转字符串:1) array.join(',') 2) array.toString()
说明解释
数组去重方法:
ES6 Set方法:
[...new Set(array)]利用Set数据结构不允许重复值的特性
最简洁,性能好
filter + indexOf:
array.filter((item, index) => array.indexOf(item) === index)保留第一次出现的元素
兼容性好,但性能相对差
reduce方法:使用reduce累加器判断元素是否已存在
数组转字符串方法:
join方法:
array.join(',')专门用于数组转字符串
可以指定分隔符
toString方法:
array.toString()默认用逗号分隔
不能自定义分隔符
要点:掌握ES6新特性的使用,理解不同方法的性能差异。
Spring Cloud是什么?它的核心组件有哪些,各自的作用是什么?
解答
Spring Cloud是微服务架构的一站式解决方案,提供了服务发现、配置管理、断路器、API网关等组件。
说明解释
Spring Cloud核心组件:
Eureka:服务注册与发现中心
服务提供者注册到Eureka Server
服务消费者从Eureka Server获取服务列表
Ribbon:客户端负载均衡
在服务消费者端实现负载均衡
支持多种负载均衡策略
Feign:声明式服务调用
通过接口和注解方式调用服务
集成了Ribbon和Hystrix
Hystrix:断路器
服务熔断、降级、限流
防止雪崩效应
Zuul/Gateway:API网关
统一入口,路由转发
权限验证、限流等
Config:配置中心
集中管理配置文件
支持动态刷新
要点:理解微服务架构的基本概念,掌握各组件在系统中的作用。
过滤器和拦截器的区别是什么?它们的执行顺序如何?
解答
过滤器基于Servlet规范,在请求进入容器时执行;拦截器基于Spring框架,在Controller执行前后执行。执行顺序:Filter → Interceptor → Controller。
说明解释
过滤器(Filter):
层级:Servlet容器级别
规范:基于Servlet规范
作用:请求和响应的预处理和后处理
使用场景:字符编码、XSS防护、日志记录、权限验证
拦截器(Interceptor):
层级:Spring框架级别
规范:基于Spring MVC
作用:Controller执行前后的处理
使用场景:登录验证、权限检查、日志记录、性能监控
执行顺序:
请求 → Filter前置处理 → Interceptor.preHandle → Controller执行
→ Interceptor.postHandle → Interceptor.afterCompletion → Filter后置处理 → 响应主要区别:
Filter能够修改请求和响应对象,Interceptor不能
Filter在Servlet容器中执行,Interceptor在Spring容器中执行
Filter对所有请求生效,Interceptor只对Controller请求生效
要点:理解两者的设计层次不同,掌握它们在请求处理流程中的位置。
Spring Boot项目中常用的注解有哪些?它们的作用是什么?
解答
主要分为组件注解、依赖注入注解、Web注解、配置注解等几类。
说明解释
组件注解:
@Component:通用组件注解@Service:业务层组件@Repository:数据访问层组件@Controller:控制层组件@RestController:REST控制器(@Controller + @ResponseBody)
依赖注入注解:
@Autowired:自动装配,按类型注入@Resource:按名称注入@Qualifier:指定注入的bean名称@Value:注入配置文件中的值
Web注解:
@RequestMapping:请求映射@GetMapping、@PostMapping:HTTP方法映射@PathVariable:路径参数@RequestParam:请求参数@RequestBody:请求体参数@ResponseBody:响应体
配置注解:
@Configuration:配置类@Bean:定义bean@ComponentScan:组件扫描@SpringBootApplication:Spring Boot启动类
其他重要注解:
@Transactional:事务管理@Aspect:切面@Cacheable:缓存
要点:理解注解的分类和使用场景,掌握Spring的依赖注入机制。
如何在Spring项目中实现AOP切面?步骤是什么?
解答
使用Spring AOP实现切片:1) 添加AOP依赖 2) 创建切面类 3) 定义切点 4) 实现通知方法 5) 配置切面。
说明解释
AOP实现步骤:
添加依赖:
spring-boot-starter-aop创建切面类:使用
@Aspect注解标记定义切点:使用
@Pointcut定义切入点表达式实现通知:定义在切点前后执行的方法
通知类型:
@Before:前置通知,方法执行前@After:后置通知,方法执行后@Around:环绕通知,方法执行前后@AfterReturning:返回通知,方法成功返回后@AfterThrowing:异常通知,方法抛出异常后
切点表达式:
execution():匹配方法执行within():匹配类型@annotation():匹配注解
常用场景:
日志记录:记录方法调用和参数
性能监控:统计方法执行时间
事务管理:自动事务控制
权限验证:检查用户权限
缓存处理:自动缓存结果
要点:理解AOP的核心概念(切面、切点、通知),掌握切点表达式的写法。
API接口安全需要考虑哪些方面?如何保证接口的安全性?
解答
接口安全包括:身份认证、权限控制、参数校验、传输安全、接口限流、数据加密、防护攻击等多个方面。
说明解释
接口安全的主要方面:
身份认证:
JWT Token验证
OAuth2.0授权
API Key认证
权限控制:
基于角色的访问控制(RBAC)
细粒度权限验证
资源级别的权限控制
参数校验:
输入参数验证
数据类型检查
长度和格式限制
传输安全:
HTTPS加密传输
证书验证
传输层安全协议
防护攻击:
SQL注入防护
XSS攻击防护
CSRF防护
请求伪造防护
接口限流:
防止恶意请求
避免系统过载
基于IP或用户的限流
数据安全:
敏感数据加密
数据脱敏
审计日志记录
要点:理解接口安全是一个体系化的工程,需要从多个层面进行防护。
Java线程池的核心参数有哪些?它们的作用是什么?
解答
线程池的核心参数有7个:corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler。
说明解释
线程池核心参数:
corePoolSize:核心线程数
池中始终保持的线程数量
即使空闲也不会销毁
maximumPoolSize:最大线程数
池中允许的最大线程数量
当队列满时会创建新线程
keepAliveTime:线程存活时间
非核心线程的空闲存活时间
超过这个时间会被销毁
unit:时间单位
keepAliveTime的时间单位
如TimeUnit.SECONDS
workQueue:任务队列
ArrayBlockingQueue:有界队列
LinkedBlockingQueue:无界队列
SynchronousQueue:不存储队列
threadFactory:线程工厂
创建线程的工厂
可以自定义线程名称、优先级等
handler:拒绝策略
AbortPolicy:抛出异常
CallerRunsPolicy:调用者执行
DiscardPolicy:丢弃任务
DiscardOldestPolicy:丢弃最老任务
线程池工作流程:
小于corePoolSize时,创建新线程
达到corePoolSize时,任务放入队列
队列满时,创建新线程直到maximumPoolSize
超过maximumPoolSize时,执行拒绝策略
要点:理解线程池的工作机制,掌握参数调优的原则。
Redis的主要应用场景有哪些?Redis的内存淘汰机制是什么?
解答
Redis主要用于缓存、分布式锁、计数器、消息队列、session存储等。内存淘汰机制有8种策略。
说明解释
Redis主要应用场景:
缓存:提高数据访问速度,减少数据库压力
分布式锁:解决分布式系统的并发控制问题
计数器:点赞数、访问量、库存等实时计数
消息队列:简单的队列服务,发布订阅模式
Session存储:分布式系统的会话共享
排行榜:利用有序集合实现排行功能
限流:接口访问频率控制
内存淘汰机制8种策略:
noeviction:不淘汰,内存满时返回错误
allkeys-lru:所有key中淘汰最少使用的
allkeys-lfu:所有key中淘汰最少频率使用的
allkeys-random:所有key中随机淘汰
volatile-lru:有过期时间的key中淘汰最少使用的
volatile-lfu:有过期时间的key中淘汰最少频率使用的
volatile-random:有过期时间的key中随机淘汰
volatile-ttl:有过期时间的key中淘汰即将过期的
选择策略:
缓存场景:allkeys-lru或allkeys-lfu
有明确过期时间:volatile-lru或volatile-ttl
数据重要性相同:random策略
要点:理解Redis在系统架构中的作用,掌握内存管理机制。
MySQL主键应该选择什么数据类型?选择的原则是什么?
解答
推荐使用BIGINT AUTO_INCREMENT作为主键,分布式环境可以考虑UUID或雪花算法ID。
说明解释
推荐的主键类型:
BIGINT AUTO_INCREMENT:
单机环境的最佳选择
占用空间小,索引效率高
顺序递增,插入性能好
UUID:
分布式环境可用
全局唯一,但性能相对较差
占用空间大,索引效率低
雪花算法ID:
分布式环境的较好选择
全局唯一,性能好于UUID
包含时间信息,有一定顺序性
选择原则:
避免业务字段:不使用业务相关字段作为主键
考虑性能:主键会影响索引性能和存储效率
考虑扩展性:分布式环境需要全局唯一
考虑存储空间:主键在每个索引中都会存储
不推荐的做法:
使用字符串类型作为主键
使用业务字段(如身份证号)作为主键
使用复合主键(除非必要)
要点:理解主键对数据库性能的影响,根据系统架构选择合适的主键类型。
如何使用EXPLAIN分析MySQL查询性能?重点关注哪些字段?
解答
EXPLAIN用于分析SQL执行计划,重点关注type、key、rows、Extra字段来判断查询性能。
说明解释
EXPLAIN关键字段解读:
type:连接类型,性能从好到差
system:系统表,只有一行
const:常量查询,通过主键或唯一索引
eq_ref:唯一索引扫描
ref:非唯一索引扫描
range:范围扫描
index:索引全扫描
ALL:全表扫描(需要优化)
key:实际使用的索引
如果为NULL,说明没有使用索引
显示具体使用的索引名称
rows:预估扫描的行数
数值越小越好
结合表的总行数判断扫描比例
Extra:额外信息
Using index:使用覆盖索引(好)
Using where:使用where条件过滤
Using filesort:使用文件排序(需要优化)
Using temporary:使用临时表(需要优化)
优化重点:
避免type为ALL的全表扫描
确保复杂查询使用了索引
避免Extra中出现filesort和temporary
控制rows的数量在合理范围
优化策略:
为where条件添加索引
为order by字段添加索引
使用覆盖索引避免回表
优化查询语句结构
要点:掌握EXPLAIN的使用方法,能够根据执行计划进行SQL优化。
MySQL服务器CPU使用率过高(200%-300%)的可能原因有哪些?如何排查和解决?
解答
主要原因:慢查询、锁等待、连接数过多、死锁、大量并发等。需要通过查看进程列表、慢查询日志、锁状态等方式排查。
说明解释
CPU高使用率的可能原因:
慢查询:
没有使用索引的查询
大表的全表扫描
复杂的多表关联查询
锁等待:
长事务持有锁时间过长
大量事务等待锁释放
表锁、行锁竞争激烈
连接数过多:
超过max_connections设置
连接池配置不合理
应用没有正确释放连接
死锁:
多个事务相互等待对方释放资源
事务设计不合理
大量并发:
瞬时高并发超过服务器承载能力
缺少有效的限流机制
排查步骤:
查看当前连接:
SHOW PROCESSLIST分析慢查询:查看慢查询日志
检查锁状态:
SHOW ENGINE INNODB STATUS监控系统资源:CPU、内存、磁盘IO
检查配置参数:缓冲池大小、连接数限制等
解决方案:
优化慢查询:添加索引、改写SQL
调整事务:减少长事务,合理设计事务边界
优化配置:调整缓冲池、连接数等参数
加强监控:建立性能监控和告警机制
架构优化:读写分离、分库分表、缓存
要点:理解数据库性能问题的常见原因,掌握系统的排查和优化方法。