know

了解的工具

# 1. 为什么推荐将静态资源放到 CDN 上?

# 1.1. 静态资源是什么

静态资源是指在不同请求中访问到的数据都相同的静态文件。例如:图片、视频、网站中的文件(html、css、js)、软件安装包、apk 文件、压缩包文件等。

# 1.2. 动态资源

动态资源是指在不同请求中访问到的数据不相同的动态内容。例如:网站中的文件(asp、jsp、php、perl、cgi)、API 接口、数据库交互请求等。

# 2. CDN 是什么

CDN(内容分发网络,Content Delivery Network)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。

CDN 加速的本质是缓存加速。 将服务器上存储的静态内容缓存在 CDN 节点上,当访问这些静态内容时,无需访问服务器源站,就近访问 CDN 节点即可获取相同内容,从而达到加速的效果,同时减轻服务器源站的压力。

CDN 应用广泛,解决因分布、带宽、服务器性能带来的访问延迟问题,适用于站点加速、点播、直播等场景。使用户可就近取得所需内容,提高网站响应速度和成功率。

由于访问动态内容时,每次都需要访问服务器,由服务器动态生成实时的数据并返回。因此 CDN 的缓存加速不适用于加速动态内容,CDN 无法缓存实时变化的动态内容。对于动态内容请求,CDN 节点只能转发回服务器源站,没有加速效果。

# 3. CDN 的作用

  1. 加速网站的访问 用户可就近访问 CDN 节点,提升访问速度。

  2. 实现跨运营商、跨地域的全网覆盖 解决区域性无法访问问题,合理部署 CDN 边缘节点,平衡源站流量。

  3. 保障网站安全 CDN 的负载均衡和分布式存储技术可加强网站可靠性,防御大部分互联网攻击。

  4. 异地备援 某个服务器故障时,系统自动调用其他健康节点,提升可靠性。

  5. 节约成本投入 使用 CDN 可全国铺设,无需自购服务器和托管运维,节省人力和财力。

  6. 专注业务本身 CDN 厂商一般提供一站式服务和 7x24 运维监控,用户可专注核心业务。

# 4. CDN 工作原理

  1. 用户点击网站内容 URL,经过本地 DNS 解析,最终将域名解析权交给 CNAME 指向的 CDN 专用 DNS 服务器。
  2. CDN 的 DNS 服务器返回 CDN 全局负载均衡设备 IP 地址给用户。
  3. 用户向 CDN 全局负载均衡设备发起内容 URL 访问请求。
  4. 全局负载均衡设备根据用户 IP 和请求内容,选择区域负载均衡设备,告知用户向该设备发起请求。
  5. 区域负载均衡设备为用户选择合适的缓存服务器(依据用户 IP、内容名称、服务器负载等)。
  6. 全局负载均衡设备返回缓存服务器 IP 给用户。
  7. 用户向缓存服务器发起请求,缓存服务器响应并传送内容。如果没有内容,则向上级缓存或源站请求。

DNS 服务器根据用户 IP,将域名解析成相应节点的缓存服务器 IP,实现用户就近访问。使用 CDN 服务的网站,只需将域名解析权交给 CDN 的 GSLB 设备,将需要分发的内容注入 CDN,即可实现内容加速。

CDN原理示意图

# 5. 当没有 CDN 时

B/S 架构下,用户访问网站流程:

  1. 用户在浏览器输入网站域名。
  2. 浏览器向本地 DNS 请求解析。
  3. 本地 DNS 有缓存则直接响应,没有则递归请求整个 DNS 系统,获得结果后反馈给浏览器。
  4. 浏览器得到域名解析结果(IP 地址)。
  5. 浏览器向服务器请求内容。
  6. 服务器将内容传送给浏览器。

总结: CDN 能有效提升静态资源访问速度、降低源站压力、提升安全性和可靠性,是现代网站推荐的静态资源分发方案。

# 6. 说说你对跨平台的理解

我们知道,CPU 有不同的架构和指令集,上层也有不同的操作系统,一个系统的可执行文件在另一个系统上就是不可执行的,比如 Windows 的 exe 文件在 Mac 上就不能直接执行。不同的系统就是不同的运行平台。可执行文件是不跨平台的。

不同平台提供的 API 不同,所以代码逻辑可能也不同,需要不同平台单独维护代码。这样就带来了几个问题:

  • 多平台各自开发,怎么保证功能是一致的
  • 多平台各自开发,那是不是得各自测试,开发和测试的人力都是多份的

所以出现了跨平台的一些技术,目标是一份代码跑在任意平台。

我们先来看一些各领域的跨平台方案:

# 6.1. 浏览器

操作系统不同,浏览器上跑的网页的代码确实同一份。浏览器就是一种历史悠久的跨平台方案。

网页跨平台不意味着浏览器也是跨平台的,浏览器的可执行文件还是每个平台单独开发和编译的,但是他们支持的网页解析逻辑一样,这样上面跑的网页就是跨平台的。

浏览器提供了一个容器,屏蔽了底层差异,提供了统一的 API(DOM API),这样就可以实现同一份代码跑在不同平台的统一的容器里。这个容器叫做浏览器引擎,由 JS 引擎、渲染引擎等构成。

浏览器跨平台原理

# 6.2. Docker

Docker 是一种虚拟化技术,可以在操作系统之上加一个虚拟层,在这层之上划分一到多个容器,容器里再去跑系统、app,这样可以实现硬件和软件的分离,动态分配硬件资源给容器,并且方便 app 运行环境的整体迁移(保存成镜像)。

docker原理

Docker 很明显也是一种跨平台技术,同一个镜像可以跑在任何操作系统的 Docker 上。只要不同操作系统实现同样的容器即可。

# 6.3. JVM

Java 是一门编译 + 解释的语言,Java 源码编译成字节码,然后字节码直接在 VM 上解释执行。

Java 为什么这么火呢?主要是因为跨平台。

C、C++ 这种语言写的代码需要编译成不同操作系统上的可执行文件来跑,而且每个平台的代码可能还不一样,需要写多份。

Java 因为提供了 JVM 容器,只要把源码编译成 JVM 能解释的字节码就行了,而且 JDK 提供了统一的 API,分别由不同操作系统的底层 API 来实现,这样对于 Java 代码来说,不同操作系统的代码是一致的。

jvm原理

JVM 也是通过容器的技术实现了一份代码跑在多个平台,而且 JRE 提供了统一的 API,屏蔽掉了底层的差异。

# 6.4. Node、Deno

Node 和 Deno 也是跨平台的技术,通过提供一套一致的 API,让其上的 JS 代码可以跨平台。这些 API 也是不同平台各自实现的。

node跨平台原理

# 7. Electron

Electron 内置了 Chromium,并为其注入了 Node 的 API 和一些 GUI 相关的 API,是基于两大跨平台技术综合而成的跨平台方案。基于这些方案的组合使得 Electron 支持用前端技术开发桌面端。

electron原理

# 8. 跨平台方案的优缺点

跨平台方案的优点很明显,就是一份代码跑在不同平台的同样的容器内,不用不同平台单独开发,节省成本。

但是跨平台方案也有缺点:

  • 因为多了一层容器,所以性能相比直接调用系统 API 会有所下降
  • 为了实现多平台的一致,需要提供一套统一的 API,这套 API 有两个难题:
    • API 怎么设计。要综合不同平台的能力,取一个合适的集合来实现。设计上有一定难度。Node、Deno、Java 都抽象了操作系统的能力,提供了各自的跨平台 API
    • 部分 API 很难做到多平台的一致性
    • 当容器没有提供的能力需要扩展的时候比较麻烦,比如 JS 引擎的 bridge、JVM 的 JNI、Node 的 C++ addon 等都是为这个容器扩展能力的方式

# 9. npm 和 yarn 有哪些不一样的地方?

# 9.1. npm 的配置优先级为:

项目级的.npmrc 文件 > 用户级的 .npmrc 文件 > 全局级的 .npmrc > npm 内置的 .npmrc 文件 早期 npm 的问题:

  1. 依赖包会出现重复,形成嵌套地狱,导致依赖包过多,安装速度慢,影响开发效率且占据了大量的空间资源。
  2. 因为安装的依赖重复,会造成在安装依赖时,安装时间过长,不同开发者在同一个项目下,依赖包版本不一致,导致项目运行异常。
  3. 因为目录层级过深,导致文件路径过长,会在 windows 系统下删除 node_modules 文件,出现删除不掉的情况。

# 9.2. yarn 的优点:

  1. 采用模块扁平化的安装模式
  2. 网络性能更好: yarn 采用了请求排队的理念,类似于并发池连接,能够更好的利用网络资源;同时也引入了一种安装失败的重试机制。
  3. 缓存机制: yarn 缓存了依赖包,避免重复下载,加快了安装速度。
  4. 安全性: yarn 采用了校验机制,确保安装的依赖包是安全的。
  5. 易用性: yarn 采用了命令行的方式,使得安装依赖包更加简单。

# 10. 说说你对 git rebase 和 git merge 的理解?以及它们的区别?

git rebase 和 git merge 都是用来合并分支的命令。

git rebase 的原理是:

  1. 把当前分支的提交历史保存为一个新的分支。
  2. 切换到目标分支。
  3. 把目标分支的提交历史保存为一个新的分支。
  4. 把当前分支的提交历史和目标分支的提交历史合并。
  5. 推送到远程仓库。

merge 合并分支会新增一个 merge commit,然后将两个分支的历史联系起来。 rebase 会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交, 主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge 所需的不必要的合并提交

# 11. babel-polyfill 有什么用?

babel-polyfill 是一个垫片库,它是 babel 的一部分,作用是为浏览器提供一些 ES6 环境中缺失的一些 API。

比如 Promise、Map、Set、Symbol、Proxy、Reflect 等。

上次更新: