- 教程
【免费下载链接】ru-test-assignments
Тестовые задания для самостоятельного выполнения от разных it компаний
导读
本文基于开源仓库 ru-test-assignments 中收录的 frontend/incode-group/finance-test-task.md 任务文档展开,系统讲解如何从零实现一个连接本地 Socket.io 服务的实时股价行情(Price Ticker)前端应用。读完本文,你将掌握该任务的完整需求拆解、技术选型约束、本地服务与客户端/测试的启动流程、价格数据的 JSON 结构与字段语义,以及可选的加分功能实现思路,可直接照此完成并提交一份可运行、可测试、结构清晰的 React 解决方案。
一、任务背景与核心目标
incode-group(Incode LLC)在frontend/incode-group目录下提供了多个前端测试任务,本文聚焦其中的 React Test Task(finance-test-task)。任务原文位于 finance-test-task.md,其核心诉求非常明确:
在 UI 上实时(realtime)展示价格行情(price tickers)数据,价格数据由本地运行的服务提供。
换言之,这不是一个纯静态页面任务,而是一个客户端与本地 Socket 服务实时双向通信的实战演练:应用需要连接本地服务,并把不断更新的报价渲染到界面上。文档同时强调:“任何用于展示价格如何变化的额外可视化都是加分项”,且“测试是本次练习的重要组成部分”。
二、需求拆解与技术栈约束
2.1 必备需求
任务文档在 “Requirements” 一节中给出了两条必须满足的需求:
| 编号 | 需求 |
|---|---|
| 1 | 应用应能连接本地运行的服务(locally running service) |
| 2 | 应用应能实时渲染若干 ticker(股票代码)的价格变化 |
参考界面样式可以借鉴 Google Finance 页面(任务原文给出的提示),但实现上不强制任何特定视觉方案。
2.2 加分功能(Bonus)
文档明确列出以下可选加分项,并特别注明需要在任务文件(README/本文件)中描述已实现的加分功能:
- 额外的视觉特效,用于高亮价格上涨或下跌(positive/negative changes);
- 用户可自行开关(switch on/off)某些 ticker;
- 用户可自行指定数据刷新/推送间隔(interval time);
- 用户可向自选组(watching group)添加或移除 ticker;
- 任何你认为有用的额外功能。
这些加分项共同指向一个方向:让应用从“被动展示”升级为“可交互的行情工作台”,也是区分基础实现与优秀实现的关键分水岭。
2.3 技术栈要求
任务对技术选型有明确约束,原文 “You should use the next technologies” 列出:
- React(优先使用 Hooks);
- Redux(搭配 Redux-Thunk 或你熟悉的任意 Redux 中间件),或你选择的任意其他状态管理库(state-manager library);
- Socket.io—— 用于连接服务;
- UI 库:任意你喜欢的,或纯 CSS;
- Testing Library—— 用于编写测试。
值得注意的细节:文档对状态管理给出了较大的自由度(Redux 系列或任意替代品),对 UI 方案完全开放,但对通信层(Socket.io)与测试层(Testing Library)是硬性要求。这意味着 Socket.io 客户端集成与基于 Testing Library 的组件/交互测试是任务的技术考核重点。
2.4 评审维度
文档在 “We will assess the next parts” 中给出了明确的评分维度,可作为实现时的自查清单:
- 可运行性(workability):应用是否真正跑得起来;
- 项目结构(projects structure):文件如何组织、分层是否清晰;
- 代码质量(code quality):是否干净、可读;文档建议安装并使用ESLint 和 Prettier来保证代码风格;
- React 及其生态的掌握(knowledge React and its ecosystem):如何组合、编排各库协同工作;
- 测试(testing):能否写出有效的测试代码。
三、本地环境启动指南
任务采用经典的server+client双目录结构,两个进程需要分别在独立的 bash shell 中启动。
3.1 启动本地价格服务(server)
# 打开一个新的 bash shell cd server npm install # 或 yarn install npm run start # 或 yarn start服务启动后,可直接访问http://localhost:4000验证服务是否正常工作,并检查它产出的数据格式(见下文 JSON 结构)。这一步非常关键:在动手写前端之前,先确认本地服务返回的数据结构,能避免大量想当然的字段假设。
3.2 启动前端应用(client)
# 打开一个新的 bash shell cd client npm install # 或 yarn install npm run start # 或 yarn start3.3 运行测试
# 打开一个新的 bash shell cd client npm run test # 或 yarn test三个步骤对应三个独立终端进程,这是典型的前后端分离联调流程:server 提供数据源,client 消费数据,测试独立运行验证逻辑。整个仓库内其他前端任务(如 frontend/agro-club/junior-frontend.md 的本地 API 也约定在http://localhost:4000)同样遵循此类本地服务联调模式。
四、价格服务协议与数据格式
4.1 服务地址与通信方式
- URL:
http://localhost:4000 - 传输方式:通过web-sockets 实时推送(文档原文 “Price tickers are real-time via web-sockets”),这也是任务强制使用 Socket.io 的原因——前端需以
io("http://localhost:4000")之类的连接方式订阅行情流,而非轮询 HTTP 接口。
4.2 服务返回的 JSON 示例
文档给出了服务产出的典型响应(一个 ticker 数组),完整字段如下:
[ { "ticker": "AAPL", "exchange": "NASDAQ", "price": 279.29, "change": 64.52, "change_percent": 0.84, "dividend": 0.56, "yield": 1.34, "last_trade_time": "2021-04-30T11:53:21.000Z" }, {"ticker":"GOOGL","exchange":"NASDAQ","price":237.08,"change":154.38,"change_percent":0.10,"dividend":0.46,"yield":1.18,"last_trade_time":"2021-04-30T11:53:21.000Z"}, {"ticker":"MSFT","exchange":"NASDAQ","price":261.46,"change":161.45,"change_percent":0.41,"dividend":0.18,"yield":0.98,"last_trade_time":"2021-04-30T11:53:21.000Z"}, {"ticker":"AMZN","exchange":"NASDAQ","price":260.34,"change":128.71,"change_percent":0.60,"dividend":0.07,"yield":0.42,"last_trade_time":"2021-04-30T11:53:21.000Z"}, {"ticker":"FB","exchange":"NASDAQ","price":266.77,"change":171.92,"change_percent":0.75,"dividend":0.52,"yield":1.31,"last_trade_time":"2021-04-30T11:53:21.000Z"}, {"ticker":"TSLA","exchange":"NASDAQ","price":272.13,"change":158.76,"change_percent":0.10,"dividend":0.96,"yield":1.00,"last_trade_time":"2021-04-30T11:53:21.000Z"} ]4.3 字段语义详解
结合行情行业惯例与任务的数据结构,可对各字段做如下理解(用于驱动 UI 渲染与可视化逻辑):
| 字段 | 类型 | 语义与用途 |
|---|---|---|
ticker | string | 股票代码标识(如AAPL),是列表渲染的 key 与自选组管理的唯一标识 |
exchange | string | 交易所名称(示例中均为NASDAQ),可用于分组/筛选展示 |
price | number | 当前最新成交价,是行情看板的主体数值 |
change | number | 价格变动绝对值(较参考价的涨跌额),用于判断涨/跌方向 |
change_percent | number | 价格变动百分比(示例中为小数形式,如0.84表示 0.84%),是红绿高亮的核心依据 |
dividend | number | 每股股息(dividend per share) |
yield | number | 股息率/收益率(示例中1.34即 1.34%) |
last_trade_time | string | 最近一笔成交的 ISO 8601 时间戳(如2021-04-30T11:53:21.000Z),可用于“最后更新于 xx 秒前”之类的时效展示 |
需要注意:change_percent在示例中是以小数(0.84、0.10)形式给出的,展示为百分比时应自行换算(如乘以 100 再四舍五入),不要想当然当作整数百分比直接渲染。last_trade_time为 UTC 时间(带Z后缀),前端展示时建议调用toLocaleString()等本地化方法转换为用户时区。
4.4 任务使用的 6 个 ticker
服务默认推送以下股票代码,对应的公司信息如下:
| Ticker | 公司 | 示例交易所 |
|---|---|---|
| AAPL | Apple(苹果) | NASDAQ |
| GOOGL | Alphabet(谷歌母公司) | NASDAQ |
| MSFT | Microsoft(微软) | NASDAQ |
| AMZN | Amazon(亚马逊) | NASDAQ |
| FB | Facebook(Meta 前身) | NASDAQ |
| TSLA | Tesla(特斯拉) | NASDAQ |
这 6 个代码构成了任务的标准数据面。从仓库结构看,该任务是文档型任务(frontend/incode-group目录下仅有任务说明文档与另一任务的 github-kanban-test-task.md,未附带 server/client 源码),因此具体推送频率、Socket 事件名等需以你克隆原仓库后本地服务的实际实现为准——这也是为什么文档建议先访问http://localhost:4000检查真实数据。
五、架构设计与实现要点
原文档本身未给出实现代码,但结合其技术约束(React Hooks + Redux/状态管理 + Socket.io + Testing Library)与评审维度,可以从工程实践角度给出如下可落地的架构建议。
5.1 建议的项目结构
client/ ├── src/ │ ├── api/ │ │ └── socket.js # Socket.io 连接单例与事件订阅封装 │ ├── store/ │ │ ├── actions/ # fetchTickers、toggleTicker 等 action │ │ ├── reducers/ # tickers reducer、settings reducer │ │ └── middlewares/ # socket 中间件(如 Redux-Thunk / redux-saga) │ ├── components/ │ │ ├── TickerList/ # 行情列表 │ │ ├── TickerItem/ # 单行行情(涨跌高亮) │ │ └── Controls/ # 开关、间隔设置、自选组管理 │ ├── hooks/ │ │ └── useSocket.js # 封装 socket 订阅逻辑的 React Hook │ ├── utils/ │ │ └── format.js # 百分比换算、时间格式化 │ └── __tests__/ # Testing Library 测试 └── package.json5.2 数据流建议:Socket 事件 → Store → UI
一个常见且稳妥的编排方式:
- 连接层:在入口或专用 Hook 中建立 Socket.io 连接(如
io("http://localhost:4000")); - 订阅层:监听服务推送的行情事件,把最新数组 dispatch 到 Redux store(例如
dispatch({ type: "TICKERS_RECEIVED", payload })); - 状态层:reducer 维护
tickers数组(以ticker字段为 key 做增量合并,避免旧数据被整体覆盖导致闪烁)以及用户设置(启用的 ticker 集合、刷新间隔、自选组); - 视图层:组件通过
useSelector读取状态渲染,涨跌高亮依据change/change_percent的正负号决定绿色/红色(或你选定的配色方案)。
加分功能大多落在“设置状态”这一维度上:开关 ticker 即从展示集合中过滤;间隔设置可驱动前端对推送做节流/合并渲染;自选组则是维护一个额外的watchingGroup集合。这些状态全部收敛进 store,便于测试与调试。
5.3 关于“实时性”的两个实现细节
- 连接生命周期:socket 连接应在组件卸载时正确断开(
socket.disconnect()/off()清理监听),避免内存泄漏与重复订阅; - 渲染合并:高频推送场景下,可使用
requestAnimationFrame或节流把多次 state 更新合并为一次渲染,或仅在数值真正变化时更新对应行,保证列表滚动与高亮动画流畅。
六、测试策略(Testing Library)
任务将“testing”列为独立评审维度,建议至少覆盖以下三类用例:
- 渲染测试:给定一份固定的 tickers 数据(或 mock 的 socket 事件),断言列表渲染出正确的代码与价格文本;
- 交互测试:模拟用户点击开关/移除按钮,断言对应行从视图中消失或样式切换;
- 数据转换测试:对
change_percent的百分比换算、last_trade_time的本地化格式化等纯函数做单元测试。
由于真实场景依赖 Socket.io 服务,测试中应通过 mock 客户端(例如将 socket 模块封装后注入假事件发射器,或在测试中jest.mock掉socket.io-client)隔离网络依赖,让组件测试稳定可复现。这也再次印证了 5.1 中“把 socket 封装成独立模块”的必要性——它是可测性的基石。
七、提交与验收流程
任务原文 “How to complete the task” 给出了完整的交付流程:
- Clone 或 fork 本仓库;
- 修改
client文件夹的内容(主要开发工作); - 如需完成加分任务,可修改
server文件夹的内容; - 提交并推送代码到你的仓库;
- 把仓库链接发送给招聘方。
交付前建议对照 2.4 的评审维度做最终自检:应用能否启动、结构是否清晰、代码是否经过 ESLint/Prettier 格式化、测试是否通过,以及加分功能是否已在任务文档中说明。
八、小结
本文以 finance-test-task.md 为骨架,完整覆盖了该 React 实时行情任务的方方面面:两条必备需求与五类加分项、明确的技术栈约束(React Hooks + Redux 系状态管理 + Socket.io + Testing Library)、server/client/test 三套启动命令、http://localhost:4000服务的 JSON 数据格式与逐字段语义、6 个标准 ticker 清单,以及从工程实践出发的项目结构、数据流与测试策略建议。无论你是准备面试的求职者,还是想练习实时前端架构的开发者,都可以按本文路线快速落地一个结构清晰、可运行、可测试的行情看板,并用加分功能把方案打磨出亮点。
- 教程
【免费下载链接】ru-test-assignments
Тестовые задания для самостоятельного выполнения от разных it компаний
相关推荐
Future Group 前端开发测试任务实战:基于 React + Redux 构建 GitHub 用户仓库搜索应用
Future Group 前端开发测试任务实战:基于 React + Redux 构建 GitHub 用户仓库搜索应用 导读 本文围绕 Future Group
教程Avito 2022 前端实习生任务实战:基于 React + Redux 打造 Hacker News 双页面 SPA
Avito 2022 前端实习生任务实战:基于 React + Redux 打造 Hacker News 双页面 SPA 本篇技术指南以 Avito 2022
教程Avito Seller Experience 前端实习任务实战指南:基于 React + Redux 构建 Hacker News 双页面应用
Avito Seller Experience 前端实习任务实战指南:基于 React + Redux 构建 Hacker News 双页面应用 导读 本文全面
教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考