Skip to content

小程序面试题

本题库共收录 55 道面试题(基础 12 / 进阶 20 / 深入 16 / 架构 7)。 本文件收录小程序相关面试题,目标题量 100 道。 题型覆盖:概念题、代码分析题、手写代码题、场景设计题、系统设计题、框架原理题、性能优化题、安全题、工程化题。 难度覆盖:基础、进阶、深入、架构。 每道题除标准参考答案外,另附口头回答版,便于面试时快速组织语言。

目录


基础题(8 道)

FB-45-CO-B-001:什么是小程序?它与 H5 / WebView 应用有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:45 小程序 标签:小程序、容器、架构、组件化 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请解释什么是小程序,并对比小程序与传统 H5 / WebView 应用在技术架构、运行环境、能力边界和分发方式上的主要区别。

参考答案

小程序是一种不需要下载安装即可使用的轻量级应用,运行在超级 App(微信、支付宝、抖音等)提供的宿主环境中。它通过离线包 + 双线程模型运行,既能获得接近原生的体验,又具备即用即走、社交分发、平台能力调用等优势。

与 H5 / WebView 应用的核心区别:

维度小程序H5 / WebView 应用
运行环境宿主 App 提供的独立渲染线程与逻辑线程浏览器内核或普通 WebView
包管理离线包,需上传、审核、下发在线加载,无需审核
能力边界受平台 SDK 限制,可调用原生能力受浏览器能力限制,部分能力需桥接
渲染方式自定义组件 + 原生视图混合渲染HTML + CSS + JS
开发框架WXML / WXSS / JS,或 Taro / UniApp 转译Vue / React / 原生 JS
分发方式扫码、搜索、分享、附近的小程序链接、二维码、浏览器
更新机制平台控制,支持热更新和灰度服务端控制,灵活但缺少平台约束

最佳实践:

  • 需要强平台能力、社交裂变、离线可用时优先考虑小程序。
  • 需要复杂动画、高频自定义交互时,可评估原生 App 或 Web 方案。

评分维度

  • 能说明小程序是运行在宿主 App 中的轻应用(30%)
  • 能从运行环境、包管理、能力边界等维度对比 H5(40%)
  • 能说出分发方式和更新机制的差异(30%)

常见错误

  • 认为小程序就是 H5 套壳,忽略双线程和离线包差异。
  • 混淆小程序与快应用、PWA 的区别。
  • 认为小程序可以任意调用所有系统能力。

延伸追问

  • 小程序和快应用有什么本质区别?
  • 为什么小程序不直接用浏览器内核渲染?

相关题目

参考资源

口头回答版

小程序是运行在超级 App 里的轻应用,不用下载安装,扫码或搜索就能打开。它和 H5 最大的区别是:小程序有独立的渲染线程和 JS 逻辑线程,用离线包运行;H5 是在浏览器或 WebView 里在线加载页面。小程序能更方便地调用微信、支付宝的平台能力,比如支付、扫码、分享,但能力受平台限制,更新也要走平台审核。


FB-45-CO-B-002:微信小程序的项目结构和主要文件类型有哪些?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:45 小程序 标签:小程序、工程化、组件化 出现频率:高频 预计回答时长:2-3 分钟

题目描述: 请说明微信小程序的标准项目结构,并解释 .json.wxml.wxss.js 四类文件的作用。

参考答案

微信小程序的标准目录结构如下:

text
project/
├── app.js              # 小程序逻辑入口
├── app.json            # 全局配置
├── app.wxss            # 全局样式
├── project.config.json # 项目配置
├── sitemap.json        # 搜索索引配置
├── pages/
│   ├── index/
│   │   ├── index.wxml  # 页面结构
│   │   ├── index.wxss  # 页面样式
│   │   ├── index.js    # 页面逻辑
│   │   └── index.json  # 页面配置
│   └── logs/
│       └── ...
├── components/
│   └── my-component/
│       ├── my-component.wxml
│       ├── my-component.wxss
│       ├── my-component.js
│       └── my-component.json
└── utils/
    └── util.js

四类核心文件:

文件类型作用类比
.wxml描述页面结构,使用小程序标签和 Mustache 语法HTML / 模板
.wxss描述页面样式,支持 rpx、部分 CSS 选择器CSS
.js页面或组件逻辑,包括 data、生命周期、事件处理JavaScript
.json页面或全局配置,如导航栏、窗口表现、使用组件配置文件

注意:

  • app.jsonpages 数组的第一项为首页。
  • 页面 .json 配置会覆盖 app.json 中的同名配置。
  • .wxss 不支持所有 CSS 特性,如部分伪类、属性选择器需谨慎使用。

评分维度

  • 能说出四类文件的作用(50%)
  • 能描述标准项目结构(30%)
  • 能说明 app.json 与页面 json 的覆盖关系(20%)

常见错误

  • .wxss 当成完全兼容 CSS 使用。
  • 忘记在页面 json 中注册自定义组件。
  • 在 app.json 中配错 pages 顺序导致首页不对。

延伸追问

  • sitemap.json 的作用是什么?
  • 全局样式和页面样式的优先级如何?

相关题目

参考资源

口头回答版

微信小程序主要由四类文件组成:wxml 是结构,相当于 HTML;wxss 是样式,相当于 CSS,但支持 rpx;js 是逻辑;json 是配置。全局有 app.js、app.json、app.wxss,页面一般在 pages 目录下,每个页面也各有这四个文件。app.json 里的 pages 第一项就是首页,页面 json 可以覆盖全局配置。


FB-45-CO-B-003:小程序的 MVVM 数据绑定原理是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:45 小程序 标签:小程序、数据绑定、响应式 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请解释小程序中数据绑定的基本用法,并说明其背后的 MVVM 实现原理。

参考答案

小程序采用类 MVVM 架构:视图层(View)和逻辑层(ViewModel)分离,开发者只需在逻辑层修改 data,框架会自动把变化同步到视图层。

基本用法:

xml
<!-- index.wxml -->
<view class="container">
  <text>&#123;&#123;message&#125;&#125;</text>
  <button bindtap="onTap">修改文案</button>
</view>
javascript
// index.js
Page({
  data: {
    message: 'Hello Mini Program',
  },
  onTap() {
    this.setData({
      message: 'Hello World',
    });
  },
});

实现原理:

  1. 数据劫持/观察:小程序逻辑层维护一份 data 对象,框架在初始化时对其做响应式处理。
  2. setData 驱动更新:开发者调用 this.setData(newData) 时,框架会计算差异(diff)。
  3. 跨线程通信:逻辑层通过 JSBridge 把 diff 数据序列化后发送到渲染线程。
  4. 视图更新:渲染线程根据 diff 数据更新虚拟 DOM 树,最终映射到原生视图。

注意:

  • 不要直接修改 this.data,应使用 this.setData
  • setData 有单次数据量和频率限制,频繁大量调用会影响性能。
  • 建议只 setData 必要字段,避免一次性更新整个对象。

评分维度

  • 能写出基本数据绑定示例(30%)
  • 能解释 View / ViewModel 分离和 setData 作用(40%)
  • 能说明数据通过 JSBridge 跨线程同步到视图(30%)

常见错误

  • 直接 this.data.xxx = yyy 后期待视图更新。
  • 在 setData 中一次性传入过大的数据对象。
  • 在循环中高频调用 setData。

延伸追问

  • setData 为什么不能直接修改深层对象?
  • 小程序数据绑定和 Vue 的响应式系统有什么异同?

相关题目

参考资源

口头回答版

小程序的数据绑定是 MVVM 模式,我们在 JS 里写 data,在 wxml 里用双花括号 绑定。要更新视图必须调用 this.setData,框架会算出差异,通过 JSBridge 把变化发给渲染线程,再更新到原生视图。不能直接改 this.data,那样视图不会更新。还要注意 setData 不要传太多数据,性能会有影响。


FB-45-CO-B-004:小程序页面生命周期有哪些?执行顺序是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:45 小程序 标签:小程序、生命周期、路由 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请列出微信小程序页面的主要生命周期函数,并说明它们的执行顺序和常见使用场景。

参考答案

微信小程序页面生命周期:

生命周期触发时机常见用途
onLoad页面加载时,只触发一次获取页面参数、初始化数据
onShow页面显示/切入前台时恢复状态、埋点上报
onReady页面初次渲染完成获取节点信息、操作 DOM
onHide页面隐藏/切入后台时暂停计时器、保存草稿
onUnload页面卸载时清理资源、取消订阅

执行顺序:

text
onLoad -> onShow -> onReady -> (onHide -> onShow 循环) -> onUnload

页面 A 跳转到页面 B 时的典型流程:

text
页面 A: onHide
页面 B: onLoad -> onShow -> onReady
返回页面 A:
  页面 B: onUnload
  页面 A: onShow

示例:

javascript
Page({
  onLoad(options) {
    console.log('页面参数:', options.id);
  },
  onShow() {
    this.reportPageView();
  },
  onReady() {
    const query = wx.createSelectorQuery();
    query.select('#box').boundingClientRect();
    query.exec(res => console.log(res));
  },
  onHide() {
    clearInterval(this.timer);
  },
  onUnload() {
    this.unsubscribe && this.unsubscribe();
  },
});

注意:

  • onLoad 中可获取打开页面时传入的参数。
  • onShow 会多次触发,不要在其中做一次性初始化。
  • onReady 后才能安全获取节点尺寸。

评分维度

  • 能列出 5 个主要生命周期(40%)
  • 能正确描述执行顺序(30%)
  • 能说明每个生命周期的典型用途(30%)

常见错误

  • onShow 中做只应执行一次的初始化。
  • onLoad 中访问 DOM 节点。
  • 忘记在 onUnloadonHide 中清理副作用。

延伸追问

  • 页面生命周期和 App 生命周期有什么关系?
  • 自定义组件的生命周期和页面生命周期如何配合?

相关题目

参考资源

口头回答版

小程序页面生命周期主要有 onLoad、onShow、onReady、onHide、onUnload。顺序是 onLoad 先执行,然后 onShow、onReady。页面隐藏时走 onHide,重新显示再走 onShow,卸载时走 onUnload。onLoad 一般拿页面参数和初始化,onShow 做恢复和埋点,onReady 后操作 DOM,onHide 和 onUnload 清理资源。


FB-45-CO-B-005:小程序路由跳转方式有哪些?各有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:45 小程序 标签:小程序、路由、生命周期 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请列举小程序中常用的页面跳转 API,并说明它们在页面栈行为、跳转方式、使用场景上的区别。

参考答案

微信小程序主要路由 API:

API作用页面栈行为使用场景
wx.navigateTo保留当前页,跳转到新页面新页面入栈普通页面跳转,可返回
wx.redirectTo关闭当前页,跳转到新页面当前页出栈,新页入栈登录后跳转首页,不需要返回
wx.reLaunch关闭所有页面,打开新页面清空栈,新页入栈切换 Tab、重启流程
wx.switchTab跳转到 TabBar 页面清空非 Tab 页面栈Tab 切换
wx.navigateBack返回上一级或多级页面出栈返回上一页

页面栈限制:

  • 小程序页面栈最多 10 层。
  • 超过 10 层后 navigateTo 会失败,应改用 redirectToreLaunch

示例:

javascript
// 普通跳转
wx.navigateTo({ url: '/pages/detail/detail?id=123' });

// 不需要返回的跳转
wx.redirectTo({ url: '/pages/home/home' });

// 返回上一页
wx.navigateBack({ delta: 1 });

// 切换到 Tab 页
wx.switchTab({ url: '/pages/index/index' });

带参数跳转:

  • URL 参数通过 onLoad(options) 接收。
  • 参数需 encode,复杂对象建议只传 id,到目标页再请求详情。

最佳实践:

  • 避免页面栈过深,必要时做栈管理。
  • Tab 页之间切换用 switchTab,不能用 navigateTo
  • 返回传参可通过全局状态、事件总线或页面实例方法。

评分维度

  • 能说出 5 种主要路由 API(40%)
  • 能说明页面栈行为和栈深度限制(30%)
  • 能给出不同场景的选择建议(30%)

常见错误

  • navigateTo 跳 TabBar 页面导致失败。
  • 页面栈超过 10 层后没有降级处理。
  • onLoad 外直接读取页面参数。

延伸追问

  • 返回上一页时如何传递数据?
  • 小程序页面栈和浏览器 History 有什么异同?

相关题目

参考资源

口头回答版

小程序主要有五种跳转方式:navigateTo 是保留当前页跳新页,普通场景最常用;redirectTo 是关闭当前页再跳,适合不需要返回的;reLaunch 是关掉所有页面重新打开;switchTab 是跳 TabBar 页;navigateBack 是返回。页面栈最多 10 层,超过要用 redirectTo。跳 Tab 必须用 switchTab,用 navigateTo 会失败。


FB-45-CO-B-006:小程序自定义组件的基本结构和生命周期是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:45 小程序 标签:小程序、组件化、生命周期 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请说明微信小程序自定义组件的目录结构、四个核心文件,以及组件生命周期的执行顺序。

参考答案

自定义组件目录结构:

text
components/
└── my-component/
    ├── my-component.js   # 组件逻辑
    ├── my-component.json # 组件配置
    ├── my-component.wxml # 组件模板
    └── my-component.wxss # 组件样式

组件 json 配置:

json
{
  "component": true,
  "usingComponents": {}
}

页面或父组件中注册使用:

json
{
  "usingComponents": {
    "my-component": "/components/my-component/my-component"
  }
}

组件核心生命周期:

生命周期触发时机用途
created组件实例刚创建不应用 setData,适合初始化纯数据
attached组件挂载到页面节点树可访问 this.data,适合发起请求
ready组件布局完成可获取节点信息
moved组件移动到另一节点较少使用
detached组件被移除清理副作用
error组件方法抛出错误错误处理

执行顺序:

text
created -> attached -> ready -> (moved) -> detached

组件定义示例:

javascript
Component({
  properties: {
    title: {
      type: String,
      value: '默认标题',
    },
  },
  data: {
    count: 0,
  },
  lifetimes: {
    attached() {
      console.log('组件挂载', this.properties.title);
    },
    detached() {
      console.log('组件卸载');
    },
  },
  methods: {
    onTap() {
      this.setData({ count: this.data.count + 1 });
      this.triggerEvent('change', { count: this.data.count });
    },
  },
});

注意:

  • 组件 dataproperties 都可以用于模板渲染,properties 由外部传入。
  • 组件样式默认隔离,可通过 options.addGlobalClassexternalClasses 做样式穿透。

评分维度

  • 能说出自定义组件四个文件和 json 配置(30%)
  • 能列出主要生命周期及顺序(40%)
  • 能区分 properties 和 data,并写出基本组件(30%)

常见错误

  • 忘记在组件 json 中声明 "component": true
  • created 中调用 setData
  • 混淆页面生命周期和组件生命周期。

延伸追问

  • 组件样式隔离是如何实现的?
  • 父组件如何监听子组件事件?

相关题目

参考资源

口头回答版

小程序自定义组件和页面一样,也有 js、json、wxml、wxss 四个文件,但 json 里要声明 component: true。生命周期有 created、attached、ready、detached,顺序是 created 先,attached 挂载,ready 布局完成,detached 卸载。外部传数据用 properties,内部状态用 data,组件样式默认是隔离的。


FB-45-CO-B-007:小程序中 rpx 是什么?与 px / rem 有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:45 小程序 标签:小程序、响应式、数据绑定 出现频率:中频 预计回答时长:2-3 分钟

题目描述: 请解释小程序中 rpx 的作用,并对比 rpx、px 和 rem 在小程序中的使用差异。

参考答案

rpx(responsive pixel)是小程序定义的响应式长度单位。它以 750rpx 为屏幕总宽度进行等比缩放,开发者可以用固定数值适配不同屏幕宽度。

换算规则:

text
1rpx = 屏幕宽度 / 750 px

例如:

  • iPhone 6 屏幕宽度 375px,则 1rpx = 0.5px,750rpx = 375px。
  • iPhone 6 Plus 屏幕宽度 414px,则 1rpx ≈ 0.552px,750rpx = 414px。

三者对比:

单位含义小程序支持使用建议
px物理像素或 CSS 像素支持边框、阴影等固定尺寸可用
rpx响应式像素,按 750 宽度缩放支持布局、宽高、间距首选
rem相对根元素字体大小不支持小程序无根字体概念,不可用

示例:

css
/* 设计稿宽度 750px,直接使用 rpx */
.container {
  width: 750rpx;
  padding: 20rpx;
}

/* 1px 边框建议用 px,避免 rpx 换算出现小数 */
.border {
  border-bottom: 1px solid #eee;
}

