iSpring 前端面试题「Пятнашки」:React Hooks + TypeScript 实现可解 15 拼图实战指南

发布时间:2026/10/10 8:25:24

iSpring 前端面试题「Пятнашки」:React Hooks + TypeScript 实现可解 15 拼图实战指南 教程【免费下载链接】ru-test-assignmentsТестовые задания для самостоятельного выполнения от разных it компаний项目地址https://gitcode.com/gh_mirrors/ru/ru-test-assignments点击查看免费下载导读本文围绕 iSpringispringtech/coding-interview前端面试题中的「Пятнашки」15 Puzzle / 数字华容道任务完整解读原题的四项功能要求与五项技术约束并结合经典 15 拼图的算法原理给出可复现的 React Hooks TypeScript 实现方案包括可解性判定、洗牌算法、点击移动与胜利检测。读完本文你将能独立完成这道前端测试题并理解它背后考察的 React 状态管理、不可变更新与组合数学知识点。原题出自 frontend.md 所列测试任务清单完整题目位于 15.md。一、原题要求逐条解读1.1 功能需求Задание原文档要求开发经典版本的“Пятнашки”游戏具体功能点如下「Начать заново」重新开始按钮将数字 115 以随机顺序打乱排列生成的组合必须是可解的решаема不能随便生成任意乱序否则可能无解方块通过点击移动Квадратики должны перемещаться по клику点击某个方块若其与空格相邻则滑动到位正确排列时向用户祝贺胜利поздравлен с победой当 115 按序排好且空格归位时触发胜利提示。1.2 技术约束Требования原题对实现方式有明确限制这是面试官考察的重点约束项具体内容语言TypeScript或 Vanilla JS 组件类型检查样式/结构纯手写 CSS 与 HTML禁止预处理器Sass/Less与模板引擎UI 框架必须使用 React且采用函数式风格 Hooks第三方依赖除 React 外不得引入任何第三方库加分项使用 state manager状态管理器自选如 Zustand/Redux Toolkit这些约束意味着打乱算法、可解性判断、移动逻辑、胜利判定都必须由你自己实现不能借助 lodash 之类工具库也不能用现成的拼图组件。二、核心算法为什么随机打乱可能导致无解2.1 可解性判定的数学原理15 拼图4×4 棋盘含一个空格并不是所有排列都可还原。一个排列可解的充要条件如下空格从初始位置右下角到目标位置的曼哈顿距离为偶数在 4×4 棋盘中空格的目标位置为第 4 行第 4 列初始与目标相同距离恒为 0为偶数逆序对inversions数量为偶数。逆序对的定义从左到右、从上到下读取棋盘跳过空格得到长度为 15 的序列若其中某一对数字i j但位置上前者大于后者则计一个逆序对。当逆序对数量为偶数时排列可解为奇数时不可解。由于本题中空格最终仍回到右下角奇偶性一致判定规则可简化为逆序对数为偶数即可解。2.2 为什么必须显式保证可解性如果只是简单地对1..15做Math.random()洗牌约有 50% 的概率生成不可解排列。用户在不可解的棋盘上无论怎么移动都无法完成游戏就“卡死”了。因此原题特别强调“生成的组合必须可解”这是本题最重要的算法考察点。2.3 两种可靠的洗牌策略策略一对合法移动序列洗牌正向构造从已还原的目标棋盘出发随机执行 N 次合法移动只能移动与空格相邻的方块。由于每一步都从可解状态出发最终状态必然可解for (let i 0; i 200; i) { const moves getLegalMoves(board, emptyIndex); // 空格上下左右可交换的方块 const pick moves[Math.floor(Math.random() * moves.length)]; swap(board, emptyIndex, pick); }策略二随机排列 逆序对校验逆向修正先生成随机排列计算逆序对数若为奇数交换任意两个非空格方块如前两个数字将逆序对奇偶性翻转从而保证可解function isSolvable(flat: number[]): boolean { const tiles flat.filter((v) v ! EMPTY); let inversions 0; for (let i 0; i tiles.length; i) { for (let j i 1; j tiles.length; j) { if (tiles[i] tiles[j]) inversions; } } return inversions % 2 0; }两种策略任选其一即可建议优先采用策略一因为它的正确性不依赖对奇偶规则的推导且更容易用测试验证。三、React Hooks 架构设计3.1 状态模型在函数式 React 中用 Hooks 管理游戏状态的核心思路是把棋盘建模为一维数组空格用0表示索引位置即棋盘格子编号type Board number[]; // 长度 16值为 0..150 表示空格const [board, setBoard] useStateBoard(SOLVED_BOARD); const [moves, setMoves] useState(0); const [won, setWon] useState(false);其中SOLVED_BOARD [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]目标状态空格在末尾。3.2 移动逻辑点击与相邻性判定“方块按点击移动”的本质是点击的方块索引必须与空格索引相邻上下左右二者才交换。用useCallback封装const moveTile useCallback( (index: number) { if (won) return; const emptyIndex board.indexOf(0); const row Math.floor(index / 4); const col index % 4; const eRow Math.floor(emptyIndex / 4); const eCol emptyIndex % 4; const isAdjacent Math.abs(row - eRow) Math.abs(col - eCol) 1; if (!isAdjacent) return; // 不相邻忽略点击 const next [...board]; [next[index], next[emptyIndex]] [next[emptyIndex], next[index]]; setBoard(next); setMoves((m) m 1); }, [board, won] );这里用Math.abs(dRow) Math.abs(dCol) 1判断曼哈顿距离为 1 即相邻简洁且无边界问题。注意setBoard(next)传入的是新数组满足 React 不可变更新的要求保证重渲染正确。3.3 胜利检测每次setBoard后用useEffect监听棋盘是否达到目标状态useEffect(() { if (board.every((v, i) v SOLVED_BOARD[i])) { setWon(true); } }, [board]);也可以把判断内联进moveTile在交换后立即比对目标数组命中则setWon(true)并渲染祝贺消息如「Поздравляем! Вы собрали головоломку за N ходов」。3.4 重新开始按钮「Начать заново」按钮将棋盘重置为洗牌后的新随机可解状态并复位步数与胜利标记const shuffle useCallback(() { const shuffled randomSolvableBoard(); // 见 2.3 节两种策略之一 setBoard(shuffled); setMoves(0); setWon(false); }, []);建议在首次挂载useEffect[]依赖时也执行一次洗牌让用户进入页面即可开始游戏。四、渲染与样式实现要点4.1 纯 CSS 网格布局原题要求纯手写 CSS无预处理器、无 UI 库4×4 棋盘用 CSS Grid 即可优雅实现.board { display: grid; grid-template-columns: repeat(4, 80px); grid-template-rows: repeat(4, 80px); gap: 4px; } .tile { display: flex; align-items: center; justify-content: center; font-size: 24px; border-radius: 6px; background: #4a90d9; color: #fff; cursor: pointer; user-select: none; } .tile--empty { background: transparent; cursor: default; }渲染时div classNameboard {board.map((value, index) ( button key{index} className{tile ${value 0 ? tile--empty : }} onClick{() moveTile(index)} disabled{value 0} {value 0 ? : value} /button ))} /div用button而非div可以免费获得键盘可达性这是加分细节。空格格子渲染为空且禁用点击。4.2 组件拆分建议App持有游戏状态与事件处理洗牌、移动、胜利标志Board纯展示组件接收board与onTileClickTile单个方块负责自身样式与点击回调。这样的拆分让状态集中在顶层符合函数式 Hooks 的推荐写法也便于后续引入 state manager。五、加分项接入状态管理器State Manager原题明确写出“使用 state manager 是加分项”。在仅允许 React 一个依赖的前提下可以选择轻量的 Zustandzustand包或 React 内置的useReducer Context。以useReducer为例零额外依赖最符合“不引入第三方库”约束type Action | { type: MOVE; index: number } | { type: SHUFFLE } | { type: RESET }; function reducer(state: GameState, action: Action): GameState { switch (action.type) { case MOVE: { // 相邻判定 交换 胜利检测返回新 state return movedState(state, action.index); } case SHUFFLE: { return { board: randomSolvableBoard(), moves: 0, won: false }; } default: return state; } }Reducer 是纯函数把“移动、洗牌、重置”三类状态转换集中在一处天然可测试。若面试官偏好外部状态库也可用 Zustand 的create定义 store效果等价。六、可测试性与代码组织建议纯函数优先把isSolvable、randomSolvableBoard、isAdjacent、move都写成不依赖 React 的纯函数便于单测用例覆盖至少验证三类用例——可解判定对错例的区分、从任意可解状态移动一步后仍可解、胜利检测在目标状态触发运行方式项目可用 Create React App 或 Vite 初始化二者均以 TypeScript 模板开箱支持 JSX 与类型检查执行npm install与npm start或npm run dev即可本地运行npm test运行测试。注意实现游戏逻辑本身无需任何额外库第三方依赖仅限 React 及脚手架工具。七、面试考察点总结这道题在 iSpring 的 frontend.md 中与「Пианино (Junior)」、「Пианино (Middle)」、「Drag to area」、「Видеоплеер」并列属于面向 Frontend 开发者的经典测试任务主要考察算法功底15 拼图可解性判定逆序对奇偶性与洗牌策略React 函数式写法HooksuseState/useEffect/useCallback与不可变状态更新代码组织纯函数与组件拆分、state manager 的使用工程约束意识在“零第三方库”限制下完成全部功能这对测试候选人区分度较高。完整题目原文见 15.md同系列其他任务可对照 frontend.md 任务清单查阅。赞分享教程【免费下载链接】ru-test-assignmentsТестовые задания для самостоятельного выполнения от разных it компаний项目地址https://gitcode.com/gh_mirrors/ru/ru-test-assignments点击查看免费下载相关推荐Sendsay 前端面试题实战用 React TypeScript 从零实现拖拽式计算器构造器Calculator ConstructorSendsay 前端面试题实战用 React TypeScript 从零实现拖拽式计算器构造器Calculator Constructor 本篇技术指教程KODE 前端实习生测试任务实战指南React TypeScript 实现员工目录应用KODE 前端实习生测试任务实战指南React TypeScript 实现员工目录应用 导读 本文以开源仓库 ru test assignments ht教程Highcharts React高级技巧自定义组件集成与性能优化实战Highcharts React高级技巧自定义组件集成与性能优化实战 Highcharts React是官方支持的React图表组件库它允许开发者轻松地在R上一篇中文AI绘画终极指南5分钟掌握ComfyUI工作流配置秘籍下一篇开发者必看Llama-3.2-1B-Instruct API接口调用与参数配置详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/10 8:20:23

HP MSA 1040存储部署全解析:从硬件连线到CLI故障排查

简介:面向存储系统管理员与数据中心运维人员的 HP MSA 1040 用户指南 PDF 文档,系统讲解 MSA 1040 控制器机箱的初始硬件设置与部署要点。内容覆盖 MSA 1040 存储型号、机箱用户界面、功能优势、前面板/后面板布局、控制器模块、磁盘驱动器、SFF/LFF 驱动…

2026/10/10 8:20:23

REA模型:用事件溯源思维重构订单与库存数据建模

先说清楚——标题里的“rea”不是随手打的乱码,它是我最近在给某订货系统的数据库做重构时,反复琢磨的一个缩写:REA,也就是 Resources-Events-Agents(资源-事件-代理人)语义建模模型。如果你和我一样&#…

2026/10/10 9:31:01

Skills能力单元:从设计到落地的可复用架构实践

1. 从“skills”这个词说起:它到底指什么“skills”这个词最近又被推到了讨论中心,但很多人第一次看到它时,脑子里冒出的问号比句号还多。它不是一个具体的软件,也不是某个单一的技术栈,而是一个在开发者社区里逐渐沉淀…

2026/10/10 9:31:01

JavaEE+MySQL酒店管理系统:从毕设源码到部署答辩全指南

简介:一套基于JavaEEMySQL的酒店管理系统完整毕业设计资源,包含项目源码、数据库SQL脚本、毕业论文、答辩PPT和演示视频,适合毕业设计、课程设计或Java Web入门学习者。压缩包约186.81MB,涵盖源码工程、数据库初始化脚本、论文文档…

2026/10/10 9:31:01

从AST到质量门禁:代码审查工具impeccable的设计与实践

什么样的代码才配叫“无可挑剔”?我花了大半年时间写了一个名为 impeccable 的代码质量审查工具,才慢慢摸到答案的边缘。它解决的不只是“这段代码能不能跑”,更是“这段代码上线两天后会不会让我们后悔”。今天把这套设计思路、踩坑经过和落…

2026/10/10 9:31:01

a2conn:Python连接内网数据库的SSH隧道管理利器

开篇先把一个很容易被带偏的点说清楚:a2conn 这个包,名字里那个 a2,很容易让人以为它和 aio 系列一样是个异步库。我第一次看到也是这么以为的,装上之后才发现,它跟异步没有半点关系,它的主要作用是帮你在 …

2026/10/10 9:31:01

Suricata毕设实战:从最小系统到可视化展示与避坑指南

简介:基于Suricata的轻量级网络入侵检测系统毕业设计源码包,适合计算机、电子信息等专业的学生用于毕设、课程设计或期末大作业。项目经导师指导并认可,评审高达九十八分,覆盖数据包捕获、协议解析、规则匹配与告警输出等完整流程…

2026/10/10 9:25:48

麦迪拉专业吗

时光回溯到九十年代中期的淮安,运河水静静流淌,古城街巷里飘起了新式烘焙的香气。彼时,烘焙行业刚刚传入这座江南小城,街头巷尾的糕点铺子还以传统点心为主,西式面包、奶油蛋糕对许多淮安家庭而言还是新鲜事物。就在这…

2026/10/10 7:31:36

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/9 20:15:56

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/8 6:05:44

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

2026/10/10 0:04:53

从逻辑门到计算机:数字电路核心原理与全加器搭建实战

如果你拆过一台旧电脑的主板,盯着那些黑乎乎的小芯片看上一会儿,可能会冒出同一个疑问:这堆引脚密集的元件,到底是怎么“变”出那么复杂的应用的?答案并不在某个神秘的部件里,而是在所有芯片内部都在反复使…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