智慧园区前端技能

1.websocket

WebSocket 是一种在单个TCP 连接上进行全双工通信的协议。

  • 全双工通信:允许服务器和客户端在同一连接上同时、主动地发送和接收数据。

  • 持久连接:只需一次握手便可建立长久连接,无需每次数据传输都重新建立连接。

  • 低延迟与低开销:数据传输时不需要携带冗长的 HTTP 头部信息,WebSocket 的帧头部非常轻量(仅 2~14 字节),极大节省了带宽。

  • 二进制支持:除了文本,还能更轻松地处理二进制数据(如 ArrayBuffer)。

连接建立过程(握手)

WebSocket 并非直接建立连接,而是通过 HTTP 协议进行协议升级

  • 客户端发起一个标准的 HTTP GET 请求,请求头包含 Upgrade: websocketConnection: Upgrade,以及一个随机生成的 Sec-WebSocket-Key

  • 服务端如果支持,会返回 101 Switching Protocols 状态码,并在响应头中返回经过计算的 Sec-WebSocket-Accept 值。

  • 握手成功后,底层 TCP 连接保留,但应用层协议从HTTP切换为WebSocket

核心事件与 API

在浏览器端,WebSocket 对象提供了四个核心事件来管理连接生命周期:

  • onopen:连接成功建立时触发。

  • onmessage:接收到服务端推送的消息时触发。

  • onerror:发生通信错误时触发。

  • onclose:连接关闭时触发(需区分主动关闭和异常断开)。

  • 建连new WebSocket('ws://...')

  • 发消息ws.send('数据'),发送前一定要判断 ws.readyState === WebSocket.OPEN

  • 收消息 :监听 ws.onmessage,数据在 event.data 里(通常是 JSON 字符串,需要 JSON.parse)。

  • 生命周期onopen(连上)、onclose(断开)、onerror(报错)

javascript 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>前端 WebSocket Demo</title>
</head>
<body>
  <h3>WebSocket 前端极简 Demo</h3>
  <input id="input" placeholder="输入消息..." />
  <button id="sendBtn">发送</button>
  <p>服务端回复:<span id="msg" style="color:blue;"></span></p>

  <script>
    // 1. 建立连接(替换为你实际的 ws 或 wss 地址)
    const ws = new WebSocket('ws://localhost:8080/ws');
    // 2. 连接成功
    ws.onopen = () => {
      console.log('✅ WebSocket 连接已建立');
    };
    // 3. 接收服务端消息
    ws.onmessage = (event) => {
      console.log('📩 收到消息:', event.data);
      document.getElementById('msg').innerText = event.data;
    };
    // 4. 点击按钮发送消息
    document.getElementById('sendBtn').onclick = () => {
      const input = document.getElementById('input');
      // 发送前最好判断一下连接状态,防止报错
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(input.value);
        input.value = '';
      } else {
        console.warn('WebSocket 尚未连接');
      }
    };
    // 5. 连接关闭
    ws.onclose = () => {
      console.log('❌ WebSocket 连接已关闭');
    };
    // 6. 发生错误
    ws.onerror = (error) => {
      console.error('⚠️ WebSocket 发生错误:', error);
    };
  </script>
</body>
</html>

1.WebSocket 和 HTTP 的核心区别是什么?

  • HTTP 是单向的请求-响应模型,服务端无法主动推送;WebSocket 是全双工通信,双方都可以随时主动发消息。

  • HTTP通常是短连接(即使有 Keep-Alive 也是请求完即释放);WebSocket 是持久化的长连接。

  • 数据开销:HTTP 每次请求都要携带完整的 Header,开销大;WebSocket 建立连接后,数据帧头部极小,适合高频、小数据量的实时通信。

2.WebSocket 和 SSE (Server-Sent Events) 有什么区别?什么时候用谁?

  • 通信方向:SSE 是单向的(仅服务端向客户端推送),WebSocket 是双向的。

  • 协议与数据:SSE 基于 HTTP,通常只支持文本(JSON);WebSocket 是独立协议,支持文本和二进制。

  • 重连机制:SSE 内置了自动重连机制;WebSocket 需要开发者手动实现重连。

  • 场景选择:AI 流式输出、系统通知等只需服务端推送的场景用 SSE;实时聊天、在线游戏、协同编辑等需要双向交互的场景必须用 WebSocket。

3.如何保证 WebSocket 连接的稳定性?

  • 心跳检测 (Ping/Pong):由于网络波动或网关超时,长连接可能会"假死"。客户端需要定期(如 20-30 秒)发送 Ping 消息,服务端回复 Pong。如果连续多次未收到 Pong,则判定连接断开并主动关闭。

  • 断线重连策略:在 onerroronclose 事件中触发重连。必须采用指数退避算法(如延迟 1s、2s、4s、8s 递增重试),并加入随机抖动,防止大量客户端同时重连导致服务器"雪崩"。

  • 状态恢复:重连成功后,必须重新发送 Token 进行身份验证,并重新订阅之前的频道或状态。

4.移动端或浏览器休眠时,WebSocket 断开怎么处理?

  • 可以利用 Page Visibility API 监听页面的可见性。当用户从后台切回前台(visibilitychange)时,检查连接状态,如果已断开则立即触发重连。

  • 结合 navigator.onLine 监听网络状态,在网络恢复时触发重连,避免在离线状态下发起无效请求。

5.ws 和 wss 的区别是什么?

  • ws:// 是明文传输,wss:// 是基于 TLS/SSL 加密的 WebSocket。生产环境强烈推荐使用 wss://,因为很多防火墙和代理会拦截未加密的 WebSocket 连接,且 wss 能防止数据被窃听或篡改。

2.微前端

qiankun是蚂蚁金服开源的一款微前端框架,基于 Single-SPA 进行了二次封装,提供了更完善的开箱即用体验。是目前国内最流行、最适合 Vue 生态的微前端方案之一,已在大量线上系统中经受过考验。

  • 主框架不限制接入应用的技术栈,子应用(React、Vue、Angular 等)具备完全自主权。

  • 微应用仓库独立,前后端可独立开发、部署,主框架自动完成同步更新。

  • 提供完备的JS沙箱和样式隔离机制,确保微应用间的样式和全局变量不相互影响。

  • 支持主子应用间的数据传递、全局状态管理,完整的应用加载、挂载、卸载生命周期

实现原理(面试高频考点)

  • HTML Entry 加载机制:qiankun 的加载入口不是一个JS文件,而是抓取子应用的index.html,解析其中的 <link><script> 等资源,再动态注入到基座页面中,使得子应用能像独立页面那样工作。

  • JS 沙箱隔离:

    • Proxy 沙箱:针对现代浏览器,对 window 的读写通过 Proxy 重定向到子应用私有对象,避免污染宿主全局。

    • 快照沙箱:针对兼容模式,进入子应用前保存全局状态,退出后恢复。

  • 样式隔离:

    • Strict 模式:基于 Shadow DOM,为每个微应用的容器包裹上一个 shadow dom 节点,实现浏览器原生的严格隔离。

    • 实验性模式(experimentalStyleIsolation):在运行时给 CSS 选择器加作用域前缀(类似 Scoped),限制其影响范围。

  • 路由劫持:监听浏览器的 hashchangepopstate 事件,根据 URL 匹配激活规则,自动卸载当前应用并挂载目标应用。

  1. 主子应用通信方案
  • Props 传递(父→子):主应用在注册或加载微应用时,通过 props 传递初始化数据(如用户信息、主题配置等),子应用在 mount 生命周期中接收。

  • 全局状态管理:通过 qiankun 提供的 initGlobalState API 实现跨应用的状态共享与监听。

  • 事件总线(Event Bus):基于 CustomEvent 实现微应用间的消息传递。

主应用(基座)配置:

javascript 复制代码
import { registerMicroApps, start } from 'qiankun';
// 注册子应用
registerMicroApps([
  {
    name: 'vue-app',        // 应用唯一名称
    entry: '//localhost:7100', // 子应用入口
    container: '#subapp-container', // 挂载容器
    activeRule: '/vue',      // 路由激活规则
    props: {                 // 传递给子应用的数据
      user: { name: '张三' }
    }
  }
]);
// 启动 qiankun
start({ 
  sandbox: { experimentalStyleIsolation: true }, // 开启实验性样式隔离
  prefetch: true // 开启预加载
});

子应用适配(以 Vue/React 为例):

子应用需要暴露生命周期钩子,并在挂载时将 DOM 渲染到主应用提供的容器中:

javascript 复制代码
// 子应用入口文件
export async function mount(props) {
  // 将应用挂载到 props.container 中
  ReactDOM.render(<App />, props.container);
}

export async function unmount(props) {
  // 卸载时清理 DOM
  ReactDOM.unmountComponentAtNode(props.container);
}
  1. JS 沙箱隔离原理

"在 qiankun 中,为了防止多个微应用同时运行时全局变量(如 window 对象)互相污染,它提供了 JS 沙箱机制。具体分为两种实现:

  • 第一种是快照沙箱(SnapshotSandbox):主要为了兼容不支持 Proxy 的老旧浏览器。它的原理是在微应用挂载前,对当前的 window 对象拍一张快照(浅拷贝)。微应用运行期间可以随意修改全局变量,但在卸载时,qiankun 会将当前的 window 状态与快照进行 Diff 对比,从而删除新增的属性、还原被修改的属性,实现环境恢复。

  • 第二种是代理沙箱(ProxySandbox):这是 qiankun 推荐的现代方案。它利用 ES6 的 Proxy 为每个微应用创建一个伪造的 fakeWindow 对象。微应用代码中对 window 的所有读写操作,都会被拦截并重定向到这个 fakeWindow 上,从而实现了真正的隔离。这种方式不仅性能更好,而且支持多个微应用同时运行(多实例)。"

  1. CSS 样式隔离原理

为了防止不同微应用的 CSS 样式互相覆盖,qiankun 提供了两种样式隔离方案:

  • 第一种是严格样式隔离(Strict Style Isolation):它基于 Web Components 的 Shadow DOM 技术。qiankun 会为每个微应用创建一个 Shadow Root,将子应用的 DOM 和样式包裹在里面。这种方式利用了浏览器原生的隔离特性,效果最好,但缺点是某些挂载到 document.body 的第三方 UI 组件(如弹窗、下拉框)可能会出现样式丢失的问题。

  • 第二种是实验性样式隔离(Scoped CSS):这也是目前更常用的方案。它的原理类似于 Vue 的 scoped 或 CSS Modules。qiankun 会在运行时拦截子应用的样式,给所有的 CSS 选择器动态添加一个带有应用名的属性前缀(例如 div[data-qiankun="app1"])。这样,样式的作用域就被严格限制在了该子应用的容器内部,既实现了隔离,又避免了 Shadow DOM 的兼容性问题。"

在实际项目中,通常会在主应用启动时配置 experimentalStyleIsolation: true 来开启运行时 CSS 隔离,因为它对现有项目的侵入性最小。如果遇到第三方组件样式错乱的问题,结合全局 CSS 变量或给主应用样式加前缀来兜底处理。

3.Three.js

Three.js 是一个基于JS编写的开源3D 图形库(3D引擎)。

核心作用是让前端开发者能够直接在网页浏览器中,轻松创建和展示复杂的、逼真的 3D 场景和动画,完全不需要用户安装任何插件

解决了什么痛点?(与 WebGL 的关系)

在浏览器里画 3D 图形,底层依赖的是 WebGL 技术。直接使用原生WebGL极其繁琐,需要处理大量复杂的图形学细节(如着色器、顶点缓冲、矩阵运算等),学习门槛极高。

Three.js 就像是一个"翻译官"和"工具箱",它封装了 WebGL 的底层复杂性,提供了一套极其简洁、优雅的JS API。只需要几行代码,就能调用 GPU 实现原本需要成百上千行代码才能完成的 3D 渲染效果。

核心"三剑客"是什么?

任何一个 Three.js 3D 场景的搭建,都离不开这三个最核心的概念:

  • 场景Scene:相当于一个虚拟的3D舞台或容器,里面放置了所有的3D物体、灯光等。

  • 相机Camera:相当于观察者的眼睛。决定了从什么角度、什么视野去观察这个 3D 舞台(最常用的是模拟人眼"近大远小"的透视相机)。

  • 渲染器 Renderer:相当于摄影师。负责将场景和相机捕捉到的信息,最终计算并绘制到网页的Canvas画布上,让能看到 3D 画面

在前端开发中有什么用?

数字孪生与 3D 可视化:在网页上 1:1 还原真实的园区、工厂或城市,展示设备运行状态、安防监控热力图等。

WebGIS 进阶:与 Cesium 等地图引擎结合,在真实的 3D 地球上叠加建筑白模、粒子特效、无人机巡检轨迹等。

数据大屏:将枯燥的数据转化为立体的3D图表,如3D柱状图、地球飞线等,提升视觉冲击力

互动式展示:如网页端的 3D 汽车预览、虚拟展厅、在线 3D 小游戏等。

  1. 构建一个最基础的3D场景,必须掌握以下三个核心类的构造函数:
  • new THREE.Scene():创建场景对象,它是所有 3D 物体、光源和相机的根容器

  • new THREE.PerspectiveCamera():创建透视相机,参数通常包括视野角度(FOV)、宽高比(Aspect)、近裁剪面(Near)和远裁剪面(Far)。

  • new THREE.WebGLRenderer({}):创建 WebGL 渲染器,负责将场景和相机渲染到 HTML 的 Canvas 画布上

  1. 物体构建 API(几何体 + 材质)

3D 场景中的可见物体(网格 Mesh)由几何体和材质两部分组合而成:

  • 几何体 API (Geometry):定义物体的形状。最常用的是 new THREE.BoxGeometry(宽, 高, 深) 创建立方体,此外还有 SphereGeometry(球体)、CylinderGeometry(圆柱)等。

  • 材质 API (Material):定义物体的外观。最基础的是 new THREE.MeshBasicMaterial({color: 0xff0000})(不受光照影响的基础材质);支持物理光照渲染的则是 new THREE.MeshStandardMaterial({...})

  • 网格组合 API:new THREE.Mesh(geometry, material),将几何体和材质组合成一个可渲染的网格对象。

  1. 场景图操作 API

用于管理场景中的对象层级和空间变换:

  • scene.add(object):将相机、灯光、网格等对象添加到场景中,这是最常用的场景管理方法。

  • 空间变换属性:

    • object.position.set(x, y, z):设置物体在 3D 空间中的位置。

    • object.rotation.set(x, y, z):设置物体的旋转角度(以弧度为单位)。

    • object.scale.set(x, y, z):设置物体的缩放比例。

  1. 渲染与动画 API

让静态的 3D 场景动起来:

  • renderer.render(scene, camera):执行一次渲染,将当前场景通过指定相机的视角绘制到屏幕上。

  • requestAnimationFrame(callback):浏览器原生 API,Three.js 依赖它来实现渲染循环(动画循环),确保动画以流畅的帧率(如 60FPS)持续更新和重绘。

  1. 交互与辅助 API

提升用户体验和开发调试效率:

  • OrbitControls:轨道控制器插件。通过监听鼠标事件,允许用户按住左键旋转视角、滚轮缩放、按住右键平移,是 3D 预览最常用的交互 API。

  • THREE.AxesHelper(size):坐标轴辅助对象。在场景中添加红(X轴)、绿(Y轴)、蓝(Z轴)三色坐标线,方便开发者定位和调试 3D 空间

4.WebGIS

Web地理信息系统的核心公式为:WebGIS = GIS基础理论 + Web前端开发 + 可视化技术

  1. GIS 基础理论(必学基石)
  • 坐标系与投影:这是WebGIS的灵魂。必须掌握地理坐标系(如 WGS84、CGCS2000)与投影坐标系(如 Web Mercator)的区别。了解国内常见的坐标系(如高德的 GCJ-02、百度的 BD-09)以及它们之间的转换。

  • 空间数据类型:理解矢量数据(点、线、面)和栅格数据(瓦片、遥感影像)的区别与渲染逻辑

  • 地理数据格式:必须一眼看懂并能处理 GeoJSON 格式,了解 Shapefile、KML、3D Tiles 等格式

  • OGC 地图服务:掌握 WMS(地图服务)、WMTS(瓦片服务)、WFS(矢量要素服务)的调用方式与区别

  1. 前端地图技术栈
  • 二维地图库:

    • Leaflet:轻量、简单,适合基础展示和移动端。

    • OpenLayers:功能极其强大,支持专业GIS业务,政企项目首选。

    • Mapbox GL JS:基于 WebGL,支持矢量瓦片,适合炫酷的定制化商业可视化。

  • 三维地图库:

    • CesiumJS:Web 3D GIS 的行业标准,支持真实地形、BIM模型、3D Tiles,是智慧城市和数字孪生的核心引擎。
  1. 进阶与性能优化
  • 海量数据渲染:掌握聚合点(Cluster)、分级加载、数据分页、Web Worker 多线程处理等技术,解决页面卡顿和崩溃问题。

  • 空间分析:了解缓冲区分析、叠加分析、路径规划、地理编码(地址转坐标)等前端实现方案。

  • 后端 GIS 能力(加分项):了解 PostGIS(空间数据库)、GeoServer(地图服务发布)的基本原理。

1.什么是 WebGIS?它和传统 GIS 有什么区别?

传统 GIS 偏向桌面端,侧重数据采集、建模和空间分析;而 WebGIS 侧重于通过浏览器展示地图、数据可视化和空间数据接口调用,技术栈以 JavaScript、WebGL 和前端框架为主。

2.如何处理不同坐标系的地理数据?

可以使用地图库自带的坐标转换功能,或者引入第三方库(如 proj4.js)将不同坐标系(如 WGS84、GCJ-02)统一转换为地图引擎所需的坐标系,避免点位偏移。

3.WebGIS 中如何处理大规模地理数据的渲染性能问题?

  1. 数据层:采用分级加载、数据分页、按需请求;2. 渲染层:使用聚合图层(Cluster)、LOD(多细节层次)算法、动态渲染;3. 交互层:使用异步操作和 Web Worker,避免阻塞主线程。

4.介绍一下你熟悉的 GIS 地图库及其特点?

OpenLayers:它功能强大,支持多种地图数据源,可定制性极高,适合复杂的企业级 WebGIS 业务;或者 Cesium:它是真三维地球,擅长处理 3D Tiles、倾斜摄影模型,是数字孪生场景的首选

5.WMS 和 WMTS 服务有什么区别?

WMS(动态地图服务)是客户端请求时,服务端实时渲染生成地图图片返回,灵活性高但性能差;WMTS(瓦片地图服务)是服务端预先将地图切割成固定大小的图块(金字塔),客户端按需请求,加载速度极快,适合大规模底图展示。

6.Cesium 中的 Entity 和 Primitive 有什么区别?

Entity 是高层 API,使用简单,支持丰富的样式和交互,但底层封装深,加载海量数据时性能较差;Primitive 是底层 API,直接面向图形渲染,性能极高,适合加载成千上万个模型或粒子效果,但代码编写复杂。

入门学习路线

  • 阶段 1:GIS 基础理论打底

    • 搞懂坐标系、投影、矢量/栅格数据。

    • 学习使用 QGIS 等开源工具进行简单的空间数据查看和处理。

  • 阶段 2:巩固 Web 前端基础

    • 熟练掌握 JavaScript (ES6+)、Vue 或 React。

    • 理解前端工程化(Webpack/Vite)和状态管理。

  • 阶段 3:攻克 WebGIS 核心框架(重点)

    • 先学 Leaflet 或 OpenLayers(二维),跑通 GeoJSON 渲染、鼠标交互(测距、点击查询)等基础功能。

    • 再学 Cesium(三维),掌握三维场景搭建、3D Tiles 模型加载、相机控制等。

  • 阶段 4:项目实战与进阶

    • 找一个开源项目(如智慧园区、交通轨迹可视化)从 0 到 1 完整实现。

    • 学习空间数据库(PostGIS)和地图服务发布GeoServer,打通前后端 GIS 闭环

相关推荐
YHL42 分钟前
⚛️ React `useState` 深入浅出
前端·react.js·前端框架
喝咖啡的女孩44 分钟前
vibe coding一个云书房
前端
计算机魔术师1 小时前
为了考试作弊,AI 模型黑进了 Hugging Face——这已经不是科幻了
前端
天云数据1 小时前
从“LLM+工具”到Harness 工程:Lilian Weng新文的技术拆解,与一个生产级参考实现
java·前端·网络
三8441 小时前
WordPress SQL 注入漏洞分析:从 author__not_in 参数到 REST API 全链路
linux·前端·数据库
IT_陈寒1 小时前
Vite打包时踩了个坑,static资源去哪了?
前端·人工智能·后端
龙虾PRO1 小时前
2026 年 AI 智能体工具调用:ReAct 模式与函数调用怎么选才不踩坑
前端·人工智能·react.js
何以解忧,唯有..1 小时前
Django 框架入门指南:从零开始构建 Web 应用
前端·python·django
daols881 小时前
vue 甘特图 vxe-gantt 紧前紧后依赖关系连接线配置详解
前端·vue.js·甘特图