最佳实践:

  • 布局尺寸优先使用 rpx。
  • 边框、细线等可用 px 避免模糊。
  • 字体大小通常也使用 rpx 或 px,视设计规范而定。

评分维度

  • 能说明 rpx 的换算规则(40%)
  • 能对比 rpx、px、rem(40%)
  • 能给出使用建议(20%)

常见错误

  • 认为 rpx 完全等价于 px。
  • 在所有场景都使用 rpx,导致 1px 边框变模糊。
  • 试图在小程序中使用 rem / vw / vh。

延伸追问

  • 小程序如何实现横屏适配?
  • 如果设计稿是 375px,应该如何使用 rpx?

相关题目

参考资源

口头回答版

rpx 是小程序的响应式单位,规定屏幕宽度就是 750rpx,所以写一个固定数值可以自动适配不同屏幕。比如 iPhone 6 宽 375px,1rpx 就是 0.5px。px 是绝对单位,小程序里也支持;rem 不支持。布局、宽高、间距一般用 rpx,1px 边框建议用 px,避免 rpx 换算后变模糊。


FB-45-CO-B-008:小程序用户登录和获取用户信息的流程是怎样的?

题型:概念题 难度:🟢 基础 岗位层级:初级 / 高级 面试知识域:45 小程序 标签:小程序、权限、安全 出现频率:高频 预计回答时长:3-5 分钟

题目描述: 请描述小程序中获取用户登录态和用户信息的标准流程,并说明 wx.loginwx.getUserProfile / wx.getUserInfo、服务端 session 的关系。

参考答案

小程序登录流程基于 OAuth2 风格的 Code 换 Token 机制,核心步骤如下:

text
1. 小程序前端调用 wx.login() 获取临时登录凭证 code
2. 前端把 code 发送给业务服务端
3. 服务端用 code + appid + secret 请求微信 auth.code2Session 接口
4. 微信返回 openid、unionid(如有)、session_key
5. 服务端生成自定义登录态(如 token / session)并返回给前端
6. 前端保存 token,后续请求携带 token 进行身份识别

获取用户信息:

  • wx.getUserProfile:微信推荐的方式,每次调用都会弹窗授权,可获取加密数据。
  • wx.getUserInfo:旧接口,已不再推荐,基础库 2.27.1 起默认返回匿名数据。
  • button open-type="chooseAvatar" / "getPhoneNumber":获取头像、手机号等敏感信息。

代码示例:

javascript
// 登录
async function login() {
  const { code } = await wx.login();
  const res = await request('/api/login', { code });
  wx.setStorageSync('token', res.token);
}

// 获取用户信息
wx.getUserProfile({
  desc: '用于完善会员资料',
  success(res) {
    console.log(res.userInfo);
    // 如需手机号,需用 button 触发 getPhoneNumber
  },
});

安全注意:

  • session_key 必须保存在服务端,不能返回前端。
  • 用户敏感数据(如手机号)需用 session_key 解密。
  • 建议对登录接口做频率限制和风控校验。

评分维度

  • 能描述 code -> session -> token 的登录流程(40%)
  • 能区分 wx.login 和 getUserProfile / getUserInfo(30%)
  • 能说明 session_key 的安全存储要求(30%)

常见错误

  • 认为 wx.login 直接返回 openid。
  • session_key 存在前端。
  • 用旧版 getUserInfo 获取用户信息,不符合平台新规。

延伸追问

  • 如何实现登录态的无感刷新?
  • 多账号体系下 unionid 和 openid 怎么使用?

相关题目

参考资源

口头回答版

小程序登录是前端调 wx.login 拿到一个临时 code,把 code 发给服务端,服务端用 code 去微信接口换 openid 和 session_key,然后生成自己的 token 返回给前端。前端保存 token,后面请求都带上。用户信息用 getUserProfile,会弹窗授权。session_key 必须放服务端,不能给前端,敏感数据要靠它解密。


进阶题(8 道)

FB-45-CO-A-001:小程序的双线程模型是什么?为什么采用这种架构?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、容器、架构、数据绑定 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请详细解释小程序的双线程模型,包括渲染线程和逻辑线程的职责、通信方式,以及这种架构设计的优缺点。

参考答案

小程序采用双线程架构:逻辑层(Logic Layer)和渲染层(Render Layer)分别运行在不同线程中,彼此隔离,通过 JSBridge 进行异步通信。

架构示意:

text
+---------------------+         +---------------------+
|     渲染层           |         |      逻辑层          |
|  (WebView / 原生视图) |         |    (JSCore / V8)     |
|                     |         |                     |
|  WXML / WXSS 渲染    |         |  JS 业务逻辑         |
|  原生组件同层渲染     |         |  setData / 生命周期  |
|                     |         |                     |
+----------+----------+         +----------+----------+
           |                              |
           +----------- JSBridge ---------+

职责划分:

线程运行环境职责
渲染层WebView解析 WXML/WXSS,构建 DOM 树,响应用户事件
逻辑层JSCore / V8执行 JS,管理数据、生命周期、平台 API 调用

通信机制:

  • 逻辑层通过 setData 把数据 diff 发送到渲染层。
  • 渲染层通过事件系统把用户交互传递到逻辑层。
  • 通信是异步、序列化的,数据需经过 JSON 化。

采用双线程的原因:

  1. 安全隔离:JS 逻辑无法直接操作 DOM,避免 XSS、恶意脚本破坏页面。
  2. 可控性:平台可以限制和管控逻辑层能力,统一审核和灰度。
  3. 稳定性:逻辑错误不会直接导致渲染层崩溃。
  4. 原生能力统一调度:平台 API 由逻辑层统一转发到客户端原生能力。

缺点:

  • setData 频繁调用或数据量过大时会产生性能瓶颈。
  • 跨线程通信有延迟,不适合高频实时交互。
  • 开发者无法直接操作 DOM,灵活性受限。

最佳实践:

  • 减少 setData 调用次数,合并字段更新。
  • 避免一次性 setData 大量列表数据,使用分页或虚拟列表。
  • 复杂动画优先使用 CSS 动画或原生组件,而非 JS 逐帧驱动。

评分维度

  • 能说明双线程分别是渲染层和逻辑层(30%)
  • 能解释 JSBridge 通信和 setData 机制(30%)
  • 能分析双线程架构的安全、性能优缺点(40%)

常见错误

  • 认为小程序和 H5 一样运行在同一个 WebView 线程。
  • 忽略跨线程通信带来的性能开销。
  • 认为逻辑层可以直接操作 DOM。

延伸追问

  • 双线程模型下如何实现原生组件同层渲染?
  • setData 的数据量上限是多少?如何规避?

相关题目

参考资源

口头回答版

小程序是双线程模型,渲染层跑在 WebView 里负责界面,逻辑层跑在 JSCore 或 V8 里负责 JS 逻辑。两边通过 JSBridge 异步通信。逻辑层调用 setData,会把数据 diff 传给渲染层更新视图;用户点击等事件则从渲染层传回逻辑层。这样设计主要是为了安全和可控,JS 不能直接操作 DOM,平台也更好管控。缺点是跨线程通信有开销,setData 太频繁或数据量太大会卡。


FB-45-CO-A-002:JSBridge 在小程序中如何工作?有哪些通信方式?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、容器、架构、数据绑定 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释 JSBridge 在小程序中的作用、常见实现方式,并说明逻辑层与原生能力之间是如何通过 JSBridge 交互的。

参考答案

JSBridge 是连接 JavaScript 运行环境与客户端原生能力的桥梁。在小程序中,它负责连接逻辑层 JS 与宿主 App 的原生能力(如扫码、支付、定位、蓝牙等),同时也负责逻辑层与渲染层之间的通信。

JSBridge 主要通信场景:

  1. JS 调用原生能力:如 wx.scanCodewx.requestPayment
  2. 原生能力回调 JS:如扫码结果、定位结果、网络状态变化。
  3. 逻辑层与渲染层通信:如 setData、事件分发。

常见实现方式:

方式原理特点
URL SchemeJS 通过修改 iframe.srclocation.href 携带协议,客户端拦截并解析兼容性好,但有长度限制
注入全局对象客户端在 JS 上下文中注入 wx / my / tt 等对象调用方便,性能较好
原生方法注入客户端把原生方法绑定到 JS 对象上,JS 直接调用适合同步调用
消息队列JS 把调用信息放入队列,客户端定时轮询或主动拉取适合大量异步调用

微信小程序调用示意:

javascript
// JS 调用原生扫码能力
wx.scanCode({
  success(res) {
    console.log(res.result);
  },
  fail(err) {
    console.error(err);
  },
});

内部流程:

text
1. JS 调用 wx.scanCode(options)
2. JSBridge 把方法名和参数序列化
3. 通过 JSCore / WebView 桥接协议发送到客户端
4. 客户端调用原生扫码 SDK
5. 扫码完成后,客户端把结果通过 JSBridge 回调给 JS
6. JS 执行 success / fail / complete 回调

通信特点:

  • 异步为主,部分能力支持同步调用(如 wx.getSystemInfoSync)。
  • 参数和结果都需 JSON 序列化,复杂对象可能丢失类型信息。
  • 调用有频率和并发限制,过度调用会影响性能。

最佳实践:

  • 调用原生能力前先做能力检测和版本兼容。
  • 避免在循环中高频调用 JSBridge 接口。
  • 对异步调用结果做超时和错误兜底。

评分维度

  • 能说明 JSBridge 连接 JS 与原生能力的作用(30%)
  • 能列举至少 3 种实现方式(30%)
  • 能描述一次完整调用流程并指出异步特性(40%)

常见错误

  • 认为 JSBridge 只在小程序中使用,忽略 H5 hybrid 场景也有。
  • 认为所有 JSBridge 调用都是同步的。
  • 忽略版本兼容性,直接调用高版本 API。

延伸追问

  • 小程序中 setData 为什么不走同步 JSBridge?
  • 如何实现自定义 JSBridge 扩展宿主能力?

相关题目

参考资源

口头回答版

JSBridge 就是小程序里 JS 和原生能力之间的桥梁。我们调用 wx.scanCode、wx.request 这些 API,背后都是通过 JSBridge 把消息发给宿主 App 的原生层,原生层执行完再把结果回调给 JS。实现方式有 URL Scheme、注入全局对象、消息队列等。小程序里大多是异步调用,参数要序列化,调用太频繁会有性能问题。


FB-45-CO-A-003:微信、支付宝、抖音、百度小程序的架构有什么异同?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、容器、架构、组件化 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请对比微信小程序、支付宝小程序、抖音小程序、百度小程序在运行架构、组件规范、API 命名、生态能力等方面的异同。

参考答案

四大主流小程序平台都基于"离线包 + 双线程 + JSBridge"思想,但在技术细节、组件规范和生态能力上存在差异。

架构对比:

维度微信小程序支付宝小程序抖音小程序百度小程序
渲染层WebView + 原生组件同层UC WebView + 原生WebViewWebView
逻辑层JSCore / V8V8V8V8
组件规范WXML / WXSSAXML / ACSSTTML / TTSSSWAN / CSS
全局对象wxmyttswan
包体积限制主包 2MB,总包 20MB主包 2MB主包 2MB主包 2MB
分包加载支持支持支持支持
核心优势社交生态、支付金融、生活服内容、短视频搜索、信息流

共性:

  1. 双线程模型:渲染与逻辑分离。
  2. 离线包机制:代码包下载后本地运行。
  3. 平台审核与灰度:上线需审核,支持热更新。
  4. 原生能力调用:扫码、支付、定位、分享等。
  5. 自定义组件:支持组件化开发。

差异:

  • 微信小程序:生态最成熟,组件和 API 最丰富,社交裂变能力最强。
  • 支付宝小程序:强金融属性,会员、卡包、信用能力突出。
  • 抖音小程序:内容分发能力强,短视频挂载和直播场景多。
  • 百度小程序:搜索入口强,信息流推荐和自然流量获取有优势。

跨端框架:

  • Taro、UniApp 等框架通过编译时/运行时抹平差异,一份代码输出多端产物。
  • 但平台特有 API 和组件仍需条件编译或运行时适配。

评分维度

  • 能说明四大平台都基于双线程 + 离线包架构(30%)
  • 能对比渲染/逻辑层、组件规范、全局对象差异(40%)
  • 能分析各平台生态能力差异(30%)

常见错误

  • 认为所有小程序完全等价,可以零成本迁移。
  • 忽略各平台审核规范和开放能力的差异。
  • 认为跨端框架能 100% 抹平平台差异。

延伸追问

  • Taro 和 UniApp 是如何实现跨端编译的?
  • 如果某平台不支持某个组件,跨端框架会如何处理?

相关题目

参考资源

口头回答版

微信、支付宝、抖音、百度小程序底层都是双线程加离线包,但各自组件语法和全局对象不同:微信是 WXML/WXSS 和 wx,支付宝是 AXML/ACSS 和 my,抖音是 TTML/TTSS 和 tt,百度是 SWAN 和 swan。生态上微信社交强,支付宝金融强,抖音内容分发强,百度搜索入口强。跨端框架像 Taro、UniApp 能一套代码转多端,但平台特有 API 还是要做适配。


FB-45-PE-A-004:小程序分包加载的原理是什么?如何配置?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、性能优化、工程化 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释小程序分包加载的原理,说明普通分包和独立分包的区别,并给出配置示例。

参考答案

小程序分包加载是为了解决主包体积限制和首屏启动速度问题。启动时只下载主包,用户进入分包页面时再按需下载对应分包。

分包类型:

类型特点使用场景
普通分包依赖主包运行,按需下载按业务模块拆分
独立分包不依赖主包即可启动活动页、广告投放页
分包预下载进入某页面时预加载其他分包预测用户下一步路径

配置示例:

json
// app.json
{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "subPackages": [
    {
      "root": "packageA",
      "pages": [
        "pages/cat",
        "pages/dog"
      ]
    },
    {
      "root": "packageB",
      "pages": [
        "pages/apple",
        "pages/banana"
      ],
      "independent": true
    }
  ],
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["packageA"]
    }
  }
}

分包加载流程:

text
1. 用户打开小程序,下载主包
2. 进入分包页面时,判断分包是否已下载
3. 未下载则异步下载分包,下载完成后执行页面逻辑
4. 独立分包可直接启动,不下载主包
5. 预下载规则可在用户进入某页面时提前加载指定分包

分包限制(以微信为例):

  • 主包体积不超过 2MB。
  • 整个小程序所有分包合计不超过 20MB。
  • 单个分包/独立分包不超过 2MB。

最佳实践:

  • 按业务域拆分分包,如首页、商城、个人中心各自成包。
  • 独立分包适合广告投放、分享入口等活动页。
  • 利用分包预下载优化二级页面打开速度。
  • 公共模块抽到主包,避免分包重复打包。

评分维度

  • 能解释分包加载按需下载的原理(30%)
  • 能区分普通分包、独立分包、分包预下载(30%)
  • 能写出 app.json 分包配置(20%)
  • 能说明体积限制和拆分原则(20%)

常见错误

  • 把主包页面放到 subPackages 中。
  • 独立分包引用了主包资源导致启动失败。
  • 公共代码没有抽到主包,导致多个分包重复。

延伸追问

  • 分包和主包之间如何共享组件和工具函数?
  • 分包加载失败如何降级处理?

相关题目

参考资源

口头回答版

小程序分包是为了控制主包体积和加快启动。启动时只下主包,用户进分包页面时再按需下载。分包分普通分包和独立分包,普通分包依赖主包,独立分包可以不依赖主包直接启动。还有分包预下载,能在用户进某个页面时提前加载下一个分包。主包一般 2MB 上限,总分包 20MB。配置时在 app.json 里写 subPackages,还可以配 preloadRule 做预下载。


FB-45-PE-A-005:小程序性能优化有哪些常用手段?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、性能优化、生命周期 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请列举小程序性能优化的常见手段,涵盖启动、渲染、网络、包体积等方面。

参考答案

小程序性能优化可从启动、渲染、网络、包体积、运行时五个维度入手。

一、启动优化:

  • 控制主包体积,优先使用分包。
  • 减少 app.js / 首页 onLoad 中的同步初始化。
  • 延迟加载非必要 SDK、插件和统计脚本。
  • 利用独立分包投放活动页,缩短广告落地页路径。

二、渲染优化:

  • 减少 setData 调用次数,合并字段更新。
  • setData 只传必要字段,避免更新整个对象或长列表。
  • 长列表使用虚拟列表或分页加载,避免一次性渲染大量节点。
  • 复杂动画优先使用 CSS 动画或原生组件(如 swipervideo)。

三、网络优化:

  • 合并请求,避免并发过多。
  • 图片使用 CDN 压缩、懒加载、占位图。
  • 合理使用缓存(storage、内存缓存)。
  • 接口失败重试和超时兜底。

四、包体积优化:

  • 删除未引用代码和图片资源。
  • 使用 Terser 压缩、Tree Shaking。
  • 大型依赖按分包或按需加载。
  • 图标用字体图标或 SVG 替代 PNG。

五、运行时优化:

  • 避免内存泄漏:页面卸载时清理定时器、事件监听。
  • 页面隐藏时暂停不必要的任务。
  • 使用 wx.nextTick 合并 DOM 操作。

示例:合并 setData:

javascript
// 不推荐:多次 setData
this.setData({ a: 1 });
this.setData({ b: 2 });

// 推荐:合并为一次
this.setData({ a: 1, b: 2 });

最佳实践:

  • 使用小程序开发者工具的"性能面板"和"Audits"定期检测。
  • 建立包体积门禁,防止大文件合入。
  • 对关键页面做首屏时间监控。

评分维度

  • 能从启动、渲染、网络、包体积、运行时五个维度展开(40%)
  • 能重点说明 setData 优化和长列表处理(30%)
  • 能给出具体代码示例和监控建议(30%)

常见错误

  • 只关注包体积,忽略 setData 和渲染性能。
  • 在 onLoad 中同步阻塞初始化大量逻辑。
  • 长列表一次性 setData 上千条数据。

延伸追问

  • 如何检测小程序首屏时间?
  • setData 数据量超过限制时怎么处理?

相关题目

参考资源

口头回答版

小程序性能优化可以从五个方面说:启动上控制主包体积、用分包、延迟加载 SDK;渲染上减少 setData 次数,只更新必要字段,长列表做虚拟列表或分页;网络上合并请求、图片懒加载、接口缓存;包体积上删无用资源、压缩、Tree Shaking;运行时上注意内存泄漏,页面卸载清理定时器。最核心的是 setData 要合并、要克制,不要一次传太多数据。


FB-45-CO-A-006:小程序自定义组件间的数据传递和事件通信方式有哪些?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、组件化、数据绑定、生命周期 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明小程序中父子组件、兄弟组件、跨层级组件之间进行数据传递和事件通信的方式,并给出示例。

参考答案

小程序组件通信方式:

场景方式说明
父传子properties通过属性向下传递数据
子传父triggerEvent子组件触发事件,父组件监听
兄弟组件父组件中转 / 全局状态通过共同父组件或状态管理
跨层级relations / 全局状态父子关系组件用 relations,复杂场景用状态管理
全局通信globalData / storage / 状态库跨页面或深层组件共享数据

父传子示例:

xml
<!-- parent.wxml -->
<my-component title="&#123;&#123;pageTitle&#125;&#125;" count="&#123;&#123;3&#125;&#125;" />
javascript
// my-component.js
Component({
  properties: {
    title: String,
    count: {
      type: Number,
      value: 0,
    },
  },
});

子传父示例:

xml
<!-- my-component.wxml -->
<button bindtap="handleTap">点击</button>
javascript
// my-component.js
Component({
  methods: {
    handleTap() {
      this.triggerEvent('onTap', { msg: 'hello' }, { bubbles: false });
    },
  },
});
xml
<!-- parent.wxml -->
<my-component bind:onTap="onChildTap" />
javascript
// parent.js
Page({
  onChildTap(e) {
    console.log(e.detail.msg);
  },
});

跨层级 relations 示例:

javascript
// parent.js
Component({
  relations: {
    './child.js': {
      type: 'child',
      linked(target) {
        this.children = this.children || [];
        this.children.push(target);
      },
    },
  },
  methods: {
    broadcast(msg) {
      this.children.forEach(child => child.receive(msg));
    },
  },
});

最佳实践:

  • 优先使用 properties + triggerEvent 做父子通信。
  • 兄弟组件避免直接通信,应通过父组件或状态管理中转。
  • 跨多层级且数据复杂时,使用 MobX、GlobalData 或自定义状态库。

评分维度

  • 能说明父子组件 properties / triggerEvent 通信(40%)
  • 能说明兄弟和跨层级通信方案(30%)
  • 能写出基本通信代码示例(30%)

常见错误

  • 子组件直接修改 properties。
  • 事件名写错或大小写不匹配。
  • 滥用全局状态管理简单父子通信。

延伸追问

  • triggerEvent 的 bubbles 和 composed 有什么区别?
  • relations 适合什么场景?有什么限制?

相关题目

参考资源

口头回答版

小程序组件通信和 Vue、React 类似:父传子用 properties,子传父用 triggerEvent 触发事件。兄弟组件可以通过共同父组件中转,或者用全局状态。跨层级复杂场景可以用 relations 定义父子关系,也可以用 MobX、globalData 这些状态管理。最常用还是 properties 加 triggerEvent,不要乱用全局状态。


FB-45-SE-A-007:小程序的权限管理和用户授权如何处理?

题型:安全题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、权限、安全 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明小程序中用户授权的机制,包括权限类型、授权流程、最佳实践,以及如何处理用户拒绝授权的情况。

参考答案

小程序权限分为普通权限和敏感权限。普通权限无需用户授权即可调用;敏感权限需要用户主动授权,部分还需通过按钮组件触发。

常见权限分类:

类型示例授权方式
普通权限网络请求、获取系统信息无需授权
一次性敏感权限获取手机号、选择头像必须由 button 组件触发
持久性敏感权限地理位置、相册、摄像头弹窗授权,可后续在设置页管理
后台权限后台定位、蓝牙需在 app.json 声明并引导用户开启

授权流程:

text
1. 调用 wx.authorize 或相关 API
2. 如果用户未授权,弹出授权弹窗
3. 用户同意后获得权限
4. 用户拒绝后,后续调用直接失败
5. 可引导用户到设置页重新开启权限

地理位置授权示例:

javascript
wx.getLocation({
  type: 'wgs84',
  success(res) {
    console.log(res.latitude, res.longitude);
  },
  fail(err) {
    if (err.errMsg.includes('auth deny')) {
      wx.showModal({
        title: '需要位置权限',
        content: '请前往设置开启位置权限',
        success(r) {
          if (r.confirm) {
            wx.openSetting();
          }
        },
      });
    }
  },
});

手机号授权示例:

xml
<button open-type="getPhoneNumber" bind:getphonenumber="getPhoneNumber">获取手机号</button>
javascript
Page({
  getPhoneNumber(e) {
    if (e.detail.errMsg === 'getPhoneNumber:ok') {
      // 把 encryptedData、iv 发给服务端解密
      wx.request({
        url: '/api/decrypt-phone',
        data: {
          encryptedData: e.detail.encryptedData,
          iv: e.detail.iv,
        },
      });
    }
  },
});

最佳实践:

  • 只在必要时请求权限,并提前说明用途。
  • 用户拒绝后不要反复弹窗,提供手动开启入口。
  • 敏感数据(如手机号)必须服务端解密,前端不保存。
  • app.json 中声明需要的权限(如 permissionrequiredPrivateInfos)。

评分维度

  • 能区分普通权限和敏感权限(30%)
  • 能描述授权流程和拒绝后处理(30%)
  • 能写出地理位置或手机号授权示例(40%)

常见错误

  • 未授权就调用敏感 API 导致功能异常。
  • 用户拒绝后没有引导入口。
  • 前端直接解密敏感数据。

延伸追问

  • 用户关闭授权弹窗后再次进入,如何判断授权状态?
  • 小程序隐私协议如何配置?

相关题目

参考资源

口头回答版

小程序权限分普通权限和敏感权限。普通权限比如网络请求不用授权;敏感权限比如位置、相册、摄像头要弹窗授权,手机号、头像这种必须由 button 触发。用户拒绝后不能反复弹窗,要引导他去设置页手动开。调用 wx.getLocation 失败时判断是不是 auth deny,然后用 wx.openSetting 引导。手机号授权拿到 encryptedData 和 iv 后要发给服务端解密,前端不能自己解密。


FB-45-CO-A-008:小程序的版本更新机制是怎样的?如何做到强制更新?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:45 小程序 标签:小程序、生命周期、工程化 出现频率:中频 预计回答时长:3-5 分钟

题目描述: 请说明小程序的版本更新机制,包括静默更新、启动时更新、强制更新的实现方式,以及开发中如何调试新版本。

参考答案

小程序的版本更新由平台控制,分为以下几种情况:

更新类型触发时机特点
冷启动更新用户完全退出后重新打开平台自动下载最新版本
热启动更新从后台切回前台有一定时间间隔才会检查更新
开发版 / 体验版开发者或体验者扫码打开直接加载最新预览版本

微信提供了 wx.getUpdateManager API 让开发者感知更新:

javascript
const updateManager = wx.getUpdateManager();

updateManager.onCheckForUpdate(res => {
  console.log('是否有新版本:', res.hasUpdate);
});

updateManager.onUpdateReady(() => {
  wx.showModal({
    title: '更新提示',
    content: '新版本已准备好,是否重启应用?',
    success(res) {
      if (res.confirm) {
        updateManager.applyUpdate();
      }
    },
  });
});

updateManager.onUpdateFailed(() => {
  wx.showModal({
    title: '更新失败',
    content: '新版本下载失败,请检查网络后重试',
  });
});

强制更新策略:

  • 服务端维护最低可用版本号。
  • 启动时调用接口获取当前最新版本和最低版本。
  • 如果本地版本低于最低版本,调用 applyUpdate 强制重启或引导用户。
  • 对于关键业务修复,可在页面内弹窗拦截,提示必须更新。

调试新版本:

  • 开发工具中开启"上传代码时自动更新"或手动清缓存。
  • 真机预览使用"开发版"或"体验版"。
  • 线上版本可通过"小程序助手"查看版本号。

评分维度

  • 能说明冷启动、热启动更新机制(30%)
  • 能使用 wx.getUpdateManager 写出更新监听代码(40%)
  • 能说明强制更新和调试方法(30%)

常见错误

  • 认为小程序会实时自动更新到最新版。
  • 忽略用户拒绝重启导致旧版本继续运行。
  • 没有在更新失败时做兜底提示。

延伸追问

  • 如果用户一直不更新,如何兼容旧版本接口?
  • 小程序版本号和业务版本号如何统一管理?

相关题目

参考资源

口头回答版

小程序更新是平台控制的。冷启动时会自动下新版,热启动时过段时间才会检查。开发者可以用 wx.getUpdateManager 监听更新,onUpdateReady 时弹窗让用户重启,applyUpdate 是强制应用新版。如果要更强制,可以让服务端配一个最低版本,启动时比版本号,低于就强制更新。调试新版本用开发版、体验版,或者清缓存。


深入题(7 道)

FB-45-FS-P-001:小程序 Exparser 组件框架和虚拟 DOM 渲染原理是什么?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、组件化、容器、架构 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请深入分析微信小程序的 Exparser 组件框架,以及小程序从 WXML 到原生视图的渲染流程。

参考答案

Exparser 是微信小程序的组件组织框架,负责管理自定义组件的生命周期、属性、事件、模板解析和 Shadow Tree 构建。它在概念上类似 Web Components,但底层实现针对小程序双线程架构做了大量定制。

核心能力:

  1. 组件注册与实例化:解析组件定义,管理 properties、data、methods、lifetimes。
  2. Shadow Tree 构建:每个组件有独立的 Shadow Tree,与页面节点树组合成完整渲染树。
  3. 模板解析:把 WXML 编译为可执行的渲染函数。
  4. 数据响应与 diff:监听 setData,生成最小差异集。
  5. 事件系统:封装触摸、点击等事件,跨线程派发到逻辑层。

渲染流程:

text
1. 开发者编写 WXML / WXSS / JS
2. 编译阶段:WXML 被编译为渲染函数,WXSS 解析为样式规则
3. 运行阶段:逻辑层初始化 data,构建组件实例树
4. setData 触发:逻辑层 diff 数据,生成 patch
5. JSBridge 传输:patch 序列化后发送到渲染层
6. 渲染层应用 patch,更新虚拟 DOM / Shadow Tree
7. 渲染层把节点映射为原生视图(WebView DOM + 原生组件同层)

关键概念:

  • Virtual DOM 差异更新:小程序并非完全复用 React / Vue 的 VDOM,而是基于 Shadow Tree 做增量更新。
  • Shadow Tree:组件内部节点树,与 Composed Tree 组合后形成最终渲染树。
  • 原生组件同层渲染:部分组件(如 video、map、canvas)通过原生视图直接渲染,插入到 WebView 的同一层级。

示例:setData 的 diff 与更新

javascript
Page({
  data: {
    list: [{ id: 1, name: 'A' }, { id: 2, name: 'B' }],
  },
  updateName() {
    // 框架只把 list[1].name 的变化发送到渲染层
    this.setData({
      'list[1].name': 'C',
    });
  },
});

最佳实践:

  • 避免过深的组件嵌套,减少 Shadow Tree 构建开销。
  • 列表渲染使用稳定 key,帮助框架做节点复用。
  • 减少不必要的 setData,避免跨线程通信压力。

评分维度

  • 能说明 Exparser 管理组件生命周期和 Shadow Tree(30%)
  • 能描述从 WXML 到原生视图的完整渲染流程(40%)
  • 能解释同层渲染和数据 diff 机制(30%)

常见错误

  • 认为小程序完全使用浏览器原生 DOM。
  • 把小程序 VDOM 和 React VDOM 完全等同。
  • 忽略 Shadow Tree 与页面节点树的组合关系。

延伸追问

  • 同层渲染解决了什么问题?又有哪些限制?
  • 为什么小程序不使用真实 DOM 操作?

相关题目

参考资源

口头回答版

Exparser 是微信小程序的组件框架,负责组件的注册、生命周期、属性、事件和模板解析。每个组件有自己的 Shadow Tree,组合起来形成页面渲染树。WXML 会被编译成渲染函数,运行时在逻辑层初始化数据。setData 后框架会做 diff,把最小变化通过 JSBridge 发给渲染层,渲染层更新 Shadow Tree,再映射到原生视图。像 video、map 这些原生组件是同层渲染的,直接插到 WebView 里。


FB-45-PE-P-002:小程序启动性能优化和白屏优化有哪些方案?

题型:性能优化题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、性能优化、生命周期 出现频率:高频 预计回答时长:8-15 分钟

题目描述: 请从启动流程分析小程序首屏和白屏产生的原因,并给出系统性的优化方案。

参考答案

小程序启动流程:

text
1. 用户点击图标或扫码
2. 宿主 App 加载小程序运行时
3. 下载或校验主包资源
4. 初始化逻辑层(app.js)
5. 渲染首页(page onLoad -> onShow -> onReady)
6. 发起首页数据请求
7. 请求返回后 setData 更新视图

白屏原因:

  • 主包过大导致下载和解析慢。
  • app.js 同步初始化阻塞。
  • 首页接口慢或串行请求多。
  • 首屏数据量大,setData 慢。
  • 模板复杂、节点多,渲染慢。

优化方案:

一、包层面:

  • 控制主包 2MB 以内,非核心页面放入分包。
  • 使用独立分包作为广告和活动落地页。
  • 删除冗余资源、未使用组件和图片。

二、代码层面:

  • 把非必要初始化逻辑延迟到首页加载后或异步执行。
  • 首页 onLoad 中并行发起多个独立请求。
  • 使用骨架屏或默认数据占位,减少白屏时间。
  • 对首屏非关键资源做懒加载。

三、数据层面:

  • 首页接口做缓存优先策略,先展示缓存再刷新。
  • 接口返回数据做精简,只渲染首屏必要字段。
  • 分页加载长列表,避免一次性 setData 大量数据。

四、渲染层面:

  • 首屏模板节点控制在合理范围,避免过深嵌套。
  • 使用 CSS 动画替代 JS 动画。
  • 对复杂区域使用原生组件或 cover-view。

骨架屏示例:

xml
<!-- index.wxml -->
<view wx:if="&#123;&#123;loading&#125;&#125;" class="skeleton">
  <view class="skeleton-title"></view>
  <view class="skeleton-item" wx:for="&#123;&#123;5&#125;&#125;"></view>
</view>

<view wx:else class="content">
  <view wx:for="&#123;&#123;list&#125;&#125;">&#123;&#123;item.name&#125;&#125;</view>
</view>
javascript
Page({
  data: {
    loading: true,
    list: [],
  },
  async onLoad() {
    const cached = wx.getStorageSync('home_list');
    if (cached) {
      this.setData({ list: cached, loading: false });
    }
    const fresh = await fetchHomeList();
    this.setData({ list: fresh, loading: false });
    wx.setStorageSync('home_list', fresh);
  },
});

监控指标:

  • 启动总耗时、首屏渲染时间(FMP)。
  • 接口耗时、setData 耗时、节点数量。
  • 用户白屏率和退出率。

评分维度

  • 能分析启动流程和白屏原因(30%)
  • 能从包、代码、数据、渲染四个层面给出方案(40%)
  • 能写出骨架屏或缓存优先代码示例(30%)

常见错误

  • 只优化包体积,忽略首屏接口和渲染性能。
  • 在 app.js 中同步初始化大量 SDK。
  • 首屏一次性请求过多串行接口。

延伸追问

  • 如何精确测量小程序首屏时间?
  • 独立分包对广告投放场景有什么价值?

相关题目

参考资源

口头回答版

小程序启动要经过加载运行时、下载主包、初始化 app.js、渲染首页、请求数据、setData 更新。白屏通常是因为主包大、app.js 阻塞、首屏接口慢、setData 数据多。优化可以从四个方面做:包层面控制主包、用分包;代码层面延迟初始化、并行请求;数据层面做缓存优先、分页加载;渲染层面用骨架屏、减少节点。最常用的是骨架屏加缓存先展示,接口回来再刷新。


FB-45-PE-P-003:小程序包体积优化有哪些手段?如何分析体积?

题型:性能优化题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、性能优化、工程化 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明小程序包体积的限制和优化手段,并介绍如何分析包体积构成。

参考答案

微信小程序包体积限制:

类型限制
主包2MB
单个分包2MB
所有包总计20MB

超过主包限制会导致无法预览和上传,因此体积优化是小程序工程化的核心工作。

常用优化手段:

一、代码层面:

  • Tree Shaking:移除未引用的模块和函数。
  • 代码压缩:Terser / Uglify 压缩 JS。
  • 按需加载:大型库按功能分包或按需引入。
  • 图片资源:压缩、转 WebP、CDN 外联、使用字体图标。
  • 样式精简:删除无用 WXSS,避免全局样式污染。

二、架构层面:

  • 分包加载:按业务域拆包。
  • 独立分包:活动页单独成包。
  • 组件复用:公共组件抽到主包,避免重复打包。

三、平台能力:

  • 使用小程序插件替代内置代码。
  • 利用「分包异步化」能力延迟加载非必要模块。

体积分析方法:

  1. 开发者工具

    • 点击"上传"或"详情"查看主包、分包大小。
    • 使用"代码依赖分析"查看文件体积。
  2. 构建产物分析

    • Webpack Bundle Analyzer:分析 JS 依赖。
    • 自定义脚本统计 wxml / wxss / js / 图片占比。
  3. CI 门禁

    • 在流水线中统计包体积,超过阈值阻断合并。

示例:构建脚本统计体积

javascript
// scripts/analyze-size.js
const fs = require('fs');
const path = require('path');

function getDirSize(dir) {
  let total = 0;
  const files = fs.readdirSync(dir, { withFileTypes: true });
  for (const file of files) {
    const full = path.join(dir, file.name);
    if (file.isDirectory()) {
      total += getDirSize(full);
    } else {
      total += fs.statSync(full).size;
    }
  }
  return total;
}

const dist = path.join(__dirname, '../dist');
console.log(`总包体积: ${(getDirSize(dist) / 1024 / 1024).toFixed(2)} MB`);

最佳实践:

  • 建立体积预算(Bundle Budget),主包控制在 1.5MB 以内留出余量。
  • 每次迭代前 review 新增依赖体积。
  • 对图片资源统一上 CDN,不在包内放原图。

评分维度

  • 能说明主包 2MB / 总分包 20MB 的限制(20%)
  • 能从代码、架构、平台能力三个层面给出优化手段(40%)
  • 能介绍体积分析工具和 CI 门禁(40%)

常见错误

  • 只压缩 JS 不处理图片资源。
  • 分包拆分后公共代码没有抽到主包。
  • 等上传失败才关注体积。

延伸追问

  • 如何分析单个 npm 包对体积的贡献?
  • 分包异步化适合什么场景?

相关题目

参考资源

口头回答版

微信小程序主包不能超过 2MB,所有包加起来 20MB。优化手段很多:代码上做 Tree Shaking、压缩、按需引入;图片压缩、转 WebP、上 CDN;架构上按业务分包,公共组件和工具放主包;还可以用分包异步化。分析体积可以用开发者工具的代码依赖分析,也可以用 Webpack Bundle Analyzer,CI 里加个体积门禁,超阈值就阻断合并。主包最好控制在 1.5MB 以内留余量。


FB-45-FS-P-004:小程序自定义组件的 behaviors、relations 和 slot 实现机制是什么?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、组件化、生命周期、数据绑定 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请深入分析小程序自定义组件中的 behaviors、relations 和 slot 机制,说明它们解决了什么问题,以及使用时的注意事项。

参考答案

一、behaviors:

behaviors 是小程序的代码复用机制,类似于 Vue 的 mixin 或 React 的高阶组件。它可以把一组 properties、data、methods、生命周期注入到多个组件中。

示例:

javascript
// behaviors/share.js
module.exports = Behavior({
  properties: {
    sharedProp: {
      type: String,
      value: 'default',
    },
  },
  data: {
    sharedData: 0,
  },
  methods: {
    sharedMethod() {
      console.log('来自 behavior');
    },
  },
  attached() {
    console.log('behavior attached');
  },
});
javascript
// components/my-comp/my-comp.js
const shareBehavior = require('../../behaviors/share');

Component({
  behaviors: [shareBehavior],
  methods: {
    onTap() {
      this.sharedMethod();
    },
  },
});

注意事项:

  • 同名字段以组件自身为准,可用 behaviorPriority 控制优先级。
  • 多个 behavior 有同名字段时会覆盖或合并。
  • 适合抽离公共逻辑,但不宜滥用,避免来源不清晰。

二、relations:

relations 用于建立组件之间的父子/兄弟关系,常用于表单、列表、树形组件等场景。

示例:

javascript
// components/radio-group/radio-group.js
Component({
  relations: {
    '../radio/radio': {
      type: 'child',
      linked(target) {
        this.children = this.children || [];
        this.children.push(target);
      },
      unlinked(target) {
        this.children = this.children.filter(c => c !== target);
      },
    },
  },
  methods: {
    changeSelect(selected) {
      this.children.forEach(child => {
        child.setData({ checked: child.data.value === selected });
      });
    },
  },
});
javascript
// components/radio/radio.js
Component({
  relations: {
    '../radio-group/radio-group': {
      type: 'parent',
      linked(target) {
        this.parent = target;
      },
    },
  },
  methods: {
    onTap() {
      this.parent.changeSelect(this.data.value);
    },
  },
});

三、slot:

小程序 slot 类似 Vue 插槽,支持默认插槽和命名插槽(基础库 2.1.0+)。

xml
<!-- components/card/card.wxml -->
<view class="card">
  <view class="header">
    <slot name="header"></slot>
  </view>
  <view class="body">
    <slot></slot>
  </view>
</view>
xml
<!-- page.wxml -->
<card>
  <view slot="header">标题</view>
  <view>内容区域</view>
</card>

注意:

  • slot 中传入的节点会渲染在组件的 Shadow Tree 中。
  • 可通过 slot 实现内容分发和布局复用。
  • 作用域插槽小程序支持有限,复杂场景建议用 properties 传递数据。

评分维度

  • 能说明 behaviors 的复用机制和注意事项(30%)
  • 能说明 relations 的父子关系建立和应用场景(30%)
  • 能说明 slot 的内容分发机制(30%)
  • 能指出 Shadow Tree 对这些机制的影响(10%)

常见错误

  • behaviors 中定义与组件同名字段导致覆盖困惑。
  • relations 中没有处理 unlinked,导致组件卸载后状态残留。
  • 在 slot 里使用复杂作用域导致数据流混乱。

延伸追问

  • behaviors 和 Vue mixin 有什么异同?
  • relations 能否跨多层嵌套使用?

相关题目

参考资源

口头回答版

behaviors 是小程序的代码复用机制,像 mixin,可以把 properties、data、methods、生命周期注入多个组件,但要注意字段覆盖。relations 用来建立组件之间的父子关系,比如 radio-group 和 radio,父组件通过 type child 收集子组件,子组件通过 type parent 找到父组件,适合表单、树形组件。slot 就是插槽,支持默认插槽和命名插槽,可以在组件里留位置让外部填内容。这些机制都和 Shadow Tree 有关,要注意组件树和页面树的组合关系。


FB-45-FS-P-005:小程序的同层渲染原理是什么?解决了什么问题?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、容器、架构、组件化 出现频率:中频 预计回答时长:5-8 分钟

题目描述: 请解释小程序中"同层渲染"的概念、原理,以及它解决了什么问题。并举例说明哪些组件需要同层渲染。

参考答案

小程序渲染层运行在 WebView 中,普通组件通过 HTML 节点渲染。但部分组件(如 videomapcanvascamera)如果也用 HTML 实现,性能和体验会受限,因此平台用原生视图直接渲染这些组件。

传统覆盖模式的问题:

  • 原生组件默认覆盖在 WebView 之上,层级最高。
  • 无法被普通 WXML 元素覆盖(如弹窗、遮罩层失效)。
  • 滚动时原生组件不会跟随 WebView 内容一起移动。

同层渲染原理:

text
1. WebView 渲染普通 WXML 节点
2. 遇到原生组件标签时,在 WebView 中预留一个占位区域
3. 客户端在占位区域对应位置插入原生视图
4. 原生视图与 WebView 内容处于同一层级
5. 普通 WXML 元素可以覆盖原生组件,滚动时原生组件跟随移动

同层渲染的优势:

  • 原生组件可以像普通组件一样被覆盖和定位。
  • 支持 CSS 动画、transform、overflow 等部分样式。
  • 解决了覆盖层级和滚动跟随问题。

典型需要同层渲染的组件:

组件原因
video视频解码和播放性能
map地图渲染需要原生 SDK
canvas 2d高性能绘图
camera调用系统相机
live-player / live-pusher直播推拉流

注意事项:

  • 同层渲染需要基础库版本支持,低版本会降级为覆盖模式。
  • 部分 CSS 属性在同层渲染下仍有限制。
  • 原生组件的层级关系仍需用 cover-view / cover-image 做兼容兜底。

最佳实践:

  • 使用原生组件前检测基础库版本,必要时提示升级。
  • 弹窗覆盖 video 时优先使用同层渲染,低版本用 cover-view。
  • 避免在原生组件上叠加过多复杂交互。

评分维度

  • 能解释同层渲染解决原生组件覆盖层级问题(30%)
  • 能说明同层渲染的占位 + 原生视图插入原理(40%)
  • 能列举典型同层渲染组件和兼容注意事项(30%)

常见错误

  • 认为所有组件都是同层渲染。
  • 在低版本基础库上依赖同层渲染效果。
  • 忽略 cover-view 的兼容兜底。

延伸追问

  • 同层渲染和 cover-view 有什么区别?
  • 为什么 canvas 传统 API 和同层渲染 API 有差异?

相关题目

参考资源

口头回答版

小程序里 video、map、canvas 这些是原生组件,直接由客户端渲染,性能更好。早期它们是覆盖在 WebView 上面的,层级最高,普通元素盖不住,滚动还不跟随。同层渲染就是在 WebView 里给原生组件留个占位,然后把原生视图插到同一层,这样普通元素就能盖住它,滚动也能跟随。但同层渲染要基础库支持,低版本会降级,所以覆盖原生组件时还要准备 cover-view 兜底。


FB-45-PE-P-006:小程序 SSR、预渲染和骨架屏的实践方案是什么?

题型:性能优化题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、性能优化、生命周期、数据绑定 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请分析小程序中 SSR、预渲染和骨架屏三种首屏优化方案的原理、适用场景和实现方式,并说明它们的局限性。

参考答案

小程序首屏优化方案对比:

方案原理优点局限性
骨架屏用占位 UI 模拟真实页面结构实现简单,体验好无真实数据,需配合接口请求
预渲染构建时生成页面静态快照首屏快,SEO 友好动态内容无法预渲染
SSR服务端实时渲染页面数据首屏有真实数据服务端成本高,小程序 SSR 生态弱

一、骨架屏:

最常用的小程序首屏优化方案。在数据返回前展示灰色占位块,减少白屏焦虑。

实现方式:

  • 手动编写骨架屏 WXML / WXSS。
  • 使用构建插件自动生成骨架屏代码。
  • 首页数据加载完成前显示 skeleton,加载完成后切换真实内容。

二、预渲染:

在构建阶段针对部分页面生成静态 HTML 或 JSON 数据快照,启动时直接渲染。

小程序预渲染实践:

  • 把不常变的页面数据(如分类、配置)打包进主包或分包。
  • 首页 onLoad 时先读本地静态数据渲染,再异步刷新。
  • 结合 CDN 预渲染页面 JSON,启动时直接 setData。

三、SSR(服务端渲染):

传统 SSR 在小程序中应用较少,因为小程序本身运行在客户端离线包中。但可以通过以下方式模拟 SSR 效果:

  • 服务端提前组装首屏数据,接口一次性返回完整渲染数据。
  • 使用云函数或 BFF 层做首屏数据聚合。
  • 把首屏数据通过 URL 参数或 storage 预置到小程序中。

混合方案示例:

javascript
Page({
  data: {
    pageReady: false,
    homeData: null,
  },
  async onLoad() {
    // 1. 先展示骨架屏
    // 2. 尝试读取本地缓存数据
    const cached = wx.getStorageSync('home_data');
    if (cached) {
      this.setData({ homeData: cached, pageReady: true });
    }
    // 3. 请求最新数据
    const fresh = await fetchHomeData();
    this.setData({ homeData: fresh, pageReady: true });
    wx.setStorageSync('home_data', fresh);
  },
});

最佳实践:

  • 骨架屏适合所有需要接口请求的页面。
  • 预渲染适合内容变化不频繁的展示型页面。
  • SSR 适合服务端能力强、对首屏 SEO 有要求的场景(如百度小程序)。
  • 三者可以组合使用:骨架屏 + 缓存/预渲染 + 接口刷新。

评分维度

  • 能对比骨架屏、预渲染、SSR 的原理和适用场景(40%)
  • 能说明小程序 SSR 的特殊性和实现思路(30%)
  • 能给出混合方案和代码示例(30%)

常见错误

  • 把所有页面都做成 SSR,忽略小程序离线包特性。
  • 骨架屏和真实页面结构差异大,切换时闪烁明显。
  • 预渲染数据过期没有及时刷新。

延伸追问

  • 百度小程序的搜索收录和 SSR 有什么关系?
  • 骨架屏如何自动生成?有哪些工具?

相关题目

参考资源

口头回答版

小程序首屏优化常用三种方案。骨架屏最简单,数据没回来前先显示占位块,减少白屏感。预渲染是构建时生成静态快照,启动直接渲染,适合内容不常变的页面。SSR 在小程序里用得少,因为小程序是离线包跑在客户端,但可以让服务端把首屏数据拼好一次性返回,或者用云函数聚合。实际项目中我一般是骨架屏加本地缓存,接口回来再刷新,三者可以组合用。


FB-45-SC-P-007:小程序全局状态管理有哪些方案?如何选择?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:45 小程序 标签:小程序、数据绑定、组件化、架构 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请分析小程序中常见的全局状态管理方案,包括 App.globalData、storage、EventBus、MobX、Redux、自研 Store 等,并说明各自的适用场景和选型建议。

参考答案

小程序全局状态管理方案对比:

方案特点适用场景
App.globalData简单全局对象,页面通过 getApp() 访问少量共享状态,如用户信息
wx.storage本地持久化存储缓存数据、用户偏好
EventBus发布订阅模式简单跨页面事件通知
MobX响应式状态管理,自动触发视图更新中大型项目
Redux / Zustandpredictable 状态流复杂状态、需要调试工具
自研 Store完全可控,轻量对包体积敏感、有定制需求

一、App.globalData:

javascript
// app.js
App({
  globalData: {
    userInfo: null,
  },
});

// page.js
const app = getApp();
Page({
  onLoad() {
    console.log(app.globalData.userInfo);
  },
});

优点:简单,无需引入库。 缺点:非响应式,修改后不会自动更新页面;数据在内存中,重启丢失。

二、EventBus:

javascript
// utils/eventBus.js
class EventBus {
  constructor() {
    this.events = {};
  }
  on(name, cb) {
    (this.events[name] || (this.events[name] = [])).push(cb);
  }
  emit(name, data) {
    (this.events[name] || []).forEach(cb => cb(data));
  }
}
export default new EventBus();

优点:轻量,适合跨页面事件。 缺点:事件来源难以追踪,容易内存泄漏。

三、MobX:

小程序官方推荐的响应式状态管理库,通过 observable 自动触发 setData。

javascript
// store.js
import { observable, action } from 'mobx-miniprogram';

export const store = observable({
  count: 0,
  add: action(function() {
    this.count++;
  }),
});

优点:响应式,开发体验接近 Vue / React。 缺点:引入额外依赖,增加包体积。

选型建议:

  • 简单项目:App.globalData + storage 缓存。
  • 中等项目:MobX 或自研 Store。
  • 大型项目:MobX / Redux + 自研中间件 + 模块化。
  • 对包体积极度敏感:自研轻量 Store。

最佳实践:

  • 状态尽量按领域模块拆分。
  • 持久化状态与内存状态分离。
  • 页面卸载时取消订阅,避免内存泄漏。

评分维度

  • 能列举至少 4 种状态管理方案(30%)
  • 能对比各自优缺点和适用场景(40%)
  • 能给出选型建议和代码示例(30%)

常见错误

  • 所有状态都放 globalData,导致数据流混乱。
  • EventBus 不取消订阅,造成内存泄漏。
  • 在小型项目中引入重型状态库。

延伸追问

  • 如何实现 Store 的持久化和恢复?
  • 多分包之间如何共享状态?

相关题目

参考资源

口头回答版

小程序状态管理方案有好几种:简单场景用 App.globalData,修改后不会自动更新视图;缓存用 wx.storage;跨页面通知可以用 EventBus,但要注意取消订阅;中大型项目推荐 MobX,响应式,自动触发 setData;更复杂可以用 Redux 或自研 Store。我一般小项目 globalData 加 storage,中大项目用 MobX。状态要按模块拆分,页面卸载记得取消订阅。


架构题(32 道)

FB-45-SD-R-001:如何设计一个跨端小程序框架(如 Taro / UniApp 的思路)?

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、架构、组件化、工程化 出现频率:中频 预计回答时长:15-30 分钟

题目描述: 如果你要设计一个跨端小程序框架,让开发者用一套代码同时产出微信、支付宝、抖音、百度等多个平台的小程序,你会如何设计整体架构、编译流程和运行时适配层?

参考答案

跨端小程序框架的核心目标是用统一的开发范式(通常是 React / Vue 语法)编译或运行出多个平台的小程序产物。典型代表有 Taro(以 React 语法为主)和 UniApp(以 Vue 语法为主)。

整体架构分层:

text
+---------------------------+
|       开发者源码           |
|  React / Vue 组件 + 业务逻辑 |
+---------------------------+
|       编译时层             |
|  AST 解析、模板转译、组件映射  |
+---------------------------+
|       运行时层             |
|  组件适配、API 适配、路由适配  |
+---------------------------+
|       目标平台             |
|  微信 / 支付宝 / 抖音 / 百度  |
+---------------------------+

一、编译时层:

  1. AST 解析

    • 用 Babel / SWC 解析 JSX / Vue SFC。
    • 把 JSX 编译为目标平台的 WXML / AXML / TTML。
  2. 模板转译

    • div 映射为 viewspan 映射为 text
    • 处理事件绑定:onClick -> bindtap
    • 处理条件渲染:v-if / JSX 条件表达式 -> wx:if
  3. 样式处理

    • CSS 转 WXSS / ACSS,处理 rpx、选择器兼容。
  4. 代码拆分

    • 按平台配置生成 pages、subPackages、usingComponents。

二、运行时层:

  1. API 适配
    • 统一封装 requestnavigateTogetStorage 等。
    • 运行时判断平台,调用对应 wx / my / tt / swan
javascript
// 运行时适配示例
const api = {
  request(options) {
    if (typeof wx !== 'undefined') return wx.request(options);
    if (typeof my !== 'undefined') return my.request(options);
    // ...
  },
};
  1. 组件适配

    • 统一组件接口,平台差异用 props 或 slot 兜底。
    • 对不支持的组件提供降级方案或警告。
  2. 生命周期适配

    • 把 React / Vue 生命周期映射到小程序页面和组件生命周期。
  3. 状态与事件

    • 实现跨平台的 setData、事件系统、ref 访问。

三、平台差异处理:

差异类型处理方式
组件差异条件编译 + 运行时组件映射
API 差异运行时 polyfill + 能力检测
样式差异编译时转换 + 平台后缀文件
生命周期差异运行时封装统一生命周期
包体积限制按平台分包、Tree Shaking

最佳实践:

  • 优先用标准 API 和组件,平台特有功能通过条件编译隔离。
  • 建立平台能力矩阵,明确各平台支持度。
  • 运行时适配层保持轻量,复杂转换放编译时。
  • 提供良好的调试工具和错误提示。

评分维度

  • 能画出编译时 + 运行时两层架构(30%)
  • 能说明 AST 转译、组件映射、API 适配核心机制(40%)
  • 能提出平台差异处理策略和最佳实践(30%)

常见错误

  • 认为跨端框架能 100% 抹平平台差异。
  • 把所有适配逻辑都放在运行时,导致包体积过大。
  • 忽略编译时错误提示和调试体验。

延伸追问

  • Taro 3 的编译时和运行时和 Taro 1/2 有什么区别?
  • 如何处理某个平台独有的组件或 API?

相关题目

参考资源

口头回答版

设计跨端小程序框架主要分两层:编译时和运行时。编译时用 AST 把 React 或 Vue 代码转成各平台的 WXML/AXML 这些模板,组件做映射,比如 div 转 view。运行时做 API 适配,统一封装 request、navigateTo 这些,运行时再判断是 wx、my、tt 还是 swan。平台差异用条件编译加运行时 polyfill 处理。要注意不是所有差异都能抹平,特有 API 要单独处理,复杂转换尽量放编译时,保持运行时轻量。


FB-45-EN-R-002:小程序团队的工程化建设和 Monorepo 多包管理方案是什么?

题型:工程化题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、工程化、Monorepo、组件化 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请设计一套适合中大型小程序团队的工程化方案,包括目录结构、组件库管理、构建流程、CI/CD、Monorepo 组织方式,以及多环境发布策略。

参考答案

中大型小程序团队工程化需要解决代码复用、多人协作、版本管理、多环境发布等问题。Monorepo 是常用组织方式。

一、Monorepo 目录结构:

text
mini-program-monorepo/
├── apps/
│   ├── main-app/            # 主小程序
│   ├── activity-app/        # 活动小程序
│   └── vendor-app/          # 商家端小程序
├── packages/
│   ├── ui-components/       # 组件库
│   ├── utils/               # 工具函数
│   ├── api-sdk/             # 接口 SDK
│   ├── auth/                # 登录鉴权
│   └── eslint-config/       # 共享 ESLint 配置
├── scripts/
│   └── build.js             # 构建脚本
├── pnpm-workspace.yaml
├── turbo.json
└── package.json

二、包管理工具:

  • pnpm workspace:节省磁盘空间,依赖关系清晰。
  • Turborepo / Nx:任务调度、缓存、并行构建。
  • Changesets:版本管理和 CHANGELOG 生成。

三、构建流程:

text
1. lint / type-check
2. 组件库 / SDK 构建
3. 各小程序编译(微信 / 支付宝 / 抖音)
4. 包体积检测
5. 上传体验版 / 提交审核

四、CI/CD 流程:

yaml
# .github/workflows/build.yml
name: Mini Program CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v2
      - run: pnpm install
      - run: pnpm lint
      - run: pnpm type-check
      - run: pnpm build
      - run: pnpm size-limit
      - run: pnpm upload:preview --app=main-app

五、多环境发布策略:

环境用途发布方式
开发环境本地调试开发者工具真机预览
测试环境QA 测试上传体验版,扫码体验
预发布灰度验证分阶段放量、白名单
生产环境全量用户提交平台审核后发布

六、组件库管理:

  • 组件库单独发包到私有 npm 或 workspace 引用。
  • 提供示例小程序和文档站点。
  • 使用 Storybook 或自研小程序组件文档工具。

最佳实践:

  • 统一编码规范:ESLint、Prettier、commitlint。
  • 组件库和 SDK 独立版本号,避免一个改动全量发布。
  • 建立包体积门禁和性能基线。
  • 关键流程自动化:上传体验版、收集测试二维码。

评分维度

  • 能设计 Monorepo 目录结构(30%)
  • 能说明构建、CI/CD、多环境发布流程(40%)
  • 能提出组件库管理和版本控制策略(30%)

常见错误

  • 所有小程序和组件都放在一个仓库但没有任何 workspace 管理。
  • 组件库版本混乱,导致各小程序依赖不一致。
  • 忽略多环境配置,生产测试混用。

延伸追问

  • 如何处理多个小程序之间的公共依赖版本冲突?
  • 小程序自动化测试有哪些方案?

相关题目

参考资源

口头回答版

中大型小程序团队我建议用 Monorepo,把 apps 和 packages 分开。apps 放各个小程序,packages 放组件库、工具、SDK。用 pnpm workspace 管理依赖,Turborepo 做任务调度和缓存。CI 流程里做 lint、类型检查、构建、包体积检测,然后自动上传体验版。多环境分开发、测试、预发布、生产。组件库独立发包、独立版本,避免一改全量发布。还要加包体积门禁和性能基线。


FB-45-SD-R-003:如何构建小程序的监控、埋点与灰度发布体系?

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、监控、埋点、灰度、架构 出现频率:高频 预计回答时长:15-30 分钟

题目描述: 请设计一套小程序的监控、埋点与灰度发布体系,包括技术架构、数据采集方案、核心指标、告警机制和灰度策略。

参考答案

一、监控体系:

监控分层:

层级监控内容采集方式
性能监控启动耗时、首屏时间、setData 耗时、包体积小程序 Performance API、自定义打点
错误监控JS 异常、API 失败、渲染异常try/catch、wx.onError、接口拦截
业务监控转化率、漏斗、关键路径埋点 SDK
可用性监控页面白屏、接口可用性心跳探测、用户反馈

性能监控示例:

javascript
// utils/perf.js
function reportPerformance(metric, value) {
  wx.request({
    url: '/log/perf',
    method: 'POST',
    data: { metric, value, page: getCurrentPageRoute(), timestamp: Date.now() },
  });
}

Page({
  onReady() {
    const now = Date.now();
    reportPerformance('page_ready', now - this.startTime);
  },
});

二、埋点体系:

埋点类型:

  • 代码埋点:精确,但侵入性强。
  • 可视化埋点:运营可配置,适合活动页。
  • 全埋点:自动采集点击、页面浏览,数据量大。

埋点 SDK 设计:

text
1. 事件采集:page view、click、exposure
2. 本地缓存:达到一定条数或时间窗口后批量上报
3. 数据压缩:JSON 序列化,必要时压缩
4. 失败重试:网络失败时落盘,下次启动补报
5. 去重与采样:避免重复上报,支持采样率配置

三、灰度发布:

灰度维度:

  • 用户维度:按 userId、openId、设备号分桶。
  • 地域维度:按城市、省份逐步放量。
  • 版本维度:按小程序版本号灰度。
  • 业务维度:按页面、功能开关控制。

灰度架构:

text
1. 配置中心维护灰度规则和功能开关
2. 小程序启动时拉取配置
3. 根据用户特征计算是否命中实验
4. 命中则启用新逻辑 / 新页面 / 新接口
5. 监控灰度组和对照组的核心指标差异

功能开关示例:

javascript
// services/config.js
async function getFeatureFlags() {
  const config = await fetch('/api/config');
  return config.featureFlags;
}

// page.js
Page({
  async onLoad() {
    const flags = await getFeatureFlags();
    if (flags.newHomepage) {
      this.setData({ useNewHomepage: true });
    }
  },
});

四、告警机制:

  • 核心指标超过阈值时触发告警(如错误率 > 1%、首屏时间 > 3s)。
  • 告警分级:P0 电话、P1 企业微信、P2 邮件。
  • 告警收敛:同类型告警聚合,避免轰炸。

最佳实践:

  • 埋点数据格式统一,便于分析。
  • 性能数据定期 review,建立性能基线。
  • 灰度发布要有回滚预案和监控对照组。
  • 遵守隐私合规,不上报敏感用户信息。

评分维度

  • 能设计性能、错误、业务、可用性四层监控(30%)
  • 能说明埋点 SDK 的核心模块(30%)
  • 能设计灰度策略和功能开关机制(40%)

常见错误

  • 埋点上报过于频繁,影响性能。
  • 灰度没有对照组,无法判断效果。
  • 监控只关注错误,忽略性能和业务指标。

延伸追问

  • 如何保证埋点数据的准确性和完整性?
  • 小程序崩溃和 JS 错误如何区分和采集?

相关题目

参考资源

口头回答版

小程序监控体系我分四层:性能监控启动耗时、首屏时间、setData 耗时;错误监控 JS 异常和接口失败;业务监控转化漏斗;可用性监控白屏。埋点有代码埋点、可视化埋点和全埋点,SDK 要做本地缓存、批量上报、失败重试和采样。灰度发布靠配置中心和功能开关,可以按用户、地域、版本分桶,灰度组和对照组对比核心指标。还要有告警和回滚预案,注意隐私合规。


FB-45-SC-R-004:小程序 SEO / 搜索优化和内容索引方案如何设计?

题型:场景设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、SEO、架构、生命周期 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请设计小程序的 SEO 和搜索优化方案,包括 sitemap 配置、页面内容可被搜索索引、关键词优化、内容预渲染,以及百度小程序和微信小程序的差异。

参考答案

小程序 SEO 的目标是让平台搜索引擎能够抓取、理解并索引小程序页面,从而在自然搜索、信息流推荐中获得流量。

一、基础配置:

  1. sitemap.json
    • 告诉搜索引擎哪些页面可以索引。
    • 配置索引规则和优先级。
json
{
  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
  "rules": [
    {
      "action": "allow",
      "page": "*"
    },
    {
      "action": "disallow",
      "page": "pages/secret/*"
    }
  ]
}
  1. 页面标题和描述
    • 每个页面配置清晰的 navigationBarTitleText
    • 页面内容包含核心关键词。

二、内容可索引化:

  1. 页面参数语义化

    • URL 参数使用有意义的字段名,如 ?id=123&keyword=手机
    • 避免纯哈希或加密参数。
  2. 结构化数据

    • 使用 JSON-LD 或平台定义的结构化数据标记页面内容。
    • 便于搜索引擎理解商品、文章、视频等实体。
  3. 内容预渲染

    • 对文章、商品详情等页面,服务端提前渲染内容数据。
    • 搜索引擎抓取时返回完整 HTML 或结构化数据。

三、关键词与内容优化:

  • 标题、摘要、正文围绕核心关键词展开。
  • 保持内容原创、更新频繁。
  • 图片加 alt 描述,视频加标题和标签。

四、百度小程序 vs 微信小程序:

维度百度小程序微信小程序
搜索入口百度搜索、信息流微信搜一搜、发现
SEO 权重非常高,天然搜索基因社交属性强,搜索权重相对较低
内容收录支持页面 URL 直接收录依赖 sitemap 和页面质量
SSR 需求强,建议服务端直出相对弱,可用骨架屏 + 缓存

五、数据监控:

  • 监控收录量、搜索曝光量、点击率。
  • 分析热搜词,调整内容策略。
  • A/B 测试标题和摘要,提升点击率。

最佳实践:

  • 重点页面优先配置 sitemap。
  • 内容页 URL 稳定,避免频繁变化。
  • 服务端渲染或预渲染关键内容。
  • 定期提交页面到平台搜索资源平台。

评分维度

  • 能说明 sitemap 和页面基础配置(25%)
  • 能设计内容可索引化和结构化数据方案(35%)
  • 能对比百度和微信小程序 SEO 差异(25%)
  • 能提出数据监控和优化策略(15%)

常见错误

  • 所有页面都 allow,导致低质量页面被索引。
  • URL 参数无意义,搜索引擎无法识别内容。
  • 忽略百度小程序的 SSR 优势。

延伸追问

  • 如何让搜索引擎抓取小程序中的动态内容?
  • 小程序页面 URL 和 H5 URL 如何统一做 SEO?

相关题目

参考资源

口头回答版

小程序 SEO 首先要配 sitemap.json,告诉搜索引擎哪些页面可以索引。页面标题要清晰,URL 参数要有意义,比如 ?id=123&keyword=手机,别用加密参数。内容页最好做预渲染或 SSR,方便搜索引擎抓取。还要加结构化数据标记商品、文章这些实体。百度小程序搜索权重更高,更建议服务端直出;微信小程序社交属性强,搜索权重相对低一些。最后要监控收录量、曝光、点击,定期优化标题和内容。


FB-45-SC-R-005:如何设计小程序的用户留存、分享裂变和运营增长方案?

题型:场景设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、留存、架构、数据绑定 出现频率:中频 预计回答时长:8-15 分钟

题目描述: 请从技术和产品结合的角度,设计一套小程序用户留存、分享裂变和运营增长方案,包括触达渠道、数据指标、技术实现和风控策略。

参考答案

一、留存策略:

  1. 消息触达

    • 订阅消息:用户授权后可在服务场景下发。
    • 公众号关联:通过公众号模板消息或图文触达。
    • 服务通知:订单状态、物流提醒等。
  2. 首页个性化

    • 根据用户历史行为推荐内容。
    • 本地缓存用户偏好,减少二次进入加载时间。
  3. 会员与积分体系

    • 签到、积分、等级、优惠券。
    • 把用户资产数据同步到 storage 和服务端。

二、分享裂变:

  1. 分享能力
    • onShareAppMessage 自定义分享卡片。
    • 分享参数带用户邀请码或商品 ID。
javascript
Page({
  onShareAppMessage() {
    return {
      title: '邀请你领取新人礼包',
      path: '/pages/index/index?inviter=USER123',
      imageUrl: '/images/share.png',
    };
  },
});
  1. 裂变玩法

    • 拼团、砍价、助力、邀请返利。
    • 分享后解锁内容或优惠券。
  2. 短链与二维码

    • 生成带参数二维码,便于线下投放。
    • URL Scheme 支持外部跳转回小程序。

三、运营增长技术架构:

text
1. 数据采集:埋点 SDK 采集用户行为
2. 用户画像:标签体系、分群、RFM 模型
3. 增长实验:A/B 测试、功能开关
4. 触达引擎:订阅消息、PUSH、短信、公众号
5. 效果分析:漏斗、留存、LTV、CAC

四、核心数据指标:

指标含义
DAU / MAU日活 / 月活
次日留存 / 7 日留存用户回访比例
分享率分享用户数 / 总用户数
裂变系数 K每个用户带来新用户数
转化率关键行为转化比例
LTV / CAC用户终身价值 / 获客成本

五、风控策略:

  • 邀请关系反作弊:检测同一设备、同一 IP、异常时间集中的邀请。
  • 分享内容审核:避免诱导分享、虚假宣传。
  • 频率限制:限制单个用户分享和助力次数。
  • 数据对账:奖励发放与业务数据核对。

最佳实践:

  • 留存和增长要基于数据,避免拍脑袋做活动。
  • 分享卡片要突出利益点,提高点击率。
  • 用户路径要短,减少转化流失。
  • 合规使用平台能力,避免被封禁。

评分维度

  • 能设计留存触达和分享裂变玩法(30%)
  • 能画出增长技术架构(30%)
  • 能提出核心指标和风控策略(40%)

常见错误

  • 只关注拉新,不关注留存和转化。
  • 分享参数不带追踪标识,无法归因。
  • 裂变活动没有反作弊,被羊毛党薅垮。

延伸追问

  • 订阅消息触达率下降如何应对?
  • 如何衡量一次裂变活动的真实 ROI?

相关题目

参考资源

口头回答版

小程序留存主要靠消息触达,比如订阅消息、公众号关联,再加上首页个性化、会员积分体系。分享裂变用 onShareAppMessage 自定义分享卡片,带上邀请参数,做拼团、砍价、助力这些玩法。技术架构上要有埋点采集、用户画像、增长实验、触达引擎和效果分析。核心指标看 DAU、留存、分享率、裂变系数、转化率。风控要做好反作弊、内容审核和频率限制,别让羊毛党薅垮了。


FB-45-SE-R-006:小程序安全架构应考虑哪些方面?

题型:安全题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、安全、权限、架构 出现频率:高频 预计回答时长:8-15 分钟

题目描述: 请从数据安全、接口安全、代码安全、运行安全、合规安全等维度,设计小程序的整体安全架构。

参考答案

小程序安全架构需要从客户端、服务端、通信链路和平台合规四个层面考虑。

一、数据安全:

  1. 敏感数据加密

    • 本地 storage 中 token、用户信息加密存储。
    • 敏感字段传输使用 HTTPS + 业务层加密。
  2. 密钥管理

    • AppSecret、API Key 不能写在前端。
    • 使用服务端代理或 KMS 管理密钥。
  3. 隐私合规

    • 获取用户信息前展示隐私协议。
    • 仅采集业务必需的字段,遵循最小必要原则。

二、接口安全:

  1. 身份鉴权

    • 每次请求携带 token,服务端校验签名和有效期。
    • 登录态失效后引导重新登录。
  2. 防重放与防篡改

    • 请求加时间戳、nonce、签名。
    • 关键接口做幂等处理。
  3. 频率限制

    • 登录、验证码、助力等接口限制调用频率。
    • 防止暴力破解和薅羊毛。

三、代码安全:

  1. 代码混淆

    • 小程序代码可被反编译,需做 JS 混淆和压缩。
    • 关键逻辑放到服务端。
  2. 反调试

    • 检测开发者工具、模拟器环境。
    • 敏感页面增加风控校验。
  3. 安全扫描

    • 平台上传代码时会做安全检测。
    • CI 中集成静态安全扫描。

四、运行安全:

  1. 输入校验

    • 前端做基础校验,服务端做最终校验。
    • 防止 XSS、SQL 注入等攻击。
  2. 跳转安全

    • 外部链接使用 web-view 白名单。
    • 避免被钓鱼页面劫持。
  3. 支付安全

    • 支付签名在服务端生成,前端只负责调起。
    • 支付结果以服务端回调为准。

五、合规安全:

  • 小程序隐私保护指引配置。
  • 用户授权明确告知用途。
  • 未成年人保护、内容审核。

安全架构示意:

text
+------------------+
|    小程序客户端   |
|  加密存储 / 输入校验 |
+------------------+
         | HTTPS + 签名
+------------------+
|     API 网关      |
|  鉴权 / 限流 / WAF |
+------------------+
         |
+------------------+
|     业务服务      |
|  敏感逻辑 / 数据加密 |
+------------------+

评分维度

  • 能从数据、接口、代码、运行、合规五个维度展开(40%)
  • 能说明登录鉴权、签名、限流等关键机制(30%)
  • 能给出安全架构图和代码示例(30%)

常见错误

  • 把 AppSecret 或支付密钥写在前端。
  • 只依赖前端校验,忽略服务端校验。
  • 认为小程序代码不可被反编译。

延伸追问

  • 如何防止小程序被反编译后泄露业务逻辑?
  • 小程序登录凭证 code 被截获有什么风险?

相关题目

参考资源

口头回答版

小程序安全要从五个维度考虑:数据安全上敏感信息加密存储,AppSecret 不能放前端;接口安全上做 token 鉴权、请求签名、防重放、频率限制;代码安全上做 JS 混淆,关键逻辑放服务端;运行安全上做输入校验、跳转白名单、支付签名服务端生成;合规安全上配隐私协议、最小必要采集。前端校验只是第一道防线,最终一定要服务端校验。小程序代码是可以被反编译的,所以核心逻辑不要放前端。


FB-45-SD-R-007:如何设计一个多平台小程序容器架构?

题型:系统设计题 难度:⚫ 架构 岗位层级:架构师 面试知识域:45 小程序 标签:小程序、容器、架构、组件化 出现频率:低频 预计回答时长:15-30 分钟

题目描述: 假设你要在一个超级 App 中设计一个小程序容器,支持运行多种小程序(类似微信、支付宝的宿主能力),请说明整体架构、运行时设计、安全沙箱、能力扩展和性能隔离方案。

参考答案

多平台小程序容器是超级 App 运行第三方小程序的基础能力,需要兼顾安全、性能、扩展性和开发体验。

一、整体架构:

text
+-----------------------------+
|         宿主 App             |
|  账号 / 支付 / 推送 / 原生能力  |
+-----------------------------+
|        小程序容器            |
|  包管理 / 运行时 / JSBridge   |
+-----------------------------+
|      沙箱隔离层              |
|  进程隔离 / 权限控制 / 资源限制 |
+-----------------------------+
|    渲染引擎 + JS 引擎         |
|  WebView / 原生视图 / JSCore   |
+-----------------------------+
|        小程序应用            |
|  WXML / WXSS / JS / JSON      |
+-----------------------------+

二、核心模块:

  1. 包管理器

    • 下载、校验、解压、缓存小程序包。
    • 版本管理、增量更新、灰度下发。
  2. 运行时

    • 页面栈管理、路由调度。
    • 组件系统(类似 Exparser)。
    • 生命周期管理。
  3. JSBridge

    • 统一 API 网关,连接 JS 与宿主能力。
    • 权限校验、调用频率限制、版本兼容。
  4. 渲染引擎

    • WebView 负责普通组件渲染。
    • 原生组件同层渲染。
    • 可选自研渲染引擎替代 WebView。

三、安全沙箱:

层面方案
进程隔离小程序运行在独立进程,崩溃不影响主 App
文件隔离每个小程序有独立存储空间,不能访问其他小程序
网络隔离域名白名单、请求签名、HTTPS 强制
能力隔离API 按权限分级,敏感能力需用户授权
代码隔离JS 运行在独立 JSCore,不能直接访问 DOM

四、能力扩展:

  1. 插件化

    • 宿主提供基础插件,小程序按需引入。
    • 第三方开发者可注册自定义能力。
  2. JSBridge 扩展

    • 定义标准扩展协议。
    • 新能力通过注册表动态注入。
  3. 组件市场

    • 提供审核后的公共组件库。
    • 版本管理和安全扫描。

五、性能隔离:

  • 每个小程序分配内存上限、CPU 使用限制。
  • 后台小程序暂停执行,释放资源。
  • 长时间未使用的小程序包可清理。
  • 异常小程序可快速降级或关闭。

六、监控与治理:

  • 运行时性能监控:启动耗时、内存、CPU。
  • 异常监控:崩溃、JS 错误、API 违规调用。
  • 内容安全:图片、文字、视频审核。
  • 开发者信用体系:根据历史表现分配资源和权限。

评分维度

  • 能画出容器整体架构(30%)
  • 能说明包管理、运行时、JSBridge、渲染引擎职责(30%)
  • 能设计安全沙箱和性能隔离方案(40%)

常见错误

  • 认为容器就是简单套一个 WebView。
  • 忽略进程隔离和文件隔离的重要性。
  • 能力扩展没有权限审核机制。

延伸追问

  • 小程序容器和 Flutter、RN 容器有什么异同?
  • 如何实现小程序之间的数据隔离和通信?

相关题目

参考资源

口头回答版

多平台小程序容器核心要分几层:最下面是小程序应用包,上面有渲染引擎和 JS 引擎,再上是小程序运行时负责页面栈、组件、生命周期,然后是 JSBridge 连接宿主能力,最外面是宿主 App。安全上要做进程隔离、文件隔离、网络白名单、能力分级授权。性能上要限制每个小程序的内存和 CPU,后台暂停,长时间不用清理。能力扩展通过插件化和 JSBridge 注册表实现,还要有监控、异常处理和内容审核。

FB-45-CO-A-009:微信小程序的页面生命周期有哪些?与 App 生命周期有什么关系?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、生命周期、页面、App 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中 App 生命周期和页面生命周期的主要方法,以及它们之间的关系。

参考答案: 微信小程序生命周期:

App 生命周期(在 app.js 中):

  • onLaunch:小程序初始化完成,全局只触发一次。
  • onShow:小程序启动或从后台进入前台。
  • onHide:小程序从前台进入后台。
  • onError:小程序发生脚本错误或 API 调用失败。

页面生命周期(在页面 js 中):

  • onLoad:页面加载,可获取页面参数。
  • onShow:页面显示。
  • onReady:页面初次渲染完成。
  • onHide:页面隐藏(如 navigateTo 新页面)。
  • onUnload:页面卸载。

关系

  • App onLaunch 先于所有页面 onLoad
  • 页面 onShow/onHide 受 App onShow/onHide 影响。
  • 小程序切后台时,当前页面先 onHide,再触发 App onHide
  • 切回前台时,App onShow 先触发,再当前页面 onShow

开发注意:

  • 全局状态初始化放在 App onLaunch
  • 页面数据请求可在 onLoadonShow,根据业务决定。
  • 后台切回前台需要刷新数据的场景,在 onShow 处理。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

微信小程序 App 生命周期有 onLaunch、onShow、onHide、onError;页面有 onLoad、onShow、onReady、onHide、onUnload。App onLaunch 先于页面 onLoad,切后台当前页先 onHide 再 App onHide,切回则相反。全局状态放 App onLaunch,需要后台切回刷新的逻辑放 onShow。


FB-45-CO-A-010:微信小程序的 setData 有什么特点和使用注意事项?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、setData、性能、数据绑定 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序 setData 的作用、原理和使用注意事项。

参考答案setData 是小程序框架提供的方法,用于将数据从逻辑层发送到视图层,实现数据绑定和界面更新。

原理:

  • 逻辑层(JavaScriptCore)通过 setData 把数据序列化后传递到视图层(WebView)。
  • 每次 setData 都涉及跨线程通信,有性能开销。

使用注意事项:

  1. 避免频繁调用

    • 多次连续 setData 应合并为一次。
    • 例:用 this.setData({ a: 1, b: 2 }) 而不是两次调用。
  2. 避免设置大数据

    • 不要一次性 setData 整个列表或大量无关数据。
    • 只更新需要变化的字段。
  3. 列表更新优化

    • 长列表使用 recycle-view 或虚拟列表。
    • 分页加载,避免一次性渲染大量节点。
  4. 注意数据路径

    • 可以用路径更新深层数据,如 setData({ 'list[0].name': 'x' })
  5. 异步问题

    • setData 是同步调用,但视图更新是异步的。
    • 需要获取更新后 DOM 信息可用 wx.nextTick
  6. 避免在 scroll 等高频事件中 setData

    • 可使用节流或只更新必要状态。

示例优化:

js
// 不好
this.setData({ a: 1 });
this.setData({ b: 2 });

// 好
this.setData({ a: 1, b: 2 });

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

setData 把逻辑层数据传到视图层,涉及跨线程通信。要注意避免频繁调用、避免大数据、列表用虚拟列表、用路径更新深层数据、注意视图更新异步、高频事件节流。


FB-45-CO-A-011:微信小程序的组件化开发有哪些方式?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、组件化、自定义组件、开发 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中组件化开发的方式和自定义组件的基本概念。

参考答案: 微信小程序组件化开发方式:

  1. 自定义组件

    • Component 构造器创建,包含 propertiesdatamethodslifetimes 等。
    • 组件文件包括:js、wxml、wxss、json。
    • json 中声明 "component": true
  2. 使用 Component 构造器

    • 支持组件生命周期:createdattachedreadymoveddetached
    • 支持 observers 监听数据变化。
  3. behaviors

    • 类似 Vue 的 mixin 或 React 的高阶组件。
    • 用于组件间共享代码。
  4. 模板 template

    • 轻量级复用 WXML 片段,不带 JS 逻辑。
    • 适合简单 UI 复用。
  5. npm 组件/第三方组件

    • 通过 npm 引入组件库,如 Vant Weapp、WeUI。
    • 使用小程序 npm 构建。

自定义组件关键概念:

  • properties:外部传入的属性。
  • data:组件内部数据。
  • slot:内容分发。
  • triggerEvent:向父组件传事件。
  • relations:组件间关系(父子、兄弟)。

最佳实践:

  • 通用 UI 组件抽象成自定义组件。
  • 复杂业务组件保持独立数据和行为。
  • 合理使用 behaviors 避免过度复用导致难以维护。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序组件化有自定义组件、behaviors、模板、npm 组件。自定义组件用 Component 构造器,有 properties、data、slot、triggerEvent、relations。通用 UI 抽象成组件,复杂业务组件保持独立,合理使用 behaviors。


FB-45-CO-A-012:微信小程序的导航方式有哪些?各自适用场景是什么?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、导航、路由、页面跳转 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中常用的页面导航 API 及其适用场景。

参考答案: 微信小程序导航 API:

API作用适用场景
wx.navigateTo保留当前页,打开新页面进入详情页、表单页等需要返回的场景
wx.redirectTo关闭当前页,打开新页面登录后跳转首页,不需要返回
wx.reLaunch关闭所有页面,打开新页面切换主 tab、重新进入小程序
wx.switchTab跳转到 tabBar 页面底部导航切换
wx.navigateBack返回上一页面或多级完成操作后返回

注意事项:

  • navigateTo 页面栈最多 10 层,超过需用 redirectToreLaunch
  • tabBar 页面只能用 switchTab 跳转,不能用 navigateTo
  • 返回时可通过 getCurrentPages 获取页面栈,向上一页传数据。
  • 页面参数通过 onLoad 的 options 获取。

传参方式:

  • URL query:/pages/detail?id=123
  • 返回传参:通过 getCurrentPages() 获取上一页实例调用其方法或 eventChannel。
  • 全局状态:App globalData、Storage、状态管理库。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序导航 API:navigateTo 保留当前页开新页,redirectTo 关闭当前页,reLaunch 关闭所有页,switchTab 跳 tabBar,navigateBack 返回。注意页面栈最多 10 层,tabBar 只能用 switchTab。


FB-45-CO-A-013:微信小程序的 rpx 是什么?与 px、rem 有什么区别?

题型:概念题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、rpx、响应式、布局 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明小程序中 rpx 的原理,以及它与 px、rem 的区别。

参考答案: rpx(responsive pixel)是微信小程序推出的自适应单位。

原理:

  • 规定屏幕宽度为 750 rpx。
  • 在不同设备上,1 rpx 对应不同物理像素,实现屏幕适配。
  • 例如 iPhone 6 屏幕宽度 375px = 750 rpx,则 1 rpx = 0.5 px。

与 px 区别:

  • px 是绝对像素单位,不同设备显示大小可能不同。
  • rpx 是相对屏幕宽度的单位,自动适配。

与 rem 区别:

  • rem 依赖于根元素字体大小(html font-size)。
  • rpx 由小程序框架直接处理,开发者无需设置根字体。

使用建议:

  • 布局尺寸、字体大小优先使用 rpx。
  • 边框、阴影等不需要随屏幕缩放的使用 px。
  • 复杂布局可结合 flex、grid 使用。

注意:

  • rpx 只在小程序和 uni-app 等框架中有效。
  • H5 中需要转换工具。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

rpx 是小程序自适应单位,屏幕宽度固定 750 rpx,自动适配不同设备。px 是绝对像素,rem 依赖根字体大小,rpx 由框架直接处理。布局用 rpx,边框用 px。


FB-45-CO-B-009:微信小程序的登录流程是怎样的?前端如何配合后端完成登录?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:小程序 标签:微信小程序、登录、wx.login、openid、session 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序的登录流程,以及前端在其中扮演的角色。

参考答案: 微信小程序登录流程:

  1. 前端调用 wx.login

    • 获取临时登录凭证 code
    • code 有效期 5 分钟,只能使用一次。
  2. 前端将 code 传给后端

    • 通过 HTTPS 发送到自己的服务器。
  3. 后端用 code 换 openid/session_key

    • 后端调用微信接口 jscode2session
    • 获取 openidsession_key,可能还有 unionid
  4. 后端生成自定义登录态

    • 用 openid 生成 token 或 session。
    • 返回给前端保存。
  5. 前端保存登录态

    • 通常存在 storage 中,后续请求带上 token。
  6. 后续请求

    • 前端请求业务接口时带上 token。
    • 后端校验 token 识别用户。

安全注意:

  • session_key 不能返回给前端,必须放在后端。
  • 敏感接口前端调用前需校验登录态。
  • 使用 wx.checkSession 检查登录态是否过期。

示例:

js
wx.login({
  success: res => {
    wx.request({
      url: 'https://api.example.com/login',
      data: { code: res.code },
      success: r => wx.setStorageSync('token', r.data.token)
    });
  }
});

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序登录:前端 wx.login 拿 code,传给后端,后端用 code 换 openid 和 session_key,生成 token 返回前端保存。session_key 不能给前端,用 wx.checkSession 检查登录态。


FB-45-CO-B-010:微信小程序的授权机制有哪些变化?如何做好用户授权?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:小程序 标签:微信小程序、授权、隐私、getUserProfile 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序用户授权机制的变化,以及如何合理引导用户授权。

参考答案: 小程序授权机制变化:

  1. 旧版

    • wx.getUserInfo 可直接弹出授权框获取用户信息。
    • 很多小程序一进页面就弹授权,体验差。
  2. 新版

    • wx.getUserProfile 每次调用都需用户点击按钮触发。
    • 不能自动弹出,必须用户主动触发。
    • 获取头像昵称需使用头像昵称填写能力。
  3. 权限分类

    • 用户信息、地理位置、相册、相机、麦克风等。
    • 不同权限需分别申请。

合理引导授权:

  1. 需要时再申请

    • 在用户即将使用某功能时申请对应权限。
    • 例:点击“拍照”按钮时再申请相机权限。
  2. 说明用途

    • 申请前用弹窗或文案说明为什么需要该权限。
    • 例:“需要获取位置以推荐附近门店”。
  3. 处理拒绝

    • 用户拒绝后引导其到设置页开启。
    • 不强制,提供替代方案。
  4. 避免滥用

    • 不收集与功能无关的权限和信息。
    • 遵守隐私合规要求。
  5. 使用 open-data 替代

    • 只展示用户昵称头像时,可用 open-data 组件,无需授权。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序授权已从自动弹窗改为用户主动触发。要需要时再申请,说明用途,处理拒绝并提供替代方案,避免滥用,能用 open-data 展示就不授权。


FB-45-CO-B-011:微信小程序分包加载的作用和实现方式是什么?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:小程序 标签:微信小程序、分包、性能、加载 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序分包加载的作用,以及如何实现分包。

参考答案: 分包加载作用:

  • 减小小程序首次下载和启动时加载的包体积。
  • 将用户不常用的页面放到分包,按需加载。
  • 主包大小限制 2MB,总体大小限制 20MB(可能随平台变化)。

分包类型:

  1. 普通分包

    • 在 app.json 中声明 subpackages。
    • 用户进入分包页面时才下载。
  2. 独立分包

    • 不依赖主包即可运行。
    • 适合活动页、推广页等独立入口。
  3. 分包预下载

    • 配置 preloadRule,在进入某些页面时预下载分包。
    • 提升分包页面打开速度。

实现方式:

json
{
  "pages": ["pages/index/index"],
  "subpackages": [
    {
      "root": "packageA",
      "pages": ["pages/cat", "pages/dog"]
    }
  ],
  "preloadRule": {
    "pages/index/index": {
      "network": "all",
      "packages": ["packageA"]
    }
  }
}

最佳实践:

  • 按业务模块划分分包。
  • 主包只放启动必要页面和公共资源。
  • 对可能连续访问的分包配置预下载。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

分包加载减小了首次包体积,提升启动速度。有普通分包、独立分包、分包预下载。按业务模块划分,主包放必要页面和公共资源,对可能连续访问的分包预下载。


FB-45-CO-B-012:微信小程序的 storage 和 Web Storage 有什么区别?

题型:概念题 难度:🟢 基础 岗位层级:初级 面试知识域:小程序 标签:微信小程序、storage、本地存储、区别 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序的 wx.setStorage 与 Web 端的 localStorage/sessionStorage 的区别。

参考答案: 小程序 Storage 与 Web Storage 区别:

特性小程序 wx.setStorageWeb localStorage
存储位置本地文件系统浏览器本地
容量单个小程序 10MB 左右一般 5-10MB
同步/异步同步 Sync 和异步 API同步 API
数据类型支持对象直接存储只支持字符串
跨页面全局可用同源可用
清理策略小程序卸载或用户主动清理用户清理或过期策略

小程序 Storage API:

  • wx.setStorage / wx.setStorageSync
  • wx.getStorage / wx.getStorageSync
  • wx.removeStorage / wx.clearStorage

注意事项:

  • 不要存储敏感信息,如密码、token 长期有效建议配合后端校验。
  • 同步 API 会阻塞主线程,大数据量用异步。
  • 不同用户、不同小程序之间 storage 隔离。
  • 小程序更新不会自动清理 storage,需自己管理版本。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序 storage 存本地文件系统,容量约 10MB,有同步异步 API,支持对象。Web localStorage 一般 5 到 10MB,只支持字符串。不要存敏感信息,大数据用异步,注意版本管理。


FB-45-FS-P-006:微信小程序的双线程模型是什么?有什么影响?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、双线程、渲染、逻辑层 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请解释微信小程序的双线程模型,以及它对开发的影响。

参考答案: 微信小程序双线程模型:

  • 逻辑层:运行在 JavaScriptCore 中,执行 JS 代码,管理数据、状态、业务逻辑。
  • 视图层:运行在 WebView 中,负责 WXML/WXSS 渲染和事件响应。
  • 逻辑层和视图层通过 Native 层进行异步通信。

影响:

  1. setData 是跨线程通信

    • 每次 setData 都需要序列化和传输,有性能开销。
    • 应避免频繁和大批量 setData。
  2. DOM 操作受限

    • 不能直接操作 DOM,只能通过 setData 和 WXML 更新视图。
    • 获取节点信息需用 wx.createSelectorQuery
  3. JS 运行环境隔离

    • 无法使用 window、document 等浏览器全局对象。
    • 部分 npm 包依赖浏览器 API,需要适配。
  4. 数据安全

    • 逻辑层代码不在 WebView 中运行,降低被直接篡改的风险。
  5. 开发体验差异

    • 调试需要在开发者工具中分别查看逻辑层和视图层。
    • 部分浏览器调试技巧不适用于小程序。

优化方向:

  • 减少 setData 次数和数据量。
  • 避免在视图层执行复杂逻辑。
  • 使用自定义组件减少渲染范围。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序双线程模型是逻辑层在 JSCore,视图层在 WebView,通过 Native 异步通信。影响是 setData 有跨线程开销,不能操作 DOM,无 window/document,更安全。优化要减少 setData,避免视图层复杂逻辑,用自定义组件。


FB-45-FS-P-007:微信小程序的自定义组件渲染机制是什么?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、自定义组件、渲染、机制 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序自定义组件的渲染机制和关键特性。

参考答案: 微信小程序自定义组件渲染机制:

  1. Shadow DOM 类似隔离

    • 自定义组件有独立的模板、样式、逻辑。
    • 组件内部样式默认不影响外部,外部样式也不影响内部(除特殊配置)。
  2. 组件树

    • 页面和组件构成组件树。
    • 每个组件实例有独立的 data、properties、methods。
  3. 数据响应

    • 组件 data 变化触发组件内部重新渲染。
    • properties 变化也会触发更新。
  4. slot 机制

    • 支持默认 slot 和命名 slot。
    • 用于内容分发。
  5. 样式隔离

    • 默认组件样式隔离。
    • 可通过 options.styleIsolation 调整:isolated、apply-shared、shared。
  6. 组件生命周期

    • createdattachedreadymoveddetached
    • lifetimes 字段统一声明。
  7. 性能优化

    • 组件粒度细化可减少不必要的渲染范围。
    • 但过度拆分会增加通信开销,需权衡。

示例配置:

js
Component({
  options: {
    styleIsolation: 'isolated',
    multipleSlots: true
  },
  properties: { title: String },
  data: { count: 0 },
  methods: { onTap() { ... } }
});

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序自定义组件有独立模板样式逻辑,类似 Shadow DOM 隔离,有组件树、数据响应、slot、样式隔离配置、生命周期。合理拆分组件可优化渲染,但过度拆分增加开销。


FB-45-FS-P-008:微信小程序的启动性能优化有哪些手段?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、启动性能、优化、冷启动 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明优化微信小程序冷启动性能的主要手段。

参考答案: 小程序启动性能优化:

  1. 减小包体积

    • 分包加载,主包只保留必要页面。
    • 压缩图片、JS、JSON。
    • 删除无用代码和资源。
  2. 优化代码注入

    • 延迟加载非必要 JS。
    • 使用按需注入 lazyCodeLoading
  3. 减少首屏 setData

    • 首屏数据在 onLoad 前准备好。
    • 避免多次 setData。
  4. 预加载数据

    • 使用 wx.preloadPage 或自定义预加载逻辑。
    • 在用户可能进入页面前提前请求数据。
  5. 骨架屏

    • 首屏用骨架屏占位,提升 perceived performance。
  6. 缓存策略

    • 合理利用 storage 缓存首屏数据。
    • 先展示缓存,再异步更新。
  7. 减少自定义组件数量

    • 首屏组件过多会增加渲染时间。
    • 合理控制组件层级。
  8. 避免同步阻塞

    • 减少同步 Storage 和复杂计算。
  9. 利用官方能力

    • 使用 初始渲染缓存按需注入分包预下载 等官方优化能力。
  10. 性能分析

    • 用微信开发者工具性能面板分析启动耗时。
    • 针对性优化。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序启动优化要减小包体积、分包、按需注入、减少首屏 setData、预加载数据、骨架屏、缓存、控制组件数量、避免同步阻塞、用官方能力、用开发者工具分析。


FB-45-FS-P-009:微信小程序的长列表优化方案有哪些?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、长列表、性能、虚拟列表 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中长列表场景的优化方案。

参考答案: 长列表优化方案:

  1. 分页加载

    • 不要一次性加载全部数据。
    • 触底或滚动时加载更多。
  2. recycle-view

    • 微信官方提供的可回收长列表组件。
    • 只渲染可视区域节点,复用 item。
  3. 虚拟列表自研

    • 根据滚动位置计算渲染窗口。
    • 只渲染可视区及缓冲区的 item。
  4. 图片懒加载

    • 使用 lazy-load 属性。
    • 非可视区图片不加载。
  5. 减少 item 复杂度

    • 简化每个 item 的 WXML 结构和样式。
    • 避免嵌套过深。
  6. 避免全量 setData

    • 新增数据时只 append,不重新 setData 整个列表。
  7. 使用 key

    • 列表项设置稳定唯一的 key,帮助框架 diff。
  8. 预加载图片

    • 对即将进入可视区的图片提前加载。
  9. 分页渲染

    • 一次渲染少量数据,避免一次性渲染大量节点导致卡顿。
  10. 避免复杂动画

    • 列表项内避免复杂 CSS 动画和频繁 setData。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

长列表优化要分页加载,用 recycle-view 或自研虚拟列表,图片懒加载,减少 item 复杂度,避免全量 setData,用 key,预加载即将进入可视区的图片,避免复杂动画。


FB-45-FS-P-010:微信小程序的跨平台框架(如 Taro、uni-app)有哪些优缺点?

题型:框架原理题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:跨平台、Taro、uni-app、小程序 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明使用 Taro、uni-app 等跨平台框架开发小程序的优缺点,以及选择建议。

参考答案: 跨平台框架优缺点:

优点

  1. 一套代码多端运行

    • 可同时输出微信小程序、支付宝小程序、H5、App 等。
    • 降低多平台开发和维护成本。
  2. 开发体验接近前端主流

    • 可用 React/Vue 语法、npm 生态、现代构建工具。
    • 降低前端学习成本。
  3. 组件和工具丰富

    • 大量跨端 UI 组件库和插件。
  4. 工程化能力

    • 更好的 TypeScript 支持、代码规范、测试工具。

缺点

  1. 平台差异屏蔽不完全

    • 各小程序平台 API、组件、能力有差异。
    • 复杂场景仍需写条件编译或平台特定代码。
  2. 性能损耗

    • 框架运行时有一定开销。
    • 极端性能场景可能不如原生。
  3. 排错难度

    • 编译后代码调试困难。
    • 框架 Bug 可能影响项目。
  4. 更新滞后

    • 新平台能力需要框架适配,可能有滞后。

选择建议:

  • 多平台需求强、团队熟悉 React/Vue:选跨平台框架。
  • 单平台、极致性能、快速接入新能力:选原生或轻量框架。
  • 大型项目要评估框架成熟度和社区支持。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

跨平台框架优点是一套代码多端、接近主流前端体验、组件丰富;缺点是平台差异屏蔽不完全、性能开销、调试难、新能力滞后。多平台强选跨平台,单平台性能极致选原生。


FB-45-PE-A-006:微信小程序首屏加载慢,如何系统排查?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、首屏、性能、排查 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序首屏加载慢时,你会如何系统排查和优化。

参考答案: 首屏加载慢排查步骤:

  1. 使用性能面板

    • 微信开发者工具 → 性能面板 → 查看启动耗时、渲染耗时、JS 执行耗时。
  2. 分析包体积

    • 用开发者工具代码依赖分析。
    • 查看主包和分包大小,定位大文件。
  3. 检查网络请求

    • 首屏是否依赖多个串行请求?
    • 能否并行、预加载或缓存?
  4. 检查 setData

    • 首屏 setData 次数和数据量是否过大?
    • 能否合并或减少?
  5. 检查组件层级

    • 首屏 WXML 节点数是否过多?
    • 能否简化结构?
  6. 检查图片资源

    • 图片是否过大、过多、未压缩?
    • 是否使用了懒加载?
  7. 检查同步操作

    • 启动时是否有大量同步 Storage 或复杂计算阻塞?
  8. 优化方案

    • 分包、压缩、骨架屏、缓存、预加载、减少组件、合并 setData。
  9. A/B 验证

    • 对比优化前后性能数据。
    • 用真实用户数据验证效果。

示例:某小程序首屏有 5 个接口串行请求,优化为 2 个并行 + 3 个延迟加载,首屏时间从 3.5 秒降到 1.8 秒。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

首屏慢用性能面板分析启动、渲染、JS 耗时,分析包体积,检查网络请求串并行,setData 次数,组件层级,图片资源,同步阻塞。然后分包、压缩、骨架屏、缓存、预加载、合并 setData,最后 A/B 验证。


FB-45-PE-A-007:微信小程序如何避免 setData 性能问题?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、setData、性能、优化 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明在小程序开发中,常见的 setData 性能问题及优化方法。

参考答案: 常见 setData 性能问题及优化:

  1. 频繁调用

    • 问题:多次连续 setData 增加通信次数。
    • 优化:合并为一次 setData。
  2. 大数据量

    • 问题:一次性 setData 大量数据。
    • 优化:只更新变化字段,分页/虚拟列表。
  3. 嵌套对象全量更新

    • 问题:setData({ user: {...} }) 每次更新整个对象。
    • 优化:用路径更新具体字段。
  4. 在滚动等高频事件中 setData

    • 问题:导致卡顿。
    • 优化:节流、防抖,或用 CSS 变量替代。
  5. setData 后立即读取 DOM

    • 问题:视图未更新,读取结果不准确。
    • 优化:使用 wx.nextTick
  6. 无关数据污染

    • 问题:把不需要渲染的数据也放入 data。
    • 优化:纯逻辑数据放在 this 上或其他状态管理。
  7. 列表无 key

    • 问题:框架 diff 效率低。
    • 优化:列表项设置唯一 key。

示例:

js
// 优化前
this.setData({ a: 1 });
this.setData({ b: 2 });

// 优化后
this.setData({ a: 1, b: 2 });

// 路径更新
this.setData({ 'list[0].name': 'new' });

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

setData 常见问题:频繁调用、大数据量、嵌套对象全量更新、高频事件 setData、读取 DOM 时机、无关数据污染、列表无 key。优化要合并、路径更新、分页虚拟列表、节流、nextTick、数据分离、用 key。


FB-45-PE-A-008:微信小程序的渲染层和逻辑层通信优化有哪些?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、通信、优化、双线程 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明如何优化小程序渲染层和逻辑层之间的通信性能。

参考答案: 通信优化方法:

  1. 减少 setData 次数

    • 合并数据更新,避免连续调用。
  2. 减少 setData 数据量

    • 只传视图需要的数据。
    • 避免传递大对象和整个列表。
  3. 使用纯数据字段

    • pureDataPattern 让某些字段不触发视图更新。
    • 适合纯逻辑数据。
  4. 使用 observers 谨慎

    • observers 可能引发连锁更新。
    • 避免复杂计算和频繁触发。
  5. 合理使用自定义组件

    • 组件隔离渲染范围,减少全页面重渲染。
    • 但组件过多会增加通信节点。
  6. 避免跨层通信

    • 父子组件通过 properties 和事件通信。
    • 少用全局事件总线。
  7. 减少节点数量

    • 复杂 WXML 结构增加渲染和通信成本。
    • 简化模板,减少嵌套。
  8. 使用 WXSS 变量

    • 部分动画和样式变化可用 CSS 变量或 transition,不通过 setData。
  9. 延迟非关键更新

    • 首屏关键数据优先,其他数据延迟更新。
  10. 利用 nextTick

    • 批量更新后在 nextTick 中读取最新视图状态。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

通信优化要减少 setData 次数和数据量,用纯数据字段,谨慎用 observers,合理拆分组件,避免跨层通信,减少节点,用 CSS 做动画,延迟非关键更新,用 nextTick。


FB-45-PE-A-009:微信小程序如何做图片资源优化?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、图片、优化、资源 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中图片资源的优化策略。

参考答案: 小程序图片优化策略:

  1. 压缩图片

    • 使用 TinyPNG、ImageOptim 等工具压缩。
    • 平衡画质和体积。
  2. 使用合适格式

    • WebP 比 JPG/PNG 体积小很多。
    • 小程序支持 WebP,优先使用。
  3. CDN 加速

    • 图片放 CDN,就近分发。
    • 配置合适的缓存策略。
  4. 懒加载

    • 使用 image 组件的 lazy-load 属性。
    • 长列表和瀑布流必须懒加载。
  5. 响应式图片

    • 根据屏幕宽度加载不同尺寸图片。
    • 使用图片服务裁剪参数生成合适尺寸。
  6. 占位图

    • 加载前显示占位图或骨架屏。
    • 提升 perceived performance。
  7. 雪碧图/图标字体

    • 小图标合并为雪碧图或使用 iconfont。
    • 减少请求数。
  8. 避免 base64

    • base64 图片会增加包体积和解析成本。
    • 只在极小图标时考虑。
  9. 预加载关键图片

    • 对首屏关键图片提前加载。
  10. 回收不可见图片

    • 长列表中离开可视区的图片资源及时释放。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

图片优化要压缩、用 WebP、放 CDN、懒加载、响应式尺寸、占位图、小图标合并、避免 base64、预加载关键图、长列表回收不可见图片。


FB-45-PE-A-010:微信小程序如何做网络请求优化?

题型:性能优化题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、网络请求、优化、性能 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中网络请求的优化策略。

参考答案: 网络请求优化策略:

  1. 合并请求

    • 将多个小请求合并为一次批量请求。
    • 减少 HTTP 连接和通信开销。
  2. 并行请求

    • 无依赖的请求同时发起,避免串行等待。
    • 使用 Promise.all。
  3. 缓存策略

    • 合理利用 storage 缓存不常变数据。
    • 配置 HTTP 缓存头。
  4. 数据压缩

    • 后端返回 JSON 开启 gzip/brotli 压缩。
    • 减少传输体积。
  5. 请求去重

    • 相同请求在 pending 状态时复用结果。
    • 避免重复请求。
  6. 预加载

    • 预测用户行为,提前请求可能需要的接口。
  7. 分页加载

    • 列表数据分页返回,避免一次性大数据。
  8. 接口精简

    • 后端接口只返回前端需要的数据字段。
    • 避免 over-fetching。
  9. 失败重试

    • 弱网环境下合理重试,提升成功率。
    • 注意重试次数和间隔。
  10. 监控

    • 监控接口耗时、成功率、错误率。
    • 针对性优化慢接口。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

网络请求优化要合并请求、并行无依赖请求、缓存、数据压缩、请求去重、预加载、分页、接口精简、失败重试、监控慢接口。


FB-45-SC-P-008:微信小程序如何实现一个复杂的表单页面?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、表单、复杂、实现 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明在微信小程序中实现一个字段多、校验复杂、可动态增删的表单页面的方案。

参考答案: 复杂表单实现方案:

  1. 数据结构设计

    • 用对象存储表单数据,字段名与表单字段对应。
    • 动态表单项用数组管理。
  2. 组件化

    • 将通用表单项封装为自定义组件。
    • 如 FormInput、FormPicker、FormUploader。
    • 组件内部处理展示和基础校验。
  3. 表单校验

    • 使用校验库(如 async-validator)或自研校验规则引擎。
    • 支持字段级校验和表单级校验。
    • 实时校验与提交校验结合。
  4. 动态增删

    • 动态项用数组 + 索引管理。
    • 增删时更新数组并 setData。
    • 注意 key 的唯一性。
  5. 性能优化

    • 表单项过多时考虑分页或分组展示。
    • 避免每次输入都 setData 整个表单。
    • 可用防抖或只更新当前字段。
  6. 数据持久化

    • 支持草稿自动保存到 storage。
    • 防止用户误操作丢失数据。
  7. 提交处理

    • 提交前全量校验。
    • 失败时滚动到第一个错误项。
    • 提交中禁用按钮防止重复提交。
  8. 可复用架构

    • 抽象表单配置,用 JSON 描述字段、类型、校验规则。
    • 渲染引擎根据配置生成表单。

示例:

js
formData: {
  name: '',
  contacts: [{ name: '', phone: '' }] // 动态数组
}

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

复杂表单要设计好数据结构,组件化表单项,用校验库,动态数组管理增删,性能上用防抖和字段级更新,草稿持久化,提交前全量校验并滚动到错误项,可抽象为配置驱动表单。


FB-45-SC-P-009:微信小程序如何做状态管理?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、状态管理、全局、数据 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中常见的状态管理方案及其适用场景。

参考答案: 小程序状态管理方案:

  1. 全局变量 / App globalData

    • 适合简单全局状态,如用户信息、配置。
    • 缺点:无响应式,需手动同步。
  2. 页面间传参

    • URL query、eventChannel、getCurrentPages。
    • 适合简单跨页面通信。
  3. Storage

    • 适合持久化数据,如登录态、用户偏好。
    • 注意容量和敏感信息。
  4. MobX / Redux 类库

    • 适合中大型应用。
    • 提供响应式、可预测的状态管理。
    • 如 mobx-miniprogram、redux-miniprogram。
  5. 自研状态管理

    • 基于发布订阅或 EventBus。
    • 适合团队有特定需求时。
  6. Hooks/Composition API

    • 跨端框架中可用响应式 API。
    • 如 Taro 3 配合 React/Vue 的状态管理。

选择建议:

  • 小型项目:globalData + Storage 足够。
  • 中大型项目:使用 MobX 等成熟方案或自研。
  • 跨端项目:根据框架选择 React/Vue 生态方案。

注意事项:

  • 避免全局状态滥用,导致数据流混乱。
  • 状态变更要有明确来源和监听机制。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序状态管理有 globalData、页面传参、Storage、MobX/Redux、自研、跨端框架方案。小项目用 globalData 加 Storage,中大型用 MobX 或自研。避免滥用全局状态。


FB-45-SC-P-010:微信小程序如何实现支付功能?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、支付、wx.requestPayment、安全 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序支付功能的完整流程和前端注意事项。

参考答案: 微信小程序支付流程:

  1. 用户下单

    • 前端将商品信息、数量等传给后端。
  2. 后端创建订单

    • 后端调用微信支付统一下单接口。
    • 获取 prepay_id。
  3. 后端生成支付参数

    • 用 prepay_id 生成 timeStampnonceStrpackagesignTypepaySign
    • 返回给前端。
  4. 前端调起支付

    • 调用 wx.requestPayment({...})
    • 用户完成支付操作。
  5. 支付结果处理

    • success/fail/complete 回调。
    • 最终支付结果以服务端异步通知为准。
  6. 后端校验并通知

    • 微信支付回调通知后端。
    • 后端更新订单状态,通知前端。

前端注意事项:

  • 支付参数必须由后端生成,前端不能自己签名。
  • package 值格式为 prepay_id=xxx
  • 支付回调结果不可靠,需主动查询订单状态或等待服务端通知。
  • 注意处理用户取消支付、支付失败等情况。
  • 支付功能需先开通微信支付商户号并配置。

安全:

  • 所有敏感操作在后端完成。
  • 前端只负责调起 SDK。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序支付:前端下单传后端,后端创建订单并调用微信统一下单,生成支付参数返回前端,前端 wx.requestPayment 调起,结果以服务端通知为准。参数必须由后端生成,前端只调 SDK。


FB-45-SC-P-011:微信小程序如何做版本更新处理?

题型:场景设计题 难度:🔴 深入 岗位层级:专家 面试知识域:小程序 标签:微信小程序、版本更新、热更新、管理 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序的版本更新机制,以及前端如何处理新版本发布后的兼容和提示。

参考答案: 小程序版本更新机制:

  1. 微信自动更新

    • 微信客户端会在后台静默更新小程序代码包。
    • 用户下次冷启动时使用新版本。
  2. getUpdateManager

    • 小程序提供 wx.getUpdateManager API。
    • 可监听新版本下载完成,提示用户重启。
  3. 强制更新

    • 新版本下载完成后,调用 applyUpdate 强制重启。
    • 适合重要修复或协议变更。

前端处理建议:

  1. 启动时检查更新

    js
    const updateManager = wx.getUpdateManager();
    updateManager.onCheckForUpdate(res => {
      if (res.hasUpdate) { ... }
    });
  2. 下载完成提示

    • onUpdateReady 时提示用户重启应用。
    • 或自动调用 applyUpdate
  3. 更新失败处理

    • onUpdateFailed 时记录日志,提示用户稍后重试。
  4. 数据兼容

    • 新版本发布前要考虑旧版本 storage 数据兼容。
    • 可加版本号字段,启动时做数据迁移。
  5. 灰度发布

    • 微信支持分阶段发布,先小范围验证。
    • 发现问题及时撤回。
  6. 版本提示

    • 对不支持的新能力,低版本基础库需提示用户升级微信。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序微信会自动更新,前端可用 getUpdateManager 检查更新、提示重启或强制更新。启动时检查,下载完成提示,失败处理,注意 storage 数据兼容,用灰度发布,低版本基础库提示升级微信。


FB-45-SE-A-008:微信小程序有哪些常见安全漏洞及防护措施?

题型:安全题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、安全、漏洞、防护 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序中常见的安全风险和前端防护措施。

参考答案: 小程序常见安全风险及防护:

  1. XSS

    • 风险:渲染用户输入时执行恶意脚本。
    • 防护:框架默认转义,避免使用 rich-text 渲染不可信 HTML;对用户输入做过滤。
  2. 敏感信息泄露

    • 风险:代码中硬编码 appid、secret、token。
    • 防护:敏感信息放在后端,前端不存储长期有效 token。
  3. 接口未授权访问

    • 风险:接口缺乏身份校验。
    • 防护:后端校验用户身份和权限,前端仅做体验层校验。
  4. 数据篡改

    • 风险:用户篡改本地数据影响业务。
    • 防护:关键数据校验放在后端,前端数据不可信。
  5. 第三方依赖漏洞

    • 风险:npm 包或插件有安全漏洞。
    • 防护:定期扫描依赖,审查第三方代码。
  6. CSRF

    • 风险:跨站请求伪造。
    • 防护:关键操作加 token 或二次验证,后端校验来源。
  7. 反编译风险

    • 风险:小程序代码可被反编译。
    • 防护:核心逻辑放后端,前端只做展示和交互。
  8. 滥用权限

    • 风险:过度申请用户权限。
    • 防护:按需申请,明确告知用途。

安全原则:前端不可信,关键校验和逻辑放在后端。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序常见安全风险有 XSS、敏感信息泄露、接口未授权、数据篡改、依赖漏洞、CSRF、反编译、滥用权限。防护措施包括框架转义、敏感信息放后端、后端校验权限、定期扫描依赖、按需申请权限。前端不可信,关键逻辑在后端。


FB-45-SE-A-009:微信小程序如何防止代码被反编译后泄露业务逻辑?

题型:安全题 难度:🟡 进阶 岗位层级:高级 面试知识域:小程序 标签:微信小程序、反编译、代码保护、安全 出现频率:高频 预计回答时长:5-8 分钟

题目描述: 请说明微信小程序代码反编译风险及前端防护策略。

参考答案: 小程序反编译风险:

  • 小程序代码包可被解压和反编译。
  • 业务逻辑、接口地址、密钥可能泄露。

防护策略:

  1. 核心逻辑后移

    • 把核心算法、敏感逻辑放在服务端。
    • 前端只负责展示和简单交互。
  2. 不硬编码敏感信息

    • appid、secret、token、加密 key 不要写在前端。
    • 接口地址可配置,但关键校验在后端。
  3. 代码混淆

    • 使用 webpack 等构建工具进行代码混淆和压缩。
    • 增加反编译后阅读难度。
  4. 接口安全

    • 接口请求签名、防重放、频率限制。
    • 即使接口地址泄露,也无法直接调用。
  5. 加密敏感数据

    • 必须存储在本地的敏感数据加密。
    • 如用户 token 可配合后端校验。
  6. 合法合规

    • 不存储用户敏感信息到本地。
    • 遵守数据安全和隐私法规。
  7. 监控异常

    • 监控接口异常调用、爬虫行为。
    • 及时发现和封禁。

注意:没有绝对防反编译的方法,关键是让反编译后的代码价值最小化。

评分维度

  • 能准确理解问题并给出结构化回答(40%)
  • 能结合实际案例或数据说明(30%)
  • 能体现业务思维与技术落地的结合(30%)

常见错误

  • 回答过于空泛,缺乏具体做法。
  • 只谈技术实现,忽略业务目标和约束。
  • 没有考虑风险和可执行性。

口头回答版

小程序代码可被反编译,防护策略是核心逻辑后移,不硬编码敏感信息,代码混淆,接口签名和频率限制,加密本地敏感数据,合规存储,监控异常。没有绝对防反编译,关键是降低泄露价值。


基于 MIT 协议发布