news 2026/10/13 4:12:15

用Python分析Spotify听歌数据:从导出JSON到可视化完整教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python分析Spotify听歌数据:从导出JSON到可视化完整教程

每年的听歌报告,Spotify 只给你看一张汇总页,但你有没有想过把原始数据抓下来自己算一遍?我试过之后最深的感受是:平台给的有限,自己用 Python 做出来的能多出不少东西,比如具体到每个小时的听歌习惯、播放时长和次数的真实占比、按音频特征聚类后的歌单逻辑。这篇文章就围绕如何分析 Spotify 听歌数据,完整讲清楚数据从哪来、怎么清洗、怎么画图、怎么用 API 补足细节,全程用中文讲解,代码可以直接抄。

我不打算把所有东西一次性铺开,而是按我自己做这个项目时的顺序来写:先明确要分析的问题,再拿数据、清洗数据,然后画图、调 API,最后聊聊踩过的坑。这篇文章适合刚学 pandas 想找真实数据练手的 Python 新手,也适合重度音乐用户想深入了解自己听歌习惯的人。核心分析逻辑不复杂,就是“数据获取—清洗—分组统计—可视化—特征补强”这条线。

1. 先把思路理清楚:数据藏在哪、怎么取、要分析什么

1.1 两种拿数据的姿势,各有各的局限

Spotify 听歌数据的获取主要有两条路,准确理解它们的区别,后面才不会白折腾。第一条是官方数据导出,登录账号后在隐私设置里申请“扩展流媒体历史”,官方会把你的播放记录打包成 JSON 文件发给你,这里有完整的流媒体历史,不只是最近几十首,而是从你开始使用起的所有记录。缺点是申请后会等几天,而且不能频繁重复申请。

第二条是 Web API 方式,用 Python 的 spotipy 库走 OAuth 授权,实时拉取最近播放记录、收藏歌曲、播放列表和音频特征。优点是立刻能拿、字段丰富,缺陷是拿不到完整的历史播放记录,最近播放接口通常只能拿到最近 50 首左右,根本没法做年度大盘分析。

我在实际项目中是两条腿走路:先用官方导出数据做整体统计,再通过 API 给重点歌曲补充音频特征。这样既有完整历史,又有更深的分析维度。如果只靠 API,你会发现辛苦写好的年度歌单统计缺了一大段数据;如果只用导出数据,你又拿不到类似 danceability、energy 这种反应歌曲“情绪”的细节字段。

数据来源获取方式覆盖范围主要字段时效性
官方导出隐私设置申请,等几天完整历史播放时间、歌手、歌曲、播放毫秒数离线,定期导出
Web APIOAuth 授权实时拉取近 50 首播放、收藏、歌单歌曲信息、音频特征、播放上下文实时,受频率限制

这里还要提示一下:导出文件一般会有多个 JSON 文件,常见命名是 StreamingHistory0.json、StreamingHistory1.json 这样的序号文件。不要只拿一个文件就开跑,否则你统计到的可能只是某一年或某一段时间的片段。

1.2 先想好要回答哪些问题

数据分析最忌讳一上来就写代码,我见过很多人刚拿到数据就开始画图,结果画了一大堆,一张有用的都没有。正确做法是先列问题清单,把“想知道什么”变成“用什么指标回答”。

我自己做这个项目时列的问题大概是这样的:我的总播放时长有多少、相当于听了多少天;播放次数最多的歌手是不是真的喜欢;哪些歌被我重复听了最多遍;周末和平时相比,听歌时长有没有明显变化;每天哪个时段是我最“沉浸”的时候;我的年度歌单整体是偏“燃”还是偏平静。这些问题每个都能对应一个统计指标,统计指标又能对应一段代码。

把问题定义清楚还有个好处,就是避免画图时没有边界。一次做一个图表,每张图都有明确的问题指向,做出来的东西就能直接用。这个习惯可以说适用于所有数据类个人项目,不只是 Spotify 数据。

2. 环境准备与原始数据获取:从申请导出到 API 凭证

2.1 环境装哪些东西

正式开始前先把环境准备好,我用的是 Python 3.10 以上的版本,配合 Jupyter 或 VS Code 都很顺手。核心的库只有五个:pandas 负责数据清洗和聚合,matplotlib 负责画图,spotipy 负责调 API,wordcloud 生成歌手词云,python-dotenv 用来保存密钥(如果不想用可以不装)。安装命令如下:

pip install pandas matplotlib spotipy wordcloud python-dotenv

为什么选 pandas 而不是直接用 Excel?Excel 打开几十万行的 JSON 会很痛苦,而且时间处理、分组聚合这类操作在 pandas 里就是一两行代码的事。这个项目本质上是个人数据分析项目,用 pandas 是最省精力也最不容易翻车的组合。

2.2 从官方后台导出历史数据

申请导出的步骤不复杂,但很多人找不到入口。登录账号后进入隐私设置,找到数据下载相关的选项,申请一份“扩展流媒体历史”,里面会包含播放历史和部分操作记录。提交后不会立刻下载,官方会往邮箱发一封邮件告诉你准备好了,短则一两天、长则一周左右,按照邮件提示下载压缩包就可以了。

需要注意,这种申请通常有冷却期,不能为了测试反复提交。我在第一次做的时候申请完第二天就再点了一次,结果被后台拒绝了,提示要间隔一段时间。建议你第一次申请后就踏实等邮件,别重复操作。

下载得到的压缩包里除了多处播放历史 JSON 文件,有时还有播放列表等目录。如果你只关心播放历史,就把所有 StreamingHistory*.json 文件挑出来,先把它们放到一个独立文件夹,例如 audio_data 目录,方便后面用 glob 批量匹配。

文件内容长这样,每一条记录包含几个固定字段:

{ "endTime": "2024-11-15 22:13:45", "artistName": "Some Artist", "trackName": "A Certain Song", "msPlayed": 180123 }

这里的 endTime 表示这首歌播放结束后被记录的时间点,msPlayed 是这条记录的播放毫秒数。你没有听错的含义,一条记录的时长可能因为跳过、暂停、切歌等原因小于歌曲实际长度。

2.3 申请 API 凭证,为后面的特征分析做准备

官方导出数据里没有歌曲 ID,也没有 danceability、valence 这些音频特征,所以后面在进阶分析部分必须用 API 补一节。申请 API 凭证的方式是进入 Spotify 官方开发者后台,创建一个应用,拿到 Client ID 和 Client Secret,并且设置一个 Redirect URI,我一般会写成:

http://localhost:8888/callback

写的时候一定要把回调地址保存好,因为 OAuth 流程需要它。访问 API 时还需要明确 scope,也就是你申请的数据访问范围。我常用的 scope 是 "user-library-read user-read-recently-played user-top-read",代表可以读取收藏歌曲、最近播放和你的热门歌曲。不同 scope 对应的权限不同,后面如果有 403 或者权限不足报错,先检查 scope 写全了没有。

很多人在这一步被卡住,原因不是代码有问题,而是回调地址和 scope 不匹配。代码里写的 redirect_uri 必须和开发者后台填的一模一样,包括端口号,少一个字符都不行。这个坑我后面专门整理了一个排查清单。

3. 清洗和统计:把 JSON 变成能回答问题的 DataFrame

3.1 加载和合并多个 JSON 文件

导出数据是多文件结构,所以我第一步永远是先用 glob 把所有 StreamingHistory 文件找出来,再逐个读取合并。这样处理到最后得到一个完整的 DataFrame,后续所有统计都基于它执行。

import glob import pandas as pd files = glob.glob(r"audio_data/StreamingHistory*.json") print("文件数量:", len(files)) df_list = [] for f in files: tmp = pd.read_json(f) df_list.append(tmp) df = pd.concat(df_list, ignore_index=True) print(df.shape)

如果文件特别多或者体积很大,建议在 read_json 时只读需要的列,或者用 chunksize 分批读取。个人项目的数据量一般不至于大到那个程度,但养成这个习惯没有坏处。

合并完可以先看一眼字段覆盖情况。有时某些条目可能缺失 artistName 或 trackName,比如某些现场录音或本地文件,建议统一填充为"未知",避免后续 groupby 时出现大量空值堆积。

3.2 时间处理:它是 UTC,不是你的本地时间

我第一次做这个项目时踩过一个很经典的时区坑。导出的 endTime 字段是 UTC 时间,不是本地时间。如果直接拿它统计 “我每天几点听歌最多”,结果会整体偏移,尤其在中国区会偏移 8 小时左右,原本晚上 10 点的沉浸听歌时间会被记成下午 2 点。

正确做法是先把 endTime 转成带时区的 datetime,再转换到本地时区,最后提取小时、星期几和月份字段。

df["endTime"] = pd.to_datetime(df["endTime"], utc=True) df["endTime_local"] = df["endTime"].dt.tz_convert("Asia/Shanghai") df["hour"] = df["endTime_local"].dt.hour df["weekday"] = df["endTime_local"].dt.dayofweek # 0=周一 df["month"] = df["endTime_local"].dt.month df["year"] = df["endTime_local"].dt.year df["date"] = df["endTime_local"].dt.date

这里为什么强调 UTC 转换?因为如果时间字符串恰好不带时区标记,直接 tz_convert 会报错,先 utc=True 再转换是最稳妥的顺序。如果你身处其他时区,把 Asia/Shanghai 换成你所在城市的 IANA 时区名即可。

3.3 播放时长字段的坑

msPlayed 是以毫秒为单位的播放时长,第一步先转成分钟。但是真正会让分析结果变形的不是单位,而是怎么处理“短播放”数据。

什么算短播放?你搜到一首歌顺手点了进去,听了 10 秒就切走了,这种情况算你“喜欢”这首歌吗?很多人统计高频歌曲时会发现一些奇奇怪怪的歌排进前排,原因就是短播放没有过滤。但过滤阈值又不能拍脑袋定死,比如一首实验性后摇只有 30 秒,你却用 30 秒标准把它过滤掉了,逻辑上就反了。

我常用的做法是保留两套数据:一套全量原始数据,用来统计“曾播放过的作品”;另一套过滤掉 msPlayed 小于 30000 的记录,也就是播放不足 30 秒的算作“未完成或跳过”,专门用于统计有效播放。如果歌曲本身时长很短,30 秒阈值确实会误伤,我一般通过比较 trackDuration 字段来辅助判断,没有该字段就先接受 30 秒阈值带来的误差。

还有一点容易被忽略:排名应该基于播放时长总和,而不是播放次数。一首 8 分钟的长作品播放 3 次,和一首 2 分钟的短作品播放 12 次,播放次数相同吗?显然不对。用 msPlayed 总和能更真实反映你在一首歌或一位歌手身上投入的注意力时长。所以我的做法是先把播放毫秒数聚合为小时数,再用这个小时数排序。

3.4 第一版统计指标

数据清洗完就能做第一版统计了,这个阶段不用追求好看,先追求“能回答基础问题”。我先算总播放时长、总播放条数、艺术家数量、单首歌最大重复次数,然后看每天平均听歌时长。

total_hours = df["msPlayed"].sum() / 3600000 total_plays = len(df) total_days = df["date"].nunique() daily_avg_hours = total_hours / total_days print(f"总播放时长: {total_hours:.1f} 小时") print(f"总播放条数: {total_plays}") print(f"活跃天数: {total_days}") print(f"日均播放: {daily_avg_hours:.2f} 小时")

然后是歌手排行和歌曲排行。这里我会把“有效播放”和“全量数据”对比着看,有时候你会惊讶地发现,某位你无感的歌手其实长期占领你的碎片时间。

artist_hours = ( df.groupby("artistName")["msPlayed"] .sum() .sort_values(ascending=False) .head(20) / 3600000 ) song_hours = ( df.groupby(["artistName", "trackName"])["msPlayed"] .sum() .sort_values(ascending=False) .head(20) / 3600000 )

看到这里,第一部分分析已经基本成型,接下来就是把这些数字变成能看懂的图表。

4. 画图模块:制作自己的年度听歌报告

4.1 TOP 歌手和 TOP 歌曲横向条形图

画图之前先解决中文字体问题,这是 matplotlib 最常见的坑。默认字体不支持中文,直接画图会出现一个个方框。我每次做这类个人项目都会先设置字体:

import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "Microsoft YaHei", "SimHei"] plt.rcParams["axes.unicode_minus"] = False

TOP 歌手用横向条形图最直观,因为歌手名通常比较长,横向展示不会被截断。在柱子上直接标注小时数,一眼就能看出谁是你的听歌时长霸主。

top_artists = artist_hours.head(10) fig, ax = plt.subplots(figsize=(10, 6)) top_artists.sort_values().plot.barh(ax=ax, color="#1DB954") ax.set_title("我的 TOP10 歌手(按听歌时长,小时)") ax.set_xlabel("听歌小时数") for i, v in enumerate(top_artists.sort_values().values): ax.text(v, i, f" {v:.0f}h", va="center") plt.tight_layout() plt.savefig("top_artists.png", dpi=150) plt.show()

条形图做完记得保存 PNG,后面能拼进 PDF 或者直接分享。

4.2 按小时、星期、月份的热度趋势

这个部分是我个人最爱的,因为平台报告里不会给你这么细的视角。先看“星期几 + 一天中的小时”的播放热度矩阵,横轴是 0 点到 23 点,纵轴是周一到周日,格子颜色越深代表那段时间播放量越大。这种热力图能直接看出你的“通勤听歌高峰”和“深夜循环时间”。

import numpy as np pivot = df.pivot_table( index="weekday", columns="hour", values="msPlayed", aggfunc="sum", ) pivot = pivot.reindex(index=range(7), columns=range(24)).fillna(0) / 3600000 fig, ax = plt.subplots(figsize=(12, 5)) heatmap = ax.imshow(pivot, aspect="auto", cmap="YlGnBu") ax.set_xticks(range(24)) ax.set_yticks(range(7)) ax.set_yticklabels(["周一", "周二", "周三", "周四", "周五", "周六", "周日"]) ax.set_xlabel("小时") ax.set_ylabel("星期") plt.colorbar(heatmap, ax=ax, label="播放小时数") plt.title("一周内的听歌热度分布") plt.tight_layout() plt.savefig("heatmap_weekly.png", dpi=150) plt.show()

如果你发现自己的热力图在工作日的早上 8 点到 9 点有一道非常亮的横向亮带,那基本可以断定那是在通勤路上听的。这种洞察比单纯看总时长有意思得多。

再做一个按月播放时长的折线图,能看出口味波动,比如某个月突然出现一个高峰,大概率是因为某张新专辑或者某位歌手巡回演出的时间点。折线图用普通 line 图即可,不复杂。

4.3 歌手词云,做一个直观的名片

词云是很多人喜欢的可视化方式,字越大代表播放越频繁。生成词云前要把歌手名按播放次数重复成字符串,再用 wordcloud 绘制。这里有两个容易踩的坑:一是文本量不能无穷大,建议只取 TOP100 歌手;二是一定要指定中文字体路径,否则所有歌手名都会变成方框。

from wordcloud import WordCloud artist_counts = df["artistName"].value_counts().head(100) text = " ".join(artist_counts.index) wc = WordCloud( width=1600, height=800, background_color="white", font_path="/System/Library/Fonts/PingFang.ttc", # 改成你的中文字体路径 colormap="viridis", ).generate(text) fig, ax = plt.subplots(figsize=(12, 6)) ax.imshow(wc, interpolation="bilinear") ax.axis("off") plt.title("我的歌手词云") plt.tight_layout() plt.savefig("wordcloud_artists.png", dpi=150) plt.show()

字体路径每个操作系统不一样,Windows 常见是 C:/Windows/Fonts/msyh.ttc,macOS 常见是 /System/Library/Fonts/PingFang.ttc,Linux 则要安装中文字体后找到对应位置。找不到就先用英文确认逻辑,再把字体路径补上。

5. 进阶玩法:音频特征告诉你为什么一直循环那首歌

5.1 批量拉取音频特征,补齐无法从导出数据获得的部分

官方导出的数据里没有歌曲 ID,也没有音频特征,所以需要让 API 根据“歌手 + 歌曲名”去搜索歌曲并拿特征值。先试一首,确认匹配率能接受,再批量补。

import spotipy import time from spotipy.oauth2 import SpotifyOAuth scope = "user-library-read user-read-recently-played user-top-read" sp = spotipy.Spotify(auth_manager=SpotifyOAuth( client_id="你的ClientID", client_secret="你的ClientSecret", redirect_uri="http://localhost:8888/callback", scope=scope, )) def search_track(artist, title): query = f"artist:{artist} track:{title}" result = sp.search(query, type="track", limit=1) tracks = result["tracks"]["items"] if not tracks: return None return tracks[0]["id"] top_songs = ( df.groupby(["artistName", "trackName"])["msPlayed"] .sum() .sort_values(ascending=False) .head(50) ) track_ids = [] for (artist, title), _ in top_songs.items(): track_id = search_track(artist, title) track_ids.append(track_id) time.sleep(0.2) features = [] for i in range(0, len(track_ids), 100): batch = track_ids[i:i+100] features.extend(sp.audio_features(tracks=batch)) time.sleep(0.3)

搜索接口是有频率限制的,批量补数据时一定要在循环里加 sleep,否则很容易触发 429 错误。上面代码里放慢了请求速度,虽然会多花几十秒,但比起被限速后反复重试要划算得多。

如果搜索返回空,那大概率是本地音乐、现场录音或未上架版本。我的做法是保留空位并按“未知特征”处理,不阻塞整个流程。

5.2 雷达图和散点图:看懂你的听歌偏好

拿到音频特征后,比较有价值的是以下六个字段:

特征含义范围
danceability舞蹈适合度0 到 1
energy能量强度0 到 1
valence情感积极度0 到 1,越高越“快乐”
acousticness原声程度0 到 1
instrumentalness器乐占比0 到 1
tempo速度BPM

先用雷达图画出平均水平,和你的 TOP50 歌曲特征做一个对比。你会发现一个很有意思的规律:很多人 TOP50 歌曲的平均 energy 反而低于整体平均,因为高频循环的歌往往是那些适合做背景音的歌曲,而不是最炸裂的歌曲。

散点图选 energy 和 valence 两个维度,横轴 valence 表示情绪积极度,纵轴 energy 表示激烈程度,这样你的歌单会被自动分成几个区域。右上角是“燃曲区”,左上角是“狂躁区”或者“暗黑区”,右下角是“温柔低情绪”区,左下角是“安静丧曲区”。我在实际画完之后发现,我深夜听的歌大量集中在左下角,而通勤时候听的集中在右上角,完全能对应到不同的使用场景。

5.3 歌曲级归类,让报告更有故事性

有了特征值,就可以做简单的歌曲归类。不需要上复杂模型,写几个阈值规则就够了:

def classify(row): if row["energy"] > 0.7 and row["valence"] > 0.6: return "提神/燃曲" if row["energy"] < 0.4 and row["valence"] < 0.35: return "深夜/丧曲" if row["acousticness"] > 0.5: return "安静/原声" return "日常/普通" feat_df["category"] = feat_df.apply(classify, axis=1)

对每个分类做汇总,你能知道自己的年度播放时长里有多少属于“提神/燃曲”、多少属于“深夜/丧曲”。如果觉得阈值规则不够生动,也可以顺手用 sklearn 的 KMeans 聚类,把歌曲自动分为几类,再给几个典型代表起个名字。这是可选功能,基础版规则足够完成一篇完整的个人报告。

6. 实操中的坑:排查清单与我的习惯

6.1 常见问题速查表

做这个项目过程中,我把最常遇到的坑整理成了表格,对号入座排查更快:

现象可能原因解决办法
OAuth 认证失败Redirect URI 和后台不一致复制后台完整地址到代码
提示权限不足scope 没有包含对应权限把 scope 扩为 user-library-read 等
时间统计整体偏移没有把 UTC 转本地时区先 utc=True 再 tz_convert
图表中文乱码matplotlib 中文字体未设置设置 font.sans-serif 和中文字体路径
词云全是方框wordcloud 未指定中文字体用 font_path 指定本机中文字体
API 报 429请求频率过高在循环里加 time.sleep,分批请求
统计结果比记忆少很多只读取了部分 JSON 文件用 glob 匹配所有 StreamingHistory 文件
高频歌曲榜单有奇怪歌曲没有过滤短播放增加“有效播放”维度,过滤小于 30 秒的记录

这里单独说一句 429 报错。Spotify 对 API 请求有严格的频率限制,批量拉取音频特征时比较容易碰到。除了 sleep,还可以把请求拆成小批次,单次最多 100 个 track ID,这是接口限制,不要贪多。

6.2 隐私和数据管理习惯

这个项目会涉及比较私密的个人听歌数据,我自己在做的过程中养成了一些习惯。导出 JSON 文件不会上传到任何公开仓库;演示代码里也不放真实的 Client ID 和 Client Secret,而是存到本地环境变量文件里,用一个变量名引用。如果你想复现,请一定把敏感信息全部脱敏。

还有一个体验上的心得:不要把图表文件随便用数字命名,我习惯把关键图表保存成 top_artists.png、heatmap_weekly.png、feature_profile.png 这种名字,最后放进一个 report 目录里。连续做几个月之后,你会得到一组时间序列图片,可以直观看到自己的口味漂移。

6.3 如何把这个项目继续玩下去

这个项目的扩展空间其实比想象中大。你可以按月生成月度小结,自动输出“本月新发现歌手”“本月循环最多次的歌曲”“本月的深夜歌曲”等内容;也可以把听歌数据和自己的日历对比,看出出差、加班、休假对听歌节奏的影响;更进阶的玩法是把音频特征和每天的心情评分放在一起,做一个小型的数据回归。

我个人在实际操作中最喜欢的一个扩展是把热力图做成 GIF,按月份一帧一帧播放,能看到一年里的听歌习惯如何迁徙。生成 GIF 只需要把每个月热力图保存成帧,电影界面的工具并不多,pillow 就能搞定。

最后分享一个小技巧:请一定保留清洗后的 DataFrame,不要只存图表。后面再想做一些新指标,比如统计某个歌手在不同年份的“占据率”变化,直接读清洗后的 DataFrame 就能马上算出来,而不用重新跑一遍下载、解析、合并的流程。数据管线的每个环节都应该是可重跑的,这是这类个人数据分析项目最有价值的地方。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 4:11:38

ELF地址反查函数名:从崩溃日志到addr2line的完整实战指南

程序崩了&#xff0c;日志里只有一行&#xff1a;demo_app[0x55f0a1f11a14]。没有完整调用栈&#xff0c;没有函数名&#xff0c;甚至连模块里的符号都看不出来。这种时候&#xff0c;我脑子里冒出来的第一个动作&#xff0c;从来不是去翻代码&#xff0c;而是把这串运行地址喂…

作者头像 李华
网站建设 2026/10/13 4:11:06

OAuth 2.1 + FIDO2 无密码认证实战:原理、落地与安全升级指南

先说一个让我印象特别深的场景&#xff1a;某次线上故障复盘&#xff0c;A同学发现自家应用的用户数据库里&#xff0c;有三成账号的口令哈希已经能被彩虹表直接拆穿。更麻烦的是&#xff0c;攻击者根本不碰数据库——他只需要仿冒一个登录页面&#xff0c;用户把账号和密码填进…

作者头像 李华
网站建设 2026/10/13 4:10:03

VLAN+MSTP+链路聚合综合实验:二层冗余与负载分担配置详解

最近一直在练网络竞赛里很常见的二层综合实验&#xff0c;题目把VLAN、MSTP、链路聚合三个知识点放在同一个拓扑下。说句实话&#xff0c;单个知识点单独学&#xff0c;感觉都不难&#xff0c;可真把它们揉在一起配置的时候&#xff0c;交互关系才是最容易翻车的地方。这篇文章…

作者头像 李华
网站建设 2026/10/13 4:09:56

SpringBoot+Vue新闻发布信息收集系统全栈开发实战

每年这时候都会有一大批同学被管理系统类项目折腾得够呛。前几天还有人问我“新闻发布信息收集系统”到底该从哪下手&#xff0c;我看了下市面上的资料&#xff0c;要么讲得太空不讲落地&#xff0c;要么代码片段东一块西一块根本拼不起来。这个选题看起来普通&#xff0c;但真…

作者头像 李华
网站建设 2026/10/13 4:09:56

Linux中文输入法配置全攻略:框架选型、环境变量与常见排错

我印象里&#xff0c;凡是刚跳进Linux的人&#xff0c;十有八九会在“中文输入法”这一关上卡住一阵子。明明装好了包&#xff0c;CtrlSpace按到屏幕发亮也无动于衷&#xff0c;注销重登、重启机器都试过&#xff0c;最后还是没能打出第一个汉字。后来我才明白&#xff0c;Linu…

作者头像 李华
网站建设 2026/10/13 4:09:13

BIO/NIO/AIO核心差异与手写NIO多路复用服务器实战

这个系列的上一篇&#xff0c;我把BIO的线程模型和它为什么撑不住高并发讲透了。这篇接着往下聊&#xff1a;NIO到底改了什么&#xff0c;AIO又是怎么回事&#xff0c;以及一个真实的、可以用在项目里的NIO多路复用服务器应该怎么手写。如果你面试被问到BIO/NIO/AIO的区别&…

作者头像 李华