Skip to content

基金助手 fund-helper — 面试问答

项目时间:2026年2月 - 至今 | 安装量 170+ | GitHub 10+ Star
代码仓库:https://github.com/crispyChicken999/fund-helper-vscode
Web端:https://fund-helper.ccwu.cc/

Q1: 双端架构 + 跨端同步

面试官可能问:"说说 VSCode 插件端和 Web 端是怎么设计的?怎么同步数据?"

回答

VSCode 端用 TreeView + WebviewView 展示数据,通过 Extension API 的 Configuration 存配置。Web 端是 Vue3 + Vite + Pinia 的 SPA,数据存 LocalStorage。

同步用的是 JSONBox 这个免费云存储服务。两端导出的数据格式完全一样——基金列表 {code, num, cost}、分组、排序配置等。Web 端生成二维码,用户扫码后在 VSCode 端把配置推到云端,Web 端再拉下来。带了版本号和时间戳做简单的冲突检测:谁的版本高用谁的。

追问:"为什么选 JSONBox 而不是自建后端?"

个人开源项目,JSONBox 免费、零搭建。数据量只有几 KB,全量同步就够了,没必要自建后端。

Q2: VSCode 插件开发

面试官可能问:"TreeView 和 WebviewView 两种视图模式怎么协作的?"

回答

核心是一个共享的 FundDataManager,TreeView 和 WebviewView 用同一个实例,避免重复拉数据。

TreeView 是 VSCode 原生树形列表,用 view/item/contextinline group 在每个基金行右边放上加仓/减仓/删除按钮。WebviewView 是嵌入网页视图,Table 交互更丰富——列排序、列显隐控制、拖拽排序。

插件一共注册了 36 个命令,通过 when 条件控制不同场景下哪些菜单可见。配置通过 vscode.workspace.getConfiguration 读写,自动持久化到 settings.json。

追问:"数据怎么在两个视图间同步?"

刷新时调用 fundDataManager.refreshFundData() → 同时通知 TreeView 和 WebviewView 更新。配置变更监听 onDidChangeConfiguration,数据拉新后用 postMessage 推给 WebviewView。

Q3: 基金计算引擎

面试官可能问:"说说 QDII 基金估值是怎么算的?"

回答

普通基金用 fundgz.1234567.com.cn 的 JSONP 接口就能拿到实时估值。QDII 投海外市场,这个接口不覆盖。

我的做法是:调东方财富的接口拿基金季报的股票持仓和权重 → 批量拉这些股票实时涨跌幅 → 按持仓权重加权平均,算出估算涨幅。虽然不如官方估值精确,但比完全看不到要好。

另外还做了数据过期检测——如果 gztime 不是今天的日期,就清掉估值数据不展示,避免显示昨天的旧数据误导用户。

追问:"成本价怎么算的?"

加权平均法:(旧成本 × 旧份额 + 新买入成本) ÷ (旧份额 + 新份额)。加减仓时都自动重算。也支持用户手动输入总金额反推成本价,适配从其他平台导入持仓的场景。

Q4: 跨域代理方案

面试官可能问:"浏览器端的跨域问题怎么解决的?"

回答

基金数据接口有严格的 CORS 限制和来源检测。我做了分层代理:

  • VSCode 端:Node.js 环境直接 fetch,没跨域问题
  • Web 本地开发:Vite proxy 转发,设置 changeOrigin + 伪造 Referer/Origin 头
  • Web 生产:部署到 Cloudflare Pages,利用它的网络条件

封装了一个 proxyFetch 函数,自动判断请求是否需要代理、当前是什么环境,然后走对应的代理路径。上层代码不用关心代理细节。

追问:"关键的请求头怎么伪造的?"

比如 fundmobapi 接口要求 Referer: https://mpservice.com/app,天天基金要求 Origin: https://h5.1234567.com.cn。在 Vite proxy 里直接写死这些头就行,changeOrigin: true 会把 Host 也改掉。

Q5: ECharts 可视化

面试官可能问:"图表这块做了什么?"

回答

行情中心做了大盘指数卡片、板块排行柱状图、资金流向折线图、涨跌家数统计。基金详情页做了净值走势图,支持 1月/3月/半年/1年/3年切换。对比页面做了多基金净值叠图。

技术上封装了 echarts 工具函数统一处理初始化和 resize,跟 Pinia 的暗黑模式联动自动切主题。

Q6: AI 多模型集成

面试官可能问:"怎么接入多个 AI 模型的?"

回答

因为这些模型都提供了 OpenAI 兼容的 API,我就直接用 OpenAI SDK,切换 baseURLmodel 参数来适配不同厂商。阿里云、硅基流动、DeepSeek 都是同样的调用方式。

配置流程做了个 5 步 Webview 向导:选厂商 → 填 Key → 选模型 → 设参数 → 测试连接。Prompt 设计分了 6 个维度:宏观政策、行业地位、持仓分析、财务健康、资金动向、综合建议,控制在 1000 字以内。

Q7: PWA + 部署

面试官可能问:"PWA 和部署怎么做的?"

回答

部署了两个站点:Cloudflare Pages 主力(全球 CDN),GitHub Pages 备用(Actions 自动部署)。Vite 通过 mode 控制 base path 适配不同站点。

PWA 用 vite-plugin-pwa,Manifest 设置 standalone 模式可以安装到桌面。缓存策略分了三层:API 类接口用 NetworkOnly 保证实时性,静态资源用 CacheFirst 加速加载,字体用 StaleWhileRevalidate 兼顾速度和新旧。

Q8: 数据存储架构

面试官可能问:"LocalStorage 和 JSONBox 怎么分工的?"

回答

本地所有数据通过 storageService 封装存 LocalStorage,前缀 fund_helper_ 做命名空间隔离。JSONBox 只做云端备份和跨端同步。

同步逻辑用版本号对比:云端高就拉取,本地高就上传,相同就跳过。冲突时让用户选用哪个版本。同步时还做了 VSCode 专属配置的保护——hideStatusBardefaultViewMode 这些 Web 端没有的字段不会被覆盖。

追问:"LocalStorage 够用吗?"

基金配置数据很小,100 只基金也才几 KB。基金详情缓存单独存,可以按需清理。如果后续需要更大容量,可以考虑迁 IndexedDB。

行为面试常见题快速答

"为什么做这个项目?"

自己平时定投基金,在 VSCode 里写代码时想快速看一眼收益,不想老掏手机。市面上没有 VSCode 端的同类插件,就自己写了。

"遇到的最大难点?"

跨域。浏览器端调基金接口被 CORS 拦死,试了好几套方案——JSONP 只支持部分接口、第三方代理不稳定、Netlify Function 有限额。最后结合 Vite proxy(开发)+ Cloudflare Pages(生产)搞定了。

"有什么遗憾?"

测试覆盖不够,没写单元测试。共享代码(类型定义、计算逻辑)在 VSCode 端和 Web 端是复制粘贴的,应该抽成 shared package 做 monorepo。

下一篇:02-智能回潮率检测仪系统

前端开发工程师 · 面试准备