棋盘题训练全解析:从二维数组建模到回溯与AI博弈剪枝
如果你的程序设计训练清单里有“棋盘”这两个字我先给你交个底这题目可以做得无比简单也可以做到让你怀疑人生。简单版是打印一个二维数组复杂版是带 AI 对弈、悔棋、复盘、甚至棋谱导出的完整小游戏。多数人做的是中间那条路——而棋盘题真正想训练的不是“让棋子动起来”而是让你同时面对数据结构建模、规则抽象、状态回溯、搜索剪枝这一整套问题。这题目这么经典是因为它有天然的“分层”属性同一个“棋盘”既能用来练基础语法和二维数组也能拿来练回溯算法还能一路升级到博弈搜索、启发式评估、甚至位棋盘这种偏工程的优化手法。换句话说哪怕你手里只有一个“五子棋棋盘”的题目你也能在它身上做出好几个版本的项目。这篇文章我按真实训练项目的方式来讲先拆需求再建模型再写算法最后把调试心得和扩展方向一并给你。里面用到的代码以 Python 为主但思路移植到 C、Java 或者 Go 都没有障碍关键是理解每一步“为什么这么做”而不是死记某个代码片段。1. 棋盘类训练题到底在考什么1.1 每个“棋盘”题目都共享的骨架棋盘题五花八门从八皇后到五子棋从迷宫到骑士巡游但剥开外衣它们的骨架几乎一模一样一块有边界的二维区域一组状态空、己方棋子、对方棋子、障碍一组状态转移规则落子、走子、吃子以及一个或多个目标判定胜负、最优解、全部解。理解这个骨架你就理解了出题人的意图。这个骨架意味着什么意味着你不只是在写一个数组的循环。你在设计一个微型世界棋盘是数据容器规则是业务逻辑胜负判定是输出协议。程序员处理的大部分真实项目抽象到最后往往也是这种模式——状态集合、状态迁移、终止条件。所以棋盘题才会被无数训练营和课程反复使用它不只是“算法题”更是“软件工程压缩包”。我这些年批过不少棋盘题作业一个很明显的感觉是同样拿到“棋盘”题有人三天还在纠结棋子怎么表示有人半天就能跑出第一版 AI 对企图。差距不在智商而在于是否先把题目拆对了。这个拆解的功夫就是本节要解决的事。1.2 先拆需求再写代码一个真实的拆解流程我见过太多人拿到棋盘题就撸起袖子敲代码结果写到一半发现规则没定义清楚、边界没想明白、AI 接口设计错了全部推翻重来。正确做法是先做需求拆解哪怕只用 20 分钟后面就能省下 200 分钟的改代码时间。拆需求建议按这四步走。明确交付形式是控制台交互、图形界面还是纯函数库训练题通常要求控制台交互这意味着你必须有输入解析、错误提示和清晰打印。定义核心规则棋盘多大、棋子有哪几种、谁能走什么路、怎样算赢、和棋如何判定。每一条都要能写在纸上能写成 if/else 或者查表。划分模块建议至少拆成棋盘类、规则判断、AI如果需要、输入输出四块。模块之间用数据接口连接不要互相掺和。预估复杂度如果是搜索类题目先算一下状态空间有多大。八皇后如果不剪枝92 个解要搜索多少状态五子棋如果直接穷举十步分支数会爆炸到根本跑不动。这个估算直接决定你后续要不要加剪枝和启发式。这里有一个经验把输入输出接口先定下来后续重构会轻松很多。比如棋盘就用二维数组表示对外提供get(r, c)和set(r, c, piece)不管内部怎么改上层调用不受影响。我自己做训练项目的习惯就是先写接口文档哪怕只有三四行注释也比没有强。2. 棋盘建模用代码搭出“棋盘”骨架2.1 坐标系统与二维数组最基础也最关键的约定棋盘题的第一步是选数据结构。95% 的情况一个二维数组就够了board[row][col]。行下标从 0 到 rows-1列下标从 0 到 cols-1。但越基础的地方越容易出问题尤其是方向和坐标的对应关系。以五子棋 15x15 棋盘为例方向通常用方向数组表示ROWS COLS 15 EMPTY . DIRS [ (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1) ]为什么用一个数组而不是八个 if因为你要在计算落子影响、搜索邻近点时反复用到这些方向。写清楚方向数组之后所有代码都能复用同一套逻辑还少写一堆重复代码。这里有一个需要提前约定并写进注释的点行方向是向下还是向上列方向是向左还是向右。你自己代码里看可能无所谓但一旦你写 AI、写走法生成器、或者以后做图形界面映射坐标错误会制造极难发现的逻辑 bug。我习惯统一为“行号从上往下增加列号从左往右增加”与数组下标天然一致打印棋盘时也顺眼。2.2 状态表示不要用魔法数字糊弄自己棋盘格子的状态怎么表示初学者最爱写1表示黑棋、2表示白棋、0表示空。这不是不能跑但你会在代码里不断看到if board[r][c] 1别人看你的代码就像在猜谜。过两周你自己回来看也会一脸茫然。稍微好一点的做法是定义常量EMPTY 0 BLACK 1 WHITE 2再进一步如果棋子有自己的名称、所属方、甚至符号可以用类或者命名元组。但我建议训练项目里别过度设计——二维数组加常量枚举已经是性价比最高的方案。你可以把打印符号映射放到 UI 层去处理SYMBOL {EMPTY: ., BLACK: ●, WHITE: ○}这样棋盘数据层永远不涉及显示细节后续换成图形界面也只需要改这一层。我在 4.1 节会详细展示为什么这个分离能帮你省下大把时间。2.3 边界与特殊规则大多数 bug 藏在这里棋盘类代码最常见的 crash 不是算法写错而是越界。比如中国象棋的马跳日落脚点可能跑到棋盘外围棋提子要检查相邻空点国际象棋王车易位牵扯多个格子的状态。处理边界有一个基本套路在任何访问board[nr][nc]之前先做0 nr rows and 0 nc cols判断。以中国象棋马的走法为例KNIGHT_OFFSETS [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)] def knight_moves(board, r, c): piece board[r][c] moves [] for dr, dc in KNIGHT_OFFSETS: nr, nc r dr, c dc if not (0 nr 10 and 0 nc 9): continue leg_r, leg_c r dr // 2, c dc // 2 if board[leg_r][leg_c] ! EMPTY: continue target board[nr][nc] if target EMPTY or target.isupper() ! piece.isupper(): moves.append((nr, nc)) return moves这里dr // 2和dc // 2是马腿位置的计算我用的是整数除法配合 Python 负数除法的特性正好得到半步位置。这种细节光看文档不容易想到实际调试时你可以打印每一步的leg_r, leg_c来验证。提示边界判断不要写在一个公用的get函数里就不管了。你自己还是会有直接访问 board 的地方统一越界防治很重要。建议养成一个习惯所有涉及坐标变换的函数入口先做一次坐标合法检查返回空列表或 None而不是抛异常。3. 核心算法从走法生成、回溯到博弈搜索3.1 走法生成器一切搜索的起点棋盘题一旦进入搜索第一步是生成候选状态。走法生成器就是干这个的给定一个棋盘和一个棋子返回所有合法落点或走法。走法生成器本身不难难在“合法性”的定义。比如中国象棋中马有蹩马腿象有塞象眼兵有未过河与过河的区别五子棋虽然落子没有复杂走法但评估一个点是否是有效进攻点也需要判断方向连子。所以写走法生成器时我建议把它当一个纯函数不修改任何状态只返回列表。这样测试起来极其方便。以迷宫寻路为例走法生成器长这样def neighbors(maze, r, c): result [] for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)): nr, nc r dr, c dc if 0 nr len(maze) and 0 nc len(maze[0]): if maze[nr][nc] ! #: result.append((nr, nc)) return result这个函数看起来简单但它是后续 BFS、DFS、A* 的公共底座。很多人一上来就写搜索主逻辑走法逻辑塞在里面最后代码揉成一团改一个需求就要伤筋动骨。所以我会反复强调走法生成器、规则判断、搜索主逻辑一定要分开。棋盘题给分点也常常在这些模块的清晰度上。3.2 回溯与剪枝八皇后这样“搜索暴力”的问题八皇后是棋盘题里最有代表性的回溯练习。它的核心技巧是在递归尝试放置皇后之前把搜索范围从“所有格子”压缩到“每一行必须放一个皇后”这样搜索空间就从组合问题降阶为排列问题再加上斜线冲突判断就能高效跑完。一个标准的实现长这样def solve_n_queens(n): result [] cols [False] * n diag1 [False] * (2 * n - 1) diag2 [False] * (2 * n - 1) path [] def backtrack(row): if row n: result.append(path[:]) return for col in range(n): d1 row col d2 row - col n - 1 if cols[col] or diag1[d1] or diag2[d2]: continue cols[col] diag1[d1] diag2[d2] True path.append(col) backtrack(row 1) path.pop() cols[col] diag1[d1] diag2[d2] False backtrack(0) return result请重点看path.append和path.pop这个配套操作。这就是回溯中所谓的“状态恢复”递归进去之前你改了什么等递归出来之后必须原样还原否则下一次兄弟分支会带着上一个分支的残留状态去判断怎么算都是错的。col、diag1、diag2 三个数组同理。这个现象我用一个词概括状态污染。后面调试段落我会专门讲。剪枝在这里是怎么体现的每次尝试col之前先检查列冲突和两条斜线冲突不合法就直接 continue而不是先放下去再在下一层发现错了再回头。别小看这一步它把大量无效分支提前砍掉了。八皇后从完全不剪枝的暴力枚举到这里的剪枝版本性能差距是数量级的。3.3 极小极大与 Alpha-Beta让棋盘题变成“AI 题”如果你在做一个可以两个人下的棋盘游戏大部分训练题做到这里就结束。但如果题目要求“AI 对手”你就要开始接触博弈搜索。这里我最推荐用五子棋或井字棋入门因为规则简单棋型评估也容易理解。博弈搜索的思想是轮到 AI 走它不知道对手下一步会怎么走那就假设对手足够聪明总是会选择对 AI 最不利的落点于是 AI 要考虑所有可能的回应选一个在最坏情况下评分最高的走法。这个“所有回应-取最坏-再上层取最好”的交替过程就是极小极大值搜索。一个简化但完整的 alpha-beta 剪枝搜索如下以五子棋、AI 执黑为例def evaluate_window(window): if window.count(EMPTY) 0: return 0 black window.count(BLACK) white window.count(WHITE) if black 0 and white 0: return 0 if black 4: return 1000 if white 4: return -1000 if black 3: return 100 if white 3: return -100 if black 2: return 10 if white 2: return -10 return 0 def board_score(board): score 0 for r in range(ROWS): for c in range(COLS): for dr, dc in ((0, 1), (1, 0), (1, 1), (1, -1)): window [] for k in range(5): nr, nc r dr * k, c dc * k if not (0 nr ROWS and 0 nc COLS): break window.append(board[nr][nc]) if len(window) 5: score evaluate_window(window) return score def alpha_beta(board, depth, alpha, beta, turn): if depth 0: return board_score(board) moves candidate_moves(board) if turn AI: best -10**9 for r, c in moves: board[r][c] AI v alpha_beta(board, depth - 1, alpha, beta, HUMAN) board[r][c] EMPTY best max(best, v) alpha max(alpha, best) if beta alpha: break return best else: best 10**9 for r, c in moves: board[r][c] HUMAN v alpha_beta(board, depth - 1, alpha, beta, AI) board[r][c] EMPTY best min(best, v) beta min(beta, best) if beta alpha: break return best注意这里的alpha max(alpha, best)和beta min(beta, best)它们就是剪枝的依据。当前搜索已经知道的最好值如果已经超出对方能接受的范围就不用再继续找更“差”的分支了。实际比赛中剪枝顺序很重要如果你把候选着法按启发式排序把较好的着法放前面剪枝效果会好非常多如果顺序很糟alpha-beta 几乎退化成普通极小极大性能差距几十倍。评估函数也没有标准答案。上面这个“数窗口棋子数”的版本非常粗糙但足够让 AI 具备基础战斗力。真正要让它强得分出活三、冲四、眠三这些棋型并给不同棋型合理的权值。做训练题不需要一步到位你可以让 AI 和随机落子对弈观察胜率再逐步调权重。4. 实操记录从控制台棋盘到可对战的小程序4.1 第一版先让棋盘“能看”拿到棋盘题第一件事永远是让棋盘能打印出来。既是为了验证数据结构也是为了方便后续所有调试。打印棋盘用最简单的方式就行但要有坐标轴否则你看着一堆黑白点在猜坐标。def show_board(board): header .join(f{c:2d} for c in range(COLS)) print(header) for r in range(ROWS): row .join(f{board[r][c]:2} for c in range(COLS)) print(f{r:2d} {row})这里的:2是为了对齐。控制台棋盘对齐这一步看起来很基础但真的会影响调试效率。棋盘乱了你经常会把棋型看错以为形成了一个活四其实中间有个空位。我自己的习惯是空格子就不要用太空字符表示用一个可见的占位符比如.这样空位也能被看到。4.2 第二版加交互与规则校验棋盘能看之后第二步是把“落子”变成可操作功能。读入玩家的输入row, col判断是否越界、是否已有棋子、是否轮到该玩家然后更新棋盘。def read_position(): text input(输入行列例如7 8).strip() parts text.split() if len(parts) ! 2: return None r, c int(parts[0]), int(parts[1]) return r, c def main(): board [[EMPTY] * COLS for _ in range(ROWS)] turn BLACK while True: show_board(board) print(黑棋 if turn BLACK else 白棋, 回合) pos read_position() if pos is None: print(输入格式错误重新输入) continue r, c pos if not (0 r ROWS and 0 c COLS): print(越界重新输入) continue if board[r][c] ! EMPTY: print(此位置已有棋子重新输入) continue board[r][c] turn winner check_five(board, r, c) if winner is not None: show_board(board) print(获胜方 (黑棋 if winner BLACK else 白棋)) break turn WHITE if turn BLACK else BLACK这里最重要的是check_five。判断五子棋胜负的普遍做法是检查刚落下的那个棋子向四个方向延伸数同色连续棋子数。我写一下def check_five(board, r, c): piece board[r][c] for dr, dc in ((1, 0), (0, 1), (1, 1), (1, -1)): count 1 for sign in (1, -1): nr, nc r sign * dr, c sign * dc while 0 nr ROWS and 0 nc COLS and board[nr][nc] piece: count 1 nr sign * dr nc sign * dc if count 5: return piece return None你可能会问为什么只检查最后落子的那一点不检查整个棋盘因为其他棋子早就检查过了唯一可能让局面形成五连的新变化一定包含最后落下的这个棋子。所以从这一点出发搜索已经足够。这也是棋盘题的一个重要的思路不重复做全局判断只在状态变化点做局部更新。扩展到中国象棋将军检测、围棋提子判断逻辑都是类似的。4.3 第三版给棋盘加一个“会下棋”的 AI如果训练题包含 AI到这一步就需要把 3.3 节的 alpha-beta 接进来。接的时候建议不要直接写一个巨大函数而是定义一个 AI 入口def ai_move(board, depth2): best_score -10**9 best_move None for r, c in candidate_moves(board): board[r][c] AI score alpha_beta(board, depth - 1, -10**9, 10**9, HUMAN) board[r][c] EMPTY if score best_score: best_score score best_move (r, c) return best_movecandidate_moves的写法推荐只枚举周围四格以内有棋子的空点。因为离所有棋子都很远的点短期看不可能形成威胁枚举它们纯属浪费计算。这一段剪枝虽然不完全严谨存在极端情况下远点才是好点的可能但在训练项目的深度范围内几乎不会错。实际测试下来15x15 五子棋配合 depth2 或 depth4加上候选点裁剪速度完全可接受。到这里一个“能看、能下、能赢人”的棋盘小程序已经成型。整个过程里最难的不是某个算法而是把建模、规则、搜索、交互四块拼在一起还不打架。先把接口定好比如棋盘统一用二维数组、棋局状态只通过落子函数修改这个“不打架”就能做到一大半。5. 调试心得与常见翻车现场5.1 幽灵棋子状态回溯失败的典型症状如果你玩八皇后回溯时发现解的数量不对或者在五子棋 AI 搜索完一步之后棋盘上多了一颗棋子你几乎可以肯定是状态恢复出了问题。我把这种 bug 叫“幽灵棋子”递归分支 A 里放的棋子跑到了分支 B 的棋盘上。排查这类问题先看搜索函数里的每一处修改是否成对出现。place 之后必须有 unplaceappend 之后必须有 pop修改全局数组之后必须在退出分支前还原。最直接的排查手法是在每次递归入口打印当前棋盘的关键状态和你的手算结果对比。另一个隐藏很深的场景是 Python 的可变对象引用。比如你创建棋盘用board [[EMPTY] * COLS] * ROWS然后发现改一个格子整列都变了。这是新手最容易踩的坑外层* ROWS会把多个内层列表引用复制多次而不是创建多个新列表。正确写法是列表推导式[[EMPTY] * COLS for _ in range(ROWS)]。这类问题一旦出现现象会非常诡异你甚至会怀疑是算法逻辑写错了。5.2 性能瓶颈递归深度、搜索分支与剪枝顺序棋盘 AI 常见的性能问题有两个递归层数太深分支数量太多。Python 默认递归深度限制通常在 1000 左右如果你在做棋盘覆盖或迷宫搜索递归深度可能逼近这个值就会抛 RecursionError。可以先sys.setrecursionlimit(10000)应急但更本质的方案是改写成显式栈的迭代版本或者用 BFS 避免深度递归。分支数量多则要靠剪枝和走法排序。我实测过一个五子棋 AIdepth4 时如果候选着法乱序搜索时间接近 20 秒如果按“靠近敌方最近棋子”排序时间能压到 2 秒内。这个现象在博弈类棋盘题里非常明显走法排序的成本很低收益却巨大。建议在candidate_moves里按周围棋子密度或简单棋型价值排序后再返回。5.3 测试方法论棋盘题的正确打开方式棋盘题的规则判断很适合单元测试但很多训练者不写测试全靠手动走棋这样很容易漏掉角落和边界。我列几种必测的用例落子越界、落子在已有棋子上、行首行尾的横向五连、正反对角线的斜向五连、最后一步才形成五连的边界局面、和棋/满盘。如果你写了走法生成器还有一个特别好用的方法对拍。准备一个朴素的、逻辑上完全直白的实现比如八皇后完全枚举再判断合法性然后让优化过的版本和它对同一个输入跑一遍比较输出是否一致。不一致就说明优化版本某个分支判断有问题。这个方法在棋盘题里极好用因为状态空间小的时候暴力实现也跑得动。我自己做中国象棋走法生成器时就是靠一个“啥剪枝都不做”的慢版本和快版本对拍找出过好几个蹩马腿判断的细节错误。提示不要相信一组手测用例通过就等于正确。棋盘题的规则分支非常多随手测十组只能覆盖很浅的路径。对一个纯规则函数用随机状态生成器造几百组局面跑对拍远比手工测试划算。6. 从“交作业”到“小作品”值得做的几个扩展6.1 悔棋、复盘与棋谱导出训练题做完后如果还想把它变成可以展示的作品第一个值得加的功能是悔棋。实现非常便宜维护一个着法列表moves每个元素是(row, col, piece)悔棋就从当前棋盘上把最后一个着法对应位置清空同时把回合、胜负状态同步回退。复盘则是在已有着法列表基础上从头逐步重放。再进一步可以把着法列表按固定格式导出。比如五子棋可以输出一个文本文件第一行是棋盘大小之后每行都是“回合号 行 列 棋子”。这样你甚至可以写出自己的棋谱格式。别看这个功能简单它逼你把棋局当成一个“事件序列”来建模而不是只看当前棋盘快照——这个视角在真实业务里对应的是审计日志、操作记录这一类机制。6.2 换一层“皮”终端、图形与 Web 的取舍棋盘题的界面层可替换性非常强。我见过很多训练者把棋盘数据和打印逻辑写死在一起最后想加图形界面不得不把逻辑全部重构。这也是为什么我在前面强调数据层和 UI 层分离。如果要做图形界面最简单的路径是用一个画板控件逐格绘制背景画网格前景画棋子圆片。再花哨一点可以用 Canvas 做 Web 版本地渲染都可以。实际做完你会发现核心的走法、胜负、AI 搜索代码一行都不用改只要把show_board换成另一种输出介质就算完工。这本身就是一次很好的接口设计练习也是训练题里经常被忽略的加分项。6.3 继续卷性能位棋盘、置换表与开局库如果你还想把性能推到更高棋盘题里有几个偏工程的方向。一是位棋盘一个 8x8 或 9x9 棋盘的状态可以压缩到一个或几个 64 位整数里每个位代表一个格子走法生成、并行判断都可以用位运算批量完成。二是置换表把已经搜索过的局面和评分存进哈希表下次遇到相同局面直接取结果。三是开局库对常见开局预先准备应对AI 在开局阶段直接查表避免搜索浪费。这三个方向随便挑一个深入研究都能单独写一篇长文。对于一个程序设计训练项目来说做到前两个扩展已经远超及格线。很多同学觉得棋盘题是 AI 题很难其实它的难点不是某一个算法而是你愿不愿意把它当做一个可持续迭代的小软件来做。先跑通再优化最后包装成能给别人演示的东西整个过程收获会非常大。回到开头那句话棋盘题的上下限都很高。我带训练小组时见过太多人第一版代码写到一半就删掉重写我也见过有人从纯控制台一路做到带悔棋和初级 AI 的完整作品。两者之间差的只是拆解和迭代。我个人做这类题的习惯是先定接口再写最笨的能跑版本测试通过后再逐步加搜索和优化。每次加一个功能都保证原有用例不挂。这种“加法式”的推进方式比一次次推倒重来要踏实得多。如果你正在为棋盘题头疼不妨试着把第一步的目标缩小到“棋盘能打印、棋子能放上去”你会发现后面的事情会顺利很多。

相关新闻

论文 AI 降重改写避坑指南,几款常用降AI率工具怎么选才靠谱

论文 AI 降重改写避坑指南,几款常用降AI率工具怎么选才靠谱

摘要:本文围绕论文写作中的改写与降重需求,对比了几款常见的AI辅助工具,从改写能力、语言润色、引用规范等维度做了横向梳理,并给出按写作阶段和语种匹配的选型思路。结论是先看清自己卡在改写还是润色,再决定用哪一类…

2026/10/15 0:34:33 阅读更多 →
2026 重复率和 AI 率同时超标?一站式AI智能降重工具实测指南

2026 重复率和 AI 率同时超标?一站式AI智能降重工具实测指南

一、前言:2026 高校论文审核新难题 随着高校学术审核体系不断升级,知网、维普等主流检测平台全面上线AIGC 智能检测功能,当代毕业生的论文写作与修改迎来双重考验。以往论文仅需攻克重复率超标问题,如今还要规避AI写作痕迹检测风险…

2026/10/15 0:34:33 阅读更多 →
市面上有哪些是真正不打乱逻辑的降AIGC工具(规避AIGC机器检测)

市面上有哪些是真正不打乱逻辑的降AIGC工具(规避AIGC机器检测)

最崩溃的不是查重难题,而是查重达标却AI率超标亮红灯!很多工具只会简单同义词替换、浅层改字,根本洗不掉AI专属句式、行文逻辑和高频模板话术,学校AIGC检测一查一个准,论文直接凉凉。 本篇结合全网实测数据&#xff0c…

2026/10/15 0:34:33 阅读更多 →

最新新闻

Apollo-11 自动化任务调度框架:状态机与插件化设计实践

Apollo-11 自动化任务调度框架:状态机与插件化设计实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:13:56 阅读更多 →
微信积分商城H5落地指南:授权、账务与并发防超卖全解析

微信积分商城H5落地指南:授权、账务与并发防超卖全解析

简介:这是一套面向移动端微信积分兑换商城的H5项目源码,定位于帮助开发者快速搭建具备签到、游戏积分、代金券兑换等功能的积分商城页面。基于HTML5技术实现,适配手机微信环境,适用于电商运营、会员营销等场景,也适合前…

2026/10/15 1:13:56 阅读更多 →
大数据驱动的人工智能医疗:从数据治理到临床落地的实践指南

大数据驱动的人工智能医疗:从数据治理到临床落地的实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:13:56 阅读更多 →
NumPy学习指南:从ndarray到广播,掌握高效数组计算

NumPy学习指南:从ndarray到广播,掌握高效数组计算

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:13:56 阅读更多 →
漂亮通用界面:设计令牌与组件化的多项目UI工程路线

漂亮通用界面:设计令牌与组件化的多项目UI工程路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:13:56 阅读更多 →
C#自动更新程序源码:客户端软件安全升级的架构与实现要点

C#自动更新程序源码:客户端软件安全升级的架构与实现要点

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 1:12:55 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →