1. 为什么前端在浏览器上渲染,不通过前端直接访问后端会有跨域问题?

跨域问题产生的原因:

常见跨域解决方案:

  1. CORS(跨域资源共享):
    • 后端设置 Access-Control-Allow-Origin 等响应头允许跨域访问。
  2. JSONP:
    • 通过 <script> 标签加载 JSON 格式的数据,只支持 GET 请求。
  3. 代理转发:
    • 在前端开发中,利用代理服务器(如 Nginx、Node.js 等)转发请求,使前端的请求看起来像是从同源服务器发出的。

2. 前端工程需要安装 Nginx 插件才能解决跨域问题吗?

不一定。


3. 什么是 WITH [RECURSIVE]?

WITH [RECURSIVE] 是 SQL 中用于定义**公共表表达式(Common Table Expression,简称 CTE)**的语法结构,允许在查询中定义临时结果集。

逐词解析语法:

WITH [RECURSIVE]
    cte_name [(col_name [, col_name] ...)] AS (subquery)
    [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

4. 为什么两种递归 SQL 写法结果不同?

以下为两种写法的比较:

写法 1(正确):

WITH RECURSIVE t1 AS (
    SELECT * 
    FROM course_category p 
    WHERE id = '1'
    UNION ALL
    SELECT t.* 
    FROM course_category t 
    INNER JOIN t1 ON t1.id = t.parentid
)
SELECT *  
FROM t1 
ORDER BY t1.id, t1.orderby;

写法 2(报错):

WITH RECURSIVE t1 AS (
    SELECT * 
    FROM course_category p 
    WHERE id = '1'
    UNION ALL
    SELECT * 
    FROM course_category t 
    INNER JOIN t1 ON t1.id = t.parentid
)
SELECT *  
FROM t1 
ORDER BY t1.id, t1.orderby;

原因分析:

报错信息 [21000][1222] The used SELECT statements have a different number of columns 表示:

解决方法:

显式列出字段,确保两部分 SELECT 的列数和顺序一致。


5. Java Stream API 示例分析

代码:

Map<String, CourseCategoryTreeDto> mapTemp = courseCategoryTreeDtos.stream()
    .filter(item -> !id.equals(item.getId()))
    .collect(Collectors.toMap(
        key -> key.getId(),
        value -> value,
        (key1, key2) -> key2
    ));

逐步解析:

  1. courseCategoryTreeDtos.stream()
    courseCategoryTreeDtos 转换为流对象,便于链式操作。
  2. .filter(item -> !id.equals(item.getId()))
    使用过滤条件,排除 id 匹配的元素。
  3. .collect(Collectors.toMap(...))
    将流中的数据收集为 Map,指定了 keyvalue 的生成规则:
    • key -> key.getId()
      每个元素的 id 作为 Map 的键。
    • value -> value
      每个元素本身作为 Map 的值。
    • (key1, key2) -> key2
      解决键冲突时的处理方式,保留后一个值。

6. RPC(远程过程调用)

概念:

RPC(Remote Procedure Call)是一种允许调用远程服务器上的方法,就像调用本地方法一样的技术。

核心特点:

  1. 封装底层通信细节
    隐藏网络通信、序列化等复杂过程,让远程调用看起来像本地调用。
  2. 跨语言支持
    许多现代 RPC 框架支持多语言互操作。

工作流程:

Client App  -->  Client Stub  -->  Network  -->  Server Stub  -->  Server App
  1. 客户端调用本地代理(Client Stub):
    • 序列化方法和参数,发送到服务器。
  2. 服务端接收请求(Server Stub):
    • 反序列化请求,调用实际方法。
  3. 返回结果:
    • 服务端序列化结果,客户端反序列化结果,交给应用程序。

常见 RPC 框架: