Java 项目实战: 外卖平台优化-Nginx目录结构与conf配置文件体系

接入 Nginx: 安装目录结构剖析与 conf 配置文件体系

纲要

本篇对应课程 day02 的「Nginx 目录结构」,把安装后 /usr/local/nginx 下的四个目录拆开讲透:

  • 四大目录职责 :conf(配置)、html(静态资源)、logs(日志)、sbin(二进制)
  • conf/ 完整清单 :nginx.conf 是唯一入口,其余 fastcgi/uwsgi/scgi/mime.types/koi-* 各自的作用
  • html/ 默认页面 :index.html 与 50x.html 的触发时机
  • logs/ 三类文件 :access.log、error.log、nginx.pid,以及 pid 文件的生命周期
  • 运行后新增的临时目录 :client_body_temp 等 *_temp 目录的用途
  • tree 命令:目录结构可视化的小工具

#mermaid-svg-0PqicsAnOelTr8GO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0PqicsAnOelTr8GO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0PqicsAnOelTr8GO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0PqicsAnOelTr8GO .error-icon{fill:#552222;}#mermaid-svg-0PqicsAnOelTr8GO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0PqicsAnOelTr8GO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0PqicsAnOelTr8GO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0PqicsAnOelTr8GO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0PqicsAnOelTr8GO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0PqicsAnOelTr8GO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0PqicsAnOelTr8GO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0PqicsAnOelTr8GO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0PqicsAnOelTr8GO .marker.cross{stroke:#333333;}#mermaid-svg-0PqicsAnOelTr8GO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0PqicsAnOelTr8GO p{margin:0;}#mermaid-svg-0PqicsAnOelTr8GO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0PqicsAnOelTr8GO .cluster-label text{fill:#333;}#mermaid-svg-0PqicsAnOelTr8GO .cluster-label span{color:#333;}#mermaid-svg-0PqicsAnOelTr8GO .cluster-label span p{background-color:transparent;}#mermaid-svg-0PqicsAnOelTr8GO .label text,#mermaid-svg-0PqicsAnOelTr8GO span{fill:#333;color:#333;}#mermaid-svg-0PqicsAnOelTr8GO .node rect,#mermaid-svg-0PqicsAnOelTr8GO .node circle,#mermaid-svg-0PqicsAnOelTr8GO .node ellipse,#mermaid-svg-0PqicsAnOelTr8GO .node polygon,#mermaid-svg-0PqicsAnOelTr8GO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0PqicsAnOelTr8GO .rough-node .label text,#mermaid-svg-0PqicsAnOelTr8GO .node .label text,#mermaid-svg-0PqicsAnOelTr8GO .image-shape .label,#mermaid-svg-0PqicsAnOelTr8GO .icon-shape .label{text-anchor:middle;}#mermaid-svg-0PqicsAnOelTr8GO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0PqicsAnOelTr8GO .rough-node .label,#mermaid-svg-0PqicsAnOelTr8GO .node .label,#mermaid-svg-0PqicsAnOelTr8GO .image-shape .label,#mermaid-svg-0PqicsAnOelTr8GO .icon-shape .label{text-align:center;}#mermaid-svg-0PqicsAnOelTr8GO .node.clickable{cursor:pointer;}#mermaid-svg-0PqicsAnOelTr8GO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0PqicsAnOelTr8GO .arrowheadPath{fill:#333333;}#mermaid-svg-0PqicsAnOelTr8GO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0PqicsAnOelTr8GO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0PqicsAnOelTr8GO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0PqicsAnOelTr8GO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0PqicsAnOelTr8GO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0PqicsAnOelTr8GO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0PqicsAnOelTr8GO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0PqicsAnOelTr8GO .cluster text{fill:#333;}#mermaid-svg-0PqicsAnOelTr8GO .cluster span{color:#333;}#mermaid-svg-0PqicsAnOelTr8GO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0PqicsAnOelTr8GO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0PqicsAnOelTr8GO rect.text{fill:none;stroke-width:0;}#mermaid-svg-0PqicsAnOelTr8GO .icon-shape,#mermaid-svg-0PqicsAnOelTr8GO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0PqicsAnOelTr8GO .icon-shape p,#mermaid-svg-0PqicsAnOelTr8GO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0PqicsAnOelTr8GO .icon-shape .label rect,#mermaid-svg-0PqicsAnOelTr8GO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0PqicsAnOelTr8GO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0PqicsAnOelTr8GO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0PqicsAnOelTr8GO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} /usr/local/nginx
conf/
html/
logs/
sbin/
nginx.conf ★核心配置
nginx.conf.default 备份
mime.types MIME映射
fastcgi.conf / fastcgi_params
uwsgi_params / scgi_params
koi-utf / koi-win / win-utf 编码转换
index.html 默认首页
50x.html 错误页
access.log 访问日志
error.log 错误日志
nginx.pid master进程ID

仅运行时存在
nginx 二进制可执行文件

一、顶层目录结构

安装完成后进入安装目录:

bash 复制代码
cd /usr/local/nginx
ls

输出:

txt 复制代码
conf  html  logs  sbin

只有四个目录,这是 Nginx "轻量"的一个直观体现。用 tree 命令看更清晰:

bash 复制代码
tree

若提示 command not found,先安装:

bash 复制代码
yum install tree

tree 的输出大致如下(未启动状态):

txt 复制代码
.
├── conf
│   ├── fastcgi.conf
│   ├── fastcgi.conf.default
│   ├── fastcgi_params
│   ├── fastcgi_params.default
│   ├── koi-utf
│   ├── koi-win
│   ├── mime.types
│   ├── mime.types.default
│   ├── nginx.conf
│   ├── nginx.conf.default
│   ├── scgi_params
│   ├── scgi_params.default
│   ├── uwsgi_params
│   ├── uwsgi_params.default
│   └── win-utf
├── html
│   ├── 50x.html
│   └── index.html
├── logs
└── sbin
    └── nginx

logs 为空------因为服务还没启动过。

二、conf 目录:配置文件存放处

conf 是后续所有工作的主战场。文件虽多,真正需要掌握的只有两个。

nginx.conf ------ 核心配置文件

这是 Nginx 的唯一配置入口,后面所有能力(部署静态资源、反向代理、负载均衡)全部通过修改它实现。

它的完整结构见下一篇,这里先记住三点:

  • Nginx 启动时默认加载的就是 conf/nginx.conf
  • 它由若干个"块"组成:main(全局)、events、http(内含 server,server 内含 location)
  • include 指令可以把其他文件引入进来,这就是 mime.types 等文件被使用的原因

nginx.conf.default ------ 默认配置备份

是源码自带的原始配置副本。当把 nginx.conf 改坏且无从恢复时,可以直接把它复制回去:

bash 复制代码
cp /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf

这也是一个值得养成的习惯:每次大改配置前先备份。

bash 复制代码
cp nginx.conf nginx.conf.bak.$(date +%Y%m%d%H%M%S)

mime.types ------ MIME 类型映射表

定义了文件扩展名与 Content-Type 响应头的对应关系 。nginx.conf 里通常有一行:

nginx 复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;
    ...
}

mime.types 内容形如:

nginx 复制代码
types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/javascript                js;
    application/atom+xml                  atom;
    application/rss+xml                   rss;
    text/plain                            txt;
    image/png                             png;
    image/svg+xml                         svg svgz;
    application/json                      json;
    application/pdf                       pdf;
    ...
}

为什么重要 :浏览器依据 Content-Type 决定如何处理响应体。

  • 若 .css 被当成 application/octet-stream 返回,浏览器会拒绝应用样式,页面变成裸 HTML
  • 若 .js 的 Content-Type 不对,现代浏览器会直接拒绝执行并报 MIME type mismatch

所以不要删掉 include mime.types; 。如果用了 mime.types 里没有的扩展名(比如 .wasm、.m3u8),会回退到 default_type(二进制流下载),需要手动补一行 types 或在 location 里用 add_header 覆盖。

fastcgi.conf / fastcgi_params ------ FastCGI 参数

用于把请求转发给 PHP-FPM 之类的 FastCGI 程序。二者内容几乎相同,区别仅在于 fastcgi.conf 多定义了 SCRIPT_FILENAME:

nginx 复制代码
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;

本项目的 Java 技术栈完全用不到这两个文件 ,它们是 LNMP(Linux+Nginx+MySQL+PHP)架构的产物。

uwsgi_params / scgi_params

分别用于 uWSGI 协议(Python 应用)和 SCGI 协议。同样是本项目用不到的历史遗留文件。

koi-utf / koi-win / win-utf ------ 字符集转换表

用于 KOI8-R(俄文)与 Windows-1251 之间的编码转换。因为 Nginx 出自俄罗斯,早期需要照顾西里尔字母用户。中文环境不需要关心,也不需要在配置里 include 它们。

配置文件小结

文件 是否常用 说明
nginx.conf ★★★ 核心配置,唯一必改文件
nginx.conf.default ★★ 原始备份,改崩时用于恢复
mime.types ★★ MIME 映射,被 include 引入
fastcgi.conf / fastcgi_params --- PHP 场景,Java 项目不用
uwsgi_params / scgi_params --- Python/SCGI 场景,本项目不用
koi-utf / koi-win / win-utf --- 俄文编码转换,中文环境不用

三、html 目录:静态资源根目录

默认提供两个页面:

bash 复制代码
ls html
# 50x.html  index.html

index.html ------ 默认首页

nginx.conf 默认配置中有:

nginx 复制代码
location / {
    root   html;
    index  index.html index.htm;
}

root html; 是相对路径 ,相对于 Nginx 安装目录 /usr/local/nginx,即实际路径 /usr/local/nginx/html。

访问 http://192.168.138.100/ 时:

  • location / 匹配到请求
  • index index.html index.htm; 指定默认找 index.html
  • 返回 /usr/local/nginx/html/index.html

页面内容是经典的 Welcome to nginx!,其中有 Thank you for using nginx. 字样------看到这句话就说明 Nginx 启动成功且能被访问到,这是最快的验证手段。

部署自己的静态资源时,把文件放到这个目录下即可,这就是后面「部署静态资源」一节的做法。

50x.html ------ 服务端错误页

配置中通常有:

nginx 复制代码
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   html;
}

当 Nginx 自身产生 5xx 错误(典型场景:反向代理的后端全部不可用时返回 502 Bad Gateway),会把 /50x.html 的内容返回给用户,而不是暴露默认的丑陋错误页。

注意区分:

  • 50x.html 只在 Nginx 自身出错时显示(后端挂了、网关错误)
  • 后端 Spring Boot 抛异常返回的 500 不会走这里 ------Nginx 只是把后端的响应原样透传

四、logs 目录:日志与进程 ID

启动前与启动后

安装完成未启动时,logs 是空目录。启动后:

bash 复制代码
/usr/local/nginx/sbin/nginx
ls logs
# access.log  error.log  nginx.pid

access.log ------ 访问日志

记录每一次请求 。默认格式(main 格式)的一条记录:

txt 复制代码
192.168.138.1 - - [11/Sep/2026:09:30:15 +0800] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0"

字段含义:

字段 示例 说明
客户端 IP 192.168.138.1 发起请求的来源 IP
远程用户 - 未开启认证时为空
时间 [11/Sep/2026:09:30:15 +0800] 请求时间
请求行 "GET / HTTP/1.1" 方法、URI、协议
状态码 200 响应状态
响应大小 612 响应体字节数
Referer "-" 来源页
User-Agent Mozilla/5.0 ... 客户端标识

实时跟踪:

bash 复制代码
tail -f /usr/local/nginx/logs/access.log

error.log ------ 错误日志

记录 Nginx 的错误与警告。排查问题的第一站。

典型场景:配置文件写错时执行 nginx -t,错误信息会同时输出到控制台并写入这里:

txt 复制代码
2026/09/11 09:28:03 [emerg] 12345#0: unknown directive "abc" in /usr/local/nginx/conf/nginx.conf:3

这条日志清晰地指出:未知指令 abc,在 nginx.conf 的第 3 行。

常见的错误日志内容还有:

  • connect() failed (111: Connection refused) while connecting to upstream ------ 反向代理的后端没起来
  • bind() to 0.0.0.0:80 failed (98: Address already in use) ------ 端口被占
  • No such file or directory ------ 静态资源路径配错

nginx.pid ------ 进程 ID 文件

这是理解 Nginx 信号机制的关键文件。

bash 复制代码
cat logs/nginx.pid
# 116947

用 ps 验证:

bash 复制代码
ps -ef | grep nginx
txt 复制代码
root     116947      1  0 09:30 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody   116948 116947  0 09:30 ?        00:00:00 nginx: worker process

nginx.pid 里记录的 116947 正是 master 进程的 PID。

这个文件的作用 :nginx -s reload、nginx -s stop 这些命令需要知道该给哪个进程发信号。实现方式就是读取 nginx.pid 拿到 master 的 PID,然后 kill 相应信号:

命令 实际发送的信号
nginx -s stop TERM(立即终止)
nginx -s quit QUIT(优雅退出,处理完当前请求)
nginx -s reload HUP(重新加载配置)
nginx -s reopen USR1(重新打开日志文件)

nginx.pid 的生命周期 :服务启动时创建,服务停止时自动删除。所以判断 Nginx 是否在运行,看这个文件在不在即可 (比 ps 更轻量):

bash 复制代码
test -f /usr/local/nginx/logs/nginx.pid && echo "运行中" || echo "已停止"

也可以手动发信号,效果与 -s 等价:

bash 复制代码
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)   # 等价于 nginx -s reload
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid)  # 等价于 nginx -s quit

日志切割

生产环境 access.log 会无限增长,必须定期切割。Nginx 提供 USR1 信号实现"重新打开日志文件":

bash 复制代码
#!/bin/bash
# /usr/local/nginx/sbin/cut_logs.sh
LOG_PATH=/usr/local/nginx/logs
YESTERDAY=$(date -d yesterday +%Y%m%d)

mv ${LOG_PATH}/access.log ${LOG_PATH}/access-${YESTERDAY}.log
mv ${LOG_PATH}/error.log  ${LOG_PATH}/error-${YESTERDAY}.log

# 通知 master 进程重新打开日志文件
kill -USR1 $(cat ${LOG_PATH}/nginx.pid)

# 删除 30 天前的日志
find ${LOG_PATH} -name "*-*.log" -mtime +30 -delete

配合 crontab 每天零点执行:

bash 复制代码
0 0 * * * /usr/local/nginx/sbin/cut_logs.sh

为什么必须发 USR1 :mv 只是改了文件名,Nginx 进程仍持有原文件的 inode 句柄,还会继续往那个已被改名的文件里写。发 USR1 让它重新 open 一次,才会写回新的 access.log。

五、sbin 目录:二进制可执行文件

bash 复制代码
ls -l sbin
# -rwxr-xr-x. 1 root root 3857424 nginx

整个 Nginx 只有一个可执行文件 ,约 3.8MB。所有命令都通过它加不同参数完成:

bash 复制代码
./nginx              # 启动
./nginx -v           # 查看版本
./nginx -V           # 查看版本 + 编译参数
./nginx -t           # 检查配置文件语法
./nginx -s stop      # 停止
./nginx -s reload    # 重新加载配置

注意相对路径 ./nginx 要求当前目录必须在 sbin 下。在其他目录下要用绝对路径:

bash 复制代码
/usr/local/nginx/sbin/nginx -s reload

反复写这么长的路径很麻烦,下一篇会讲如何配置环境变量简化。

六、运行时新增的临时目录

启动后回到安装目录再看:

bash 复制代码
ls /usr/local/nginx
# client_body_temp  conf  fastcgi_temp  html  logs  proxy_temp  scgi_temp  sbin  uwsgi_temp

多出一批 *_temp 目录。它们是 Nginx 的磁盘缓冲区:

目录 用途
client_body_temp 请求体超过 client_body_buffer_size 时暂存到磁盘
proxy_temp 反向代理时,后端响应超过 proxy_buffer_size 时暂存
fastcgi_temp FastCGI 响应缓冲区
uwsgi_temp uWSGI 响应缓冲区
scgi_temp SCGI 响应缓冲区

这些目录通常不需要手工操作 。但有一个生产要点:如果上传大文件或代理大响应,这些目录所在分区必须有足够空间,否则会报 No space left on device。

相关配置项(在 nginx.conf 中):

nginx 复制代码
http {
    client_max_body_size        100m;   # 允许的最大请求体
    client_body_buffer_size     128k;   # 请求体内存缓冲区,超出写临时文件
    proxy_buffer_size           4k;     # 代理响应头缓冲区
    proxy_buffers               4 32k;  # 代理响应体缓冲区数量与大小
}

client_max_body_size 默认是 1m 。外卖平台有图片上传功能,如果前端直接把图片传给 Nginx 再代理到后端,超过 1m 会被直接拒绝并报 413 Request Entity Too Large------这是一个高频踩坑点。

七、目录结构速查表

目录 / 文件 说明 备注
conf 配置文件存放目录
conf/nginx.conf Nginx 核心配置文件 后续所有配置都改这里
conf/nginx.conf.default 原始配置备份 改崩时用于恢复
conf/mime.types MIME 类型映射 被 nginx.conf 的 include 引入
html 静态资源存放目录 部署前端页面就放这里
html/index.html 默认首页 看到 Thank you for using nginx. 即启动成功
html/50x.html 5xx 错误页 后端不可用时展示
logs 日志目录
logs/access.log 访问日志 每次请求一条
logs/error.log 错误日志 排查问题第一站
logs/nginx.pid master 进程 ID 仅运行时存在,停止时自动删除
sbin/nginx 二进制可执行文件 启动、停止、重载都靠它
client_body_temp 等 磁盘缓冲区 运行时生成,一般不需干预

API 速览

命令 作用
yum install tree 安装 tree 命令
tree 以树形结构展示当前目录
tree -L 2 只展示两层
tree -d 只显示目录不显示文件
ls -l sbin 查看 sbin 目录内容
cat logs/nginx.pid 查看 master 进程 ID
`ps -ef grep nginx`
tail -f logs/access.log 实时跟踪访问日志
tail -f logs/error.log 实时跟踪错误日志
cp conf/nginx.conf.default conf/nginx.conf 用默认配置覆盖恢复
kill -HUP $(cat logs/nginx.pid) 发 HUP 信号重新加载配置
kill -QUIT $(cat logs/nginx.pid) 发 QUIT 信号优雅停止
kill -USR1 $(cat logs/nginx.pid) 发 USR1 信号重新打开日志文件

官方文档

总结

四个目录,只需盯住两个文件 :conf/nginx.conf(所有配置改这里)和 sbin/nginx(所有命令用它)。其余文件要么是被 include 的辅助配置,要么是历史遗留的无关协议支持。

conf 目录里 80% 的文件在本项目中用不到 。fastcgi_*、uwsgi_params、scgi_params、koi-* 都是 PHP/Python/俄文场景的产物,Java 技术栈直接忽略即可。但 mime.types 必须保留------它决定响应头 Content-Type,丢了会导致 CSS/JS 加载失败。

logs/nginx.pid 是理解 Nginx 信号机制的钥匙 。它记录 master 进程的 PID,nginx -s reload 本质是读取这个文件然后发 HUP 信号。文件随服务启停自动创建/删除,因此"文件是否存在"就是最简单的存活判断。

html/index.html 是最快的验证手段 。浏览器看到 Thank you for using nginx. 就说明服务正常、端口可达、防火墙已放行。访问不到时先怀疑防火墙,再看服务是否真的起来了。

运行后出现的 *_temp 目录不用管,但要留意 client_max_body_size 默认只有 1m 。涉及文件上传的场景必须显式调大,否则会得到 413。

下一篇讲 Nginx 的常用命令:查看版本、检查配置、启动停止、重新加载,以及配置环境变量让命令可以在任意目录下执行。

相关推荐
逃逸线LOF2 小时前
工具类文件头文件
java
蜗牛互联网2 小时前
Gemini 4 Argon的1M输出窗口与长程Agent工程边界
java·人工智能·后端
elseif1232 小时前
【2026 CSP-J】【逐题精讲】超详细(15道选择,3道阅读,2道完善)
java·开发语言·c++·算法·csp
XS0301062 小时前
Nginx 学习指南
运维·nginx
智鸟科技GemeOpen开发者智能设备2 小时前
MQTT智能插座GSPM1B2 · 开发者实战指南
java·开发语言·python·物联网
Thinker QAQ2 小时前
并发编程(七):volatile——从语言规则到 CPU
java·python·go·并发编程·volatile·memory model
蜗牛互联网3 小时前
从GitHub动态工作流理解确定性编排与Agent判断边界
java·人工智能·后端·github
开开心心就好3 小时前
办公软件卸载不干净?专用工具一键清残留
java·前端·人工智能·智能手机·kafka·excel·memcache
大侠归来3 小时前
C 与 Go 语言对比:从设计哲学到工程实践
java·c语言·golang