Senior Fullstack SWE · HM Phone Coding

Apple Fullstack:给图片网站 URL,如何在应用里列出 10 张图

按可见题意设计请求、解析、加载与错误状态;用显式训练 API 展示前端实现,同时标明原网站协议缺失。

题目重点:按可见题意设计请求、解析、加载与错误状态;用显式训练 API 展示前端实现,同时标明原网站协议缺失。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 示例代码假设 GET 给定 URL 返回 JSON `{images:[{url:string}]}`;这是训练接口,并非原网站事实。若给的是 HTML 网页,先确认许可、CORS 与是否有公开 API,不能用 JSON 解析强行冒充。
  • 筛掉无效 URL 后最多返回 10 张;不足 10 张就显示实际数量并提示,不从别处补图。浏览器图片加载还可能独立失败。

解题路线

  1. 先问 URL 是 JSON API、网页还是图片资源,是否允许浏览器跨域请求,是否需认证/分页/代理;同一‘列十张图’要求会因协议不同而改变实现。
  2. 将请求与展示拆开:请求端使用可注入 fetch、校验响应并解析最多十个安全 HTTP(S) URL;UI 维护 idle/loading/success/error 状态,在 URL 改变或组件卸载时取消旧请求。
  3. 用稳定图片 URL 或服务端 ID 作 key,逐项给 alt 文本或注明装饰图;图片采用响应式布局、lazy loading 和单图错误占位。不要假设请求成功就表示图片已下载。
  4. 若返回分页,按有界页数逐页取直到十张或无下一页,并防重复/循环 cursor;本训练代码不实现未知的原站分页协议。

手动走一遍

训练返回 12 个可用图片 URL、1 个 `javascript:` 地址时,过滤非法协议后取前 10 个;若网络 503,整体显示可重试状态;若第 4 张图片资源 404,只替换该卡片,不清空其他九张。

JavaScript 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

// Training contract only: GET pageUrl -> { images: [{ url: string }, ...] }.
export async function loadTenImages(pageUrl, fetcher = fetch, signal) {
  const response = await fetcher(pageUrl, { signal });
  if (!response.ok) throw new Error(`image list request failed: ${response.status}`);
  const body = await response.json();
  if (!body || !Array.isArray(body.images)) throw new TypeError("images array required");
  const urls = [];
  for (const entry of body.images) {
    if (!entry || typeof entry.url !== "string") continue;
    try {
      const url = new URL(entry.url, pageUrl);
      if (url.protocol !== "https:" && url.protocol !== "http:") continue;
      urls.push(url.href);
    } catch {
      // Skip malformed image URLs; the UI can report fewer than ten.
    }
    if (urls.length === 10) break;
  }
  return urls;
}

复杂度

若响应含 m 条记录,只扫描直到收集十条或耗尽,时间 O(min(m,命中第十条的位置)),输出最多 O(10);网络和图片解码时间另计。题目未明确图片体积或 API 分页规模。

易错点与追问

容易失分的边界

  • 把未公开网页 URL 编成固定 JSON schema。
  • 将任意字符串直接放入 img src 而不校验协议。
  • 组件重复渲染时发起多个相互覆盖的请求。
  • 只处理 fetch 失败,不处理图片本身的加载失败。
  • 图片没有可访问名称或移动端布局。

继续深挖

  • 如果给的是 HTML 网页且浏览器 CORS 禁止,产品与服务端怎么改?
  • API 每页最多五张,怎样停在第十张且避免循环 cursor?
  • URL 改变时如何防旧请求结果覆盖新列表?
  • 十张图的 LCP 与带宽如何优化?
✓已复制微信号!