前端知识点全解析

前端知识点全解析

作为一名前端高级开发人员,面试不仅考察知识点的记忆,更关注对原理的理解、工程化的思考以及解决复杂问题的能力。本文将从 HTML/CSS、JavaScript、浏览器与网络、框架、工程化、性能优化、算法与设计模式等多个维度,系统梳理前端面试中的核心知识点,并提供深入解析及案例,帮助你在面试中展现出真正的技术深度。


1. HTML & CSS 基础

1.1 语义化 HTML

讲解:语义化 HTML 是指使用具有明确含义的标签(如 <header><nav><article><section>)来描述网页结构,而不是单纯使用 <div><span>

解析

  • SEO 友好:搜索引擎爬虫依赖语义标签理解页面内容,有助于提升排名。
  • 可访问性:屏幕阅读器等辅助技术可以更好地解析页面,为视障用户提供良好体验。
  • 代码可维护性:团队协作时,语义化标签让代码结构清晰易懂。
  • 常见语义标签<header><footer><main><aside><article><section><nav>

案例

<!-- 非语义化 --><divclass="header"><divclass="logo">MySite</div><divclass="nav"><ahref="/">首页</a><ahref="/about">关于</a></div></div><!-- 语义化 --><header><h1class="logo">MySite</h1><nav><ul><li><ahref="/">首页</a></li><li><ahref="/about">关于</a></li></ul></nav></header>

面试题<b><strong> 的区别?
解析<b> 仅表示粗体样式,无语义;<strong> 表示强调内容,有语义,屏幕阅读器会以重音读出。

1.2 盒模型

讲解:CSS 盒模型描述了一个元素所占空间的结构,包括内容(content)、内边距(padding)、边框(border)、外边距(margin)。

解析

  • 标准盒模型width/height 只包含内容区,不包含 padding 和 border。总宽度 = width + padding + border + margin。
  • IE 盒模型(怪异盒模型):width/height 包含内容、padding 和 border。总宽度 = width + margin。
  • 切换方式:通过 box-sizing: content-box(默认)或 box-sizing: border-box 设置。
  • 实际应用:通常将 box-sizing 设置为 border-box 更易于布局,避免频繁计算宽高。

案例

/* 标准盒模型 */.box-standard{box-sizing: content-box;width: 100px;padding: 10px;border: 5px solid black;margin: 10px;/* 实际占据宽度 = 100 + 10*2 + 5*2 = 130px */}/* IE盒模型(常用) */.box-border{box-sizing: border-box;width: 100px;padding: 10px;border: 5px solid black;margin: 10px;/* 实际占据宽度 = 100px(包含padding和border) */}

1.3 布局方式

1.3.1 浮动与清除浮动

讲解float 使元素脱离文档流,向左或向右浮动,常用于文字环绕图片或实现多列布局。

解析

  • 浮动影响:父容器高度塌陷(因为浮动元素不占文档流高度)。
  • 清除浮动方法
    • 在父容器末尾添加空元素并设置 clear: both
    • 父容器触发 BFC(如 overflow: hidden)。
    • 使用伪元素:.clearfix::after { content: ""; display: table; clear: both; }

案例

<divclass="container clearfix"><divclass="float-left">浮动元素</div><divclass="float-left">浮动元素</div></div><style>.float-left{float: left;width: 100px;height: 100px;background: lightblue;}.clearfix::after{content:"";display: table;clear: both;}</style>
1.3.2 定位

讲解position 属性控制元素的定位方式,包括 staticrelativeabsolutefixedsticky

解析

  • relative:相对自身原本位置偏移,仍占文档流空间。
  • absolute:相对最近的非 static 祖先元素定位,脱离文档流。
  • fixed:相对视口定位,脱离文档流。
  • sticky:粘性定位,根据滚动阈值在 relativefixed 之间切换。
  • 层叠上下文z-index 仅在非 static 定位元素上生效,且受层叠上下文影响。

案例

<divclass="parent"style="position: relative;height: 200px;background: #eee;"><divclass="child"style="position: absolute;bottom: 10px;right: 10px;">绝对定位</div></div><divclass="sticky"style="position: sticky;top: 0;">粘性头部</div>
1.3.3 Flex 布局

讲解:Flex 是一维布局模型,提供强大的对齐和空间分配能力。

解析

  • 容器属性display: flexflex-direction(主轴方向);justify-content(主轴对齐);align-items(交叉轴对齐);flex-wrap(换行)。
  • 项目属性flex-grow(放大比例)、flex-shrink(缩小比例)、flex-basis(初始大小);align-self(覆盖容器的 align-items)。
  • 经典应用:垂直居中(justify-content: center; align-items: center)、圣杯布局、等分布局。

案例

.container{display: flex;justify-content: space-between;align-items: center;height: 200px;}.item{flex: 1;/* 等分剩余空间 */margin: 10px;}
1.3.4 Grid 布局

讲解:Grid 是二维布局模型,将容器划分为行和列,可精确控制元素位置。

解析

  • 容器属性display: gridgrid-template-rows/columns 定义行/列轨道;gap 间隙;justify/align-items 控制单元格内对齐。
  • 项目属性grid-row/column 指定项目占据的网格线;justify/align-self 控制项目自身对齐。
  • 与 Flex 区别:Grid 适合整体页面布局,Flex 适合组件内部的一维排列。

案例

.grid-container{display: grid;grid-template-columns: 1fr 2fr 1fr;grid-template-rows: 100px 200px;gap: 10px;}.item{background: lightcoral;}.item:first-child{grid-column: 1 / 3;/* 跨两列 */}

1.4 响应式设计

讲解:响应式设计使网站在不同设备(手机、平板、桌面)上都能良好显示。

解析

  • 视口(viewport):通过 <meta name="viewport" content="width=device-width, initial-scale=1"> 设置,确保页面宽度适配设备宽度。
  • 媒体查询@media (max-width: 768px) { ... } 根据屏幕尺寸应用不同样式。
  • 相对单位em(相对于父元素字体)、rem(相对于根元素字体)、vw/vh(视口宽高百分比)、%
  • 弹性布局:结合 Flex/Grid 实现容器自适应。
  • 图片响应式srcsetsizes 属性或 <picture> 元素,根据分辨率加载合适图片。

案例

<imgsrcset="small.jpg 300w, medium.jpg 600w, large.jpg 900w"sizes="(max-width: 600px) 100vw, (max-width: 900px) 50vw, 33vw"src="large.jpg"alt="响应式图片"><style>.container{width: 80%;margin: 0 auto;}@media(max-width: 768px){.container{width: 100%;padding: 0 10px;}}</style>

1.5 CSS 预处理器

讲解:Sass、Less 等预处理器为 CSS 提供了变量、嵌套、混合、继承等编程特性。

解析

  • 变量$primary-color(Sass)或 @primary-color(Less),便于主题管理。
  • 嵌套:减少重复父选择器,但避免过深嵌套。
  • 混合(mixin):可复用样式块,可传参。
  • 函数与运算:颜色函数、数学运算。
  • 模块化@import 分割文件,最终编译为一个 CSS 文件。

案例(Sass):

$primary: #007bff; $spacing: 1rem; @mixin rounded($radius: 4px) { border-radius: $radius; } .button { background: $primary; padding: $spacing/2 $spacing; @include rounded(8px); &:hover { background: darken($primary, 10%); } } 

1.6 BEM 命名规范

讲解:BEM(Block Element Modifier)是一种 CSS 命名方法论,旨在提高代码可读性和可维护性。

解析

  • Block:独立实体,如 .header.menu
  • Element:属于块的一部分,如 .header__logo.menu__item
  • Modifier:修饰块或元素的状态,如 .header--fixed.menu__item--active
  • 优点:避免样式冲突,清晰的结构关系。

案例

<divclass="card"><divclass="card__header"><h2class="card__title">标题</h2></div><divclass="card__body">内容</div><divclass="card__footer card__footer--highlighted">底部高亮</div></div><style>.card__footer--highlighted{background: yellow;}</style>

1.7 层叠上下文与 z-index

讲解:层叠上下文是 HTML 元素在 Z 轴上的层级概念,z-index 决定同一层叠上下文中元素的堆叠顺序。

解析

  • 创建层叠上下文的条件:根元素、positionstaticz-index 值不为 autoopacity 小于 1、transformnonefilternone 等。
  • z-index 比较:只有同一层叠上下文内的元素才能比较 z-index;不同上下文中,父级上下文决定层级。
  • 常见问题:明明设置了很大的 z-index 却无效,通常是因为元素不在同一个层叠上下文,或父级 z-index 限制。

案例

<divstyle="position: relative;z-index: 1;"><divstyle="position: absolute;z-index: 999;">这个999受父级1限制</div></div><divstyle="position: relative;z-index: 2;"><divstyle="position: absolute;z-index: 1;">这个1比上面的999大,因为父级z-index=2更高</div></div>

2. JavaScript 核心

2.1 数据类型与类型判断

讲解:JavaScript 有 8 种数据类型:undefinednullbooleannumberstringsymbol(ES6)、bigint(ES11)、object。其中前 7 种为原始类型,object 为引用类型。

解析

  • 类型判断方法
    • typeof:适合原始类型,但 typeof null === 'object'(历史遗留 bug),typeof function(){} === 'function'
    • instanceof:检查对象原型链,用于判断引用类型。
    • Object.prototype.toString.call():最准确,返回 [object Type]
  • 隐式类型转换+== 等操作符会触发类型转换,需注意规则(如 [] == ![] 结果为 true)。

案例

console.log(typeof42);// "number" console.log(typeof'hello');// "string" console.log(typeoftrue);// "boolean" console.log(typeofundefined);// "undefined" console.log(typeofnull);// "object" (历史遗留) console.log(typeof{});// "object" console.log(typeoffunction(){});// "function" console.log([]instanceofArray);// true console.log({}instanceofObject);// true console.log(Object.prototype.toString.call([]));// "[object Array]" console.log(Object.prototype.toString.call(null));// "[object Null]"

2.2 作用域与闭包

讲解:作用域决定了变量的可访问范围。JavaScript 采用词法作用域(静态作用域),函数的作用域在定义时确定。闭包是指有权访问另一个函数作用域中变量的函数。

解析

  • 作用域链:当访问变量时,从当前作用域开始向上查找,直到全局。
  • 闭包的形成:内部函数引用了外部函数的变量,即使外部函数执行完毕,变量仍被内部函数引用,不会被垃圾回收。
  • 常见用途
    • 封装私有变量(模块模式)。
    • 函数柯里化。
    • 循环中使用 var 创建多个闭包(通常用 IIFE 或 let 解决)。
  • 内存泄漏:闭包不当会导致内存无法释放,应避免无限制使用。

案例

// 闭包封装私有变量functioncreateCounter(){let count =0;return{increment:()=>++count,decrement:()=>--count,getCount:()=> count };}const counter =createCounter(); console.log(counter.increment());// 1 console.log(counter.increment());// 2 console.log(counter.getCount());// 2

2.3 原型与原型链

讲解:JavaScript 通过原型实现继承。每个对象都有一个 __proto__ 属性指向其构造函数的原型对象 prototype。原型链由多个对象的 __proto__ 链接而成。

解析

  • 构造函数:函数本身也是对象,拥有 prototype 属性。通过 new 调用构造函数创建实例,实例的 __proto__ 指向构造函数的 prototype
  • 原型链查找:访问对象属性时,如果对象自身没有,则沿着 __proto__ 向上查找,直到 null
  • 原型链终点Object.prototype.__proto__ === null
  • 继承方式
    • 原型链继承:Child.prototype = new Parent()
    • 组合继承:原型链 + 构造函数。
    • ES6 class 语法糖(本质仍是原型链)。
  • instanceof 原理:检测右侧构造函数的 prototype 是否在左侧对象的原型链上。

案例

functionAnimal(name){this.name = name;}Animal.prototype.speak=function(){ console.log(`${this.name} makes a sound.`);};functionDog(name, breed){Animal.call(this, name);// 借用构造函数this.breed = breed;}// 原型链继承Dog.prototype = Object.create(Animal.prototype);Dog.prototype.constructor = Dog;Dog.prototype.bark=function(){ console.log(`${this.name} barks.`);};const d =newDog('Rex','Husky'); d.speak();// Rex makes a sound. d.bark();// Rex barks. console.log(d instanceofDog);// true console.log(d instanceofAnimal);// true

2.4 this 指向与 call/apply/bind

讲解this 的值在函数调用时确定,取决于调用方式。

解析

  • 默认绑定:独立函数调用,this 指向全局对象(浏览器中为 window),严格模式为 undefined
  • 隐式绑定:作为对象方法调用,this 指向该对象。
  • 显式绑定callapplybind 可以强制指定 this
    • call(thisArg, arg1, arg2...):立即执行,参数列表。
    • apply(thisArg, [arg1, arg2...]):立即执行,参数数组。
    • bind(thisArg, arg1, arg2...):返回新函数,永久绑定 this
  • new 绑定:使用 new 调用构造函数,this 指向新创建的对象。
  • 箭头函数:没有自己的 this,捕获外层作用域的 this(词法绑定)。
  • 优先级new > 显式绑定 > 隐式绑定 > 默认绑定。

案例

functiongreet(greeting, punctuation){ console.log(greeting +', '+this.name + punctuation);}const person ={name:'Alice'};greet.call(person,'Hello','!');// Hello, Alice!greet.apply(person,['Hi','?']);// Hi, Alice?const bound =greet.bind(person,'Hey');bound('!!');// Hey, Alice!!

2.5 异步编程

2.5.1 回调函数

讲解:将函数作为参数传入,在异步操作完成后调用。

解析

  • 优点:简单直观。
  • 缺点:回调地狱(多层嵌套)、错误处理困难、代码可读性差。

案例

functionfetchData(callback){setTimeout(()=>{callback('data');},1000);}fetchData((result)=>{ console.log(result);});
2.5.2 Promise

讲解:Promise 是异步编程的解决方案,代表一个最终完成或失败的操作。

解析

  • 状态pending(进行中)、fulfilled(已成功)、rejected(已失败)。状态一旦改变不可逆。
  • 实例方法
    • then(onFulfilled, onRejected):返回新 Promise,支持链式调用。
    • catch(onRejected):相当于 .then(null, onRejected)
    • finally(onFinally):无论成功失败都会执行。
  • 静态方法
    • Promise.all(iterable):全部成功才成功,任一失败则立即失败。
    • Promise.race(iterable):首个状态变更的 Promise 决定结果。
    • Promise.allSettled(iterable):等待所有完成,返回每个结果(fulfilled/rejected)。
    • Promise.any(iterable):首个成功的结果,若全部失败则 AggregateError。
  • 错误处理:Promise 链中通过 catch 捕获错误,注意在 then 中抛出的错误也会被后续 catch 捕获。

案例

functionasyncTask(shouldResolve){returnnewPromise((resolve, reject)=>{setTimeout(()=>{ shouldResolve ?resolve('成功'):reject('失败');},1000);});}asyncTask(true).then(result=> console.log(result)).catch(error=> console.error(error)); Promise.all([asyncTask(true),asyncTask(true)]).then(results=> console.log('全部成功', results)).catch(err=> console.error('至少一个失败', err));
2.5.3 async/await

讲解:async/await 是 ES2017 引入的语法糖,基于 Promise,使异步代码像同步一样书写。

解析

  • async 函数:返回一个 Promise,内部返回值会被 Promise.resolve() 包装。
  • await 表达式:等待一个 Promise 完成,会暂停当前 async 函数的执行,直到 Promise 状态变为 fulfilled 或 rejected。
  • 错误处理:使用 try/catch 捕获 await 中 Promise 的 reject。
  • 注意事项:await 只能在 async 函数中使用;多个无依赖的异步操作应使用 Promise.all 并发执行,避免串行等待。

案例

asyncfunctionfetchData(){try{const result =awaitasyncTask(true); console.log(result);const data =awaitasyncTask(true); console.log(data);}catch(error){ console.error('捕获错误:', error);}}fetchData();

2.6 事件循环与宏任务/微任务

讲解:JavaScript 是单线程语言,通过事件循环机制处理异步任务。任务分为宏任务(macrotask)和微任务(microtask)。

解析

  • 宏任务:script 整体代码、setTimeoutsetInterval、I/O、UI 渲染等。
  • 微任务Promise.then/catch/finallyMutationObserverqueueMicrotaskprocess.nextTick(Node)。
  • 执行顺序
    1. 执行当前宏任务(如 script 整体)。
    2. 执行所有微任务(清空微任务队列)。
    3. 取出下一个宏任务执行,重复。

经典题目

console.log('1');setTimeout(()=> console.log('2'),0); Promise.resolve().then(()=> console.log('3')); console.log('4');// 输出顺序:1,4,3,2

案例

console.log('start');setTimeout(()=> console.log('timeout'),0); Promise.resolve().then(()=> console.log('promise1')); Promise.resolve().then(()=>{ console.log('promise2');setTimeout(()=> console.log('timeout inside promise'),0);}); console.log('end');// 输出:start, end, promise1, promise2, timeout, timeout inside promise

2.7 深拷贝与浅拷贝

讲解:浅拷贝只复制对象的第一层属性,引用类型仍共享引用;深拷贝递归复制所有层级,生成独立对象。

解析

  • 浅拷贝方法Object.assign()、扩展运算符 {...obj}Array.prototype.slice()
  • 深拷贝方法
    • JSON.parse(JSON.stringify(obj)):缺点是无法处理函数、undefined、Symbol、循环引用。
    • 递归实现(需处理各种数据类型)。
    • 使用结构化克隆:structuredClone()(现代浏览器支持)。
    • 第三方库如 Lodash 的 _.cloneDeep
  • 性能考量:深拷贝成本高,应根据场景选择。

案例

const original ={a:1,b:{c:2}};// 浅拷贝const shallow ={...original }; shallow.b.c =3; console.log(original.b.c);// 3 (相互影响)// 深拷贝const deep =JSON.parse(JSON.stringify(original)); deep.b.c =4; console.log(original.b.c);// 3 (独立)

2.8 防抖与节流

讲解:防抖和节流是限制函数执行频率的优化手段。

解析

  • 区别:防抖是“延迟合并”,节流是“频率限制”。

节流(throttle):规定一个单位时间内,只能触发一次函数。适用于滚动加载、频繁点击。

functionthrottle(fn, interval){let lastTime =0;returnfunction(...args){const now = Date.now();if(now - lastTime >= interval){fn.apply(this, args); lastTime = now;}};}

防抖(debounce):在事件被触发 n 秒后执行回调,如果在这 n 秒内又被触发,则重新计时。适用于输入框搜索、窗口 resize。

functiondebounce(fn, delay){let timer =null;returnfunction(...args){clearTimeout(timer); timer =setTimeout(()=>fn.apply(this, args), delay);};}

案例

<inputid="search"type="text"placeholder="搜索"><script>const input = document.getElementById('search'); input.addEventListener('input',debounce(function(e){ console.log('发送请求:', e.target.value);},500));</script>

2.9 数组/对象常用方法

讲解:掌握 ES5/ES6 中数组和对象的常用方法。

解析

  • 数组方法
    • 迭代:forEachmapfilterreducesomeevery
    • 查找:indexOffindfindIndexincludes
    • 增删改:push/popshift/unshiftspliceconcatslice
    • 排序/反转:sortreverse
    • 扁平化:flatflatMap
  • 对象方法
    • 遍历:Object.keys()Object.values()Object.entries()
    • 拷贝/合并:Object.assign()
    • 创建:Object.create()(指定原型)。
    • 属性描述符:Object.defineProperty()

案例

// 数组const arr =[1,2,3,4];const doubled = arr.map(x=> x *2);// [2,4,6,8]const evens = arr.filter(x=> x %2===0);// [2,4]const sum = arr.reduce((acc, cur)=> acc + cur,0);// 10// 对象const obj ={a:1,b:2}; Object.keys(obj).forEach(key=> console.log(key, obj[key]));const merged = Object.assign({}, obj,{c:3});// {a:1,b:2,c:3}

3. 浏览器与网络

3.1 浏览器渲染原理

讲解:浏览器从获取 HTML 到渲染出页面的过程。

解析

  1. 解析 HTML:构建 DOM 树。
  2. 解析 CSS:构建 CSSOM 树。
  3. 合并:生成渲染树(Render Tree),只包含可见节点。
  4. 布局(Layout/Reflow):计算每个节点的几何位置。
  5. 绘制(Paint):将渲染树绘制到屏幕。
  6. 合成(Composite):分层绘制,利用 GPU 加速。
  • 关键点:CSS 不会阻塞 DOM 解析,但会阻塞渲染;JS 会阻塞 DOM 解析(除非标记 asyncdefer)。

案例

<!-- 模拟阻塞 --><scriptsrc="slow.js"></script><!-- 会阻塞后续DOM解析 --><scriptasyncsrc="async.js"></script><!-- 下载不阻塞,执行可能乱序 --><scriptdefersrc="defer.js"></script><!-- 下载不阻塞,在DOM解析完后执行 -->

3.2 回流与重绘

讲解:回流(Reflow)指元素的几何属性(尺寸、位置)发生变化,需要重新计算布局;重绘(Repaint)指元素样式改变但不影响布局(如颜色、背景)。

解析

  • 触发回流的操作:添加/删除 DOM、修改元素尺寸、页面初始渲染、窗口大小变化、获取某些属性(如 offsetWidth)时可能强制同步布局。
  • 优化策略
    • 批量修改样式(使用 classcssText)。
    • 将元素脱离文档流(position: absolute)后再操作。
    • 使用 requestAnimationFrame 读写 DOM。
    • 避免频繁读取布局属性。

案例

// 避免多次触发回流const div = document.getElementById('box'); div.style.width ='100px';// 回流 div.style.height ='100px';// 再次回流// 优化:合并修改 div.style.cssText ='width: 100px; height: 100px;';// 或使用class div.classList.add('big-box');

3.3 跨域解决方案

讲解:同源策略限制不同源(协议、域名、端口任一不同)的资源交互。跨域指突破此限制进行通信。

解析

  • JSONP:利用 <script> 标签没有跨域限制,通过动态创建 script 加载带回调函数名的 URL。仅支持 GET。
  • CORS(跨域资源共享):服务器设置响应头 Access-Control-Allow-Origin 允许特定来源。支持所有 HTTP 方法。
    • 简单请求和非简单请求(需预检请求 OPTIONS)。
  • 代理服务器:开发环境下配置 webpack-dev-server 的 proxy,或 Nginx 反向代理。
  • postMessage:用于 iframe 或窗口间通信。
  • WebSocket:不受同源策略限制。
  • document.domain:适用于主域相同子域不同的情况(已过时)。

案例

// JSONPfunctionjsonp(url, callbackName){const script = document.createElement('script'); script.src =`${url}?callback=${callbackName}`; window[callbackName]=(data)=>{ console.log('接收数据:', data);delete window[callbackName]; document.body.removeChild(script);}; document.body.appendChild(script);}jsonp('http://api.example.com/data','handleData');// CORS: 服务器设置响应头 Access-Control-Allow-Origin: *

3.4 HTTP 协议

讲解:HTTP 是 Web 基础协议,经历了多个版本演进。

解析

  • HTTP/1.0:每个 TCP 连接只能发送一个请求,请求结束立即关闭,效率低。
  • HTTP/1.1
    • 持久连接(keep-alive),允许多个请求复用同一个 TCP 连接。
    • 管道化(pipelining),但队头阻塞问题仍存在(必须按顺序响应)。
    • 增加了 Host 头、缓存控制(Cache-Control)等。
  • HTTP/2.0
    • 二进制分帧层,将请求/响应分割为帧,实现多路复用(一个连接同时处理多个请求,解决队头阻塞)。
    • 头部压缩(HPACK),减少开销。
    • 服务器推送(server push)。
  • HTTP/3.0:基于 QUIC 协议(UDP),解决 TCP 队头阻塞,更快建立连接。

案例

// HTTP/2 服务器推送示例(需服务器支持)// 在响应头中推送关键资源Link:</styles.css>; rel=preload;as=style 

3.5 缓存机制

讲解:浏览器缓存分为强缓存和协商缓存,减少网络请求,提高加载速度。

解析

  • 强缓存
    • Expires:HTTP/1.0 头,绝对时间,依赖客户端时间。
    • Cache-Control:HTTP/1.1 头,优先级高,常用值 max-age=秒
  • 协商缓存
    • Last-Modified / If-Modified-Since:资源最后修改时间,可能不准确(如文件修改但内容未变)。
    • ETag / If-None-Match:资源唯一标识(哈希),更精确。
  • 缓存位置:Service Worker、Memory Cache、Disk Cache、Push Cache。
  • 缓存策略:HTML 通常协商缓存或禁用缓存;CSS/JS/图片设置强缓存,并配合文件名哈希更新。

案例

<!-- 通过meta禁用缓存(不推荐,用HTTP头) --><metahttp-equiv="Cache-Control"content="no-cache, no-store, must-revalidate"/><!-- 服务器设置强缓存:Cache-Control: max-age=31536000 --><!-- 资源通过哈希更新:main.a1b2c3.js -->

3.6 Web 安全

3.6.1 XSS(跨站脚本攻击)

讲解:攻击者注入恶意脚本到可信网站,当用户浏览时执行。

解析

  • 反射型:恶意脚本通过 URL 参数注入,后端未过滤直接返回。
  • 存储型:恶意脚本存储在服务器数据库,如评论区,每次访问都触发。
  • DOM 型:纯前端漏洞,通过修改 DOM 执行脚本。
  • 防御
    • 输入过滤(对用户输入进行转义)。
    • 输出编码(使用 textContent 而不是 innerHTML)。
    • 设置 Content-Security-Policy(CSP)限制资源加载。
    • 使用 HttpOnly Cookie 防止 Cookie 被脚本窃取。

案例

// 防御:对用户输入进行转义functionescapeHTML(str){return str.replace(/[&<>"]/g,function(m){if(m ==='&')return'&amp;';if(m ==='<')return'&lt;';if(m ==='>')return'&gt;';if(m ==='"')return'&quot;';return m;});}const userComment ='<script>alert(1)</script>'; document.getElementById('comment').textContent =escapeHTML(userComment);
3.6.2 CSRF(跨站请求伪造)

讲解:攻击者诱导用户访问第三方网站,利用用户的登录态向目标网站发起恶意请求。

解析

  • 防御
    • 使用 CSRF Token:表单中嵌入随机 token,服务端验证。
    • SameSite Cookie 属性:设置为 StrictLax,限制跨站发送 Cookie。
    • 验证 Referer 或 Origin 头。
    • 使用验证码(重要操作)。

案例

// 设置SameSite Cookie document.cookie ="session=abc123; SameSite=Lax; Secure";

4. 前端框架(以 Vue 为例)

4.1 Vue 核心概念

讲解:Vue 是一套用于构建用户界面的渐进式框架,采用组件化、声明式编程。

解析

  • 组件:Vue 组件由模板、脚本、样式组成,可以是选项式 API 或组合式 API。
  • 模板语法:基于 HTML 的模板,使用指令(如 v-bindv-ifv-for)和插值 {{ }}
  • 响应式系统:Vue 通过依赖追踪,在数据变化时自动更新视图。Vue 2 使用 Object.defineProperty,Vue 3 使用 Proxy。
  • 实例:每个 Vue 应用通过 createApp 创建根实例。
  • 生命周期:组件从创建到销毁的各个阶段,如 createdmountedupdatedunmounted

案例

<template> <div> <p>{{ message }}</p> <button @click="reverseMessage">反转消息</button> </div> </template> <script> export default { data() { return { message: 'Hello Vue!' }; }, methods: { reverseMessage() { this.message = this.message.split('').reverse().join(''); } } }; </script> 

4.2 生命周期与组合式 API

讲解:Vue 组件有生命周期钩子,组合式 API(Composition API)提供了更灵活的代码组织方式。

解析

  • 选项式 API 生命周期
    • beforeCreatecreated(实例创建前后)
    • beforeMountmounted(挂载前后)
    • beforeUpdateupdated(更新前后)
    • beforeUnmountunmounted(卸载前后)
  • 组合式 API
    • setup 函数是组合式 API 的入口,在 beforeCreate 之前执行。
    • 响应式数据:refreactive
    • 生命周期钩子:onMountedonUpdatedonUnmounted 等。
    • 计算属性:computed
    • 侦听器:watchwatchEffect
  • 优势:更好的逻辑复用、类型推导、代码组织。

案例(组合式 API):

<template> <div> <p>计数: {{ count }}</p> <button @click="increment">+1</button> </div> </template> <script setup> import { ref, onMounted } from 'vue'; const count = ref(0); function increment() { count.value++; } onMounted(() => { console.log('组件已挂载'); }); </script> 

4.3 虚拟 DOM 与 Diff 算法

讲解:Vue 通过虚拟 DOM 描述真实 DOM 结构,在数据变化时生成新的虚拟 DOM,与旧虚拟 DOM 进行 Diff 比较,找出最小更新范围,然后批量更新真实 DOM。

解析

  • Vue 的 Diff 策略(基于 Snabbdom):
    • 同层比较,不跨级复用。
    • 通过 key 优化列表渲染,识别节点移动、添加、删除。key 应稳定、唯一,避免使用索引。
    • 双端比较算法(Vue 2)或快速 Diff(Vue 3),提升性能。
  • Vue 3 优化:静态树提升、静态属性提升、事件缓存等,减少更新开销。

案例

<template> <ul> <li v-for="item in items" :key="item.id">{{ item.name }}</li> </ul> </template> <script setup> import { ref } from 'vue'; const items = ref([ { id: 1, name: '苹果' }, { id: 2, name: '香蕉' } ]); </script> 

4.4 状态管理

讲解:随着应用规模增大,需要统一管理共享状态。Vue 官方推荐 Vuex(Vue 2)或 Pinia(Vue 3)。

解析

  • Vuex
    • 核心概念:state(状态)、getters(派生状态)、mutations(同步修改)、actions(异步操作)、modules(模块)。
    • 原则:状态变更必须通过提交 mutation,便于追踪。
  • Pinia
    • 更简洁的 API,完全支持 TypeScript,去除了 mutations,直接在 actions 中修改 state。
    • 每个 store 独立定义,模块化自然。
  • 对比:Pinia 已成为 Vue 官方推荐,替代 Vuex。

案例(Pinia):

// stores/counter.jsimport{ defineStore }from'pinia';exportconst useCounterStore =defineStore('counter',{state:()=>({count:0}),getters:{double:(state)=> state.count *2},actions:{increment(){this.count++;}}});// 组件中使用<script setup>import{ useCounterStore }from'./stores/counter';const counter =useCounterStore();</script><template><p>{{ counter.count }}*2={{ counter.double }}</p><button @click="counter.increment">增加</button></template>

4.5 路由原理

讲解:前端路由根据 URL 变化渲染不同组件,无需刷新页面。Vue 官方路由库是 Vue Router。

解析

  • Hash 模式:利用 window.location.hashhashchange 事件。
  • History 模式:利用 HTML5 History API(pushStatereplaceState),监听 popstate 事件。需要服务端配合避免 404。
  • Vue Router 核心
    • 定义路由映射表。
    • <router-view> 显示匹配的组件。
    • <router-link> 导航链接。
    • 动态路由、嵌套路由、导航守卫等。

案例

// router/index.jsimport{ createRouter, createWebHistory }from'vue-router';import Home from'../views/Home.vue';import About from'../views/About.vue';const routes =[{path:'/',component: Home },{path:'/about',component: About }];const router =createRouter({history:createWebHistory(), routes });exportdefault router;// main.js 中使用 app.use(router);

4.6 服务端渲染(SSR)

讲解:SSR 在服务器端渲染 HTML 字符串,发送到客户端,提升首屏加载速度和 SEO。Vue 官方 SSR 方案是 Vue + Vue Router + Vue Server Renderer,或使用 Nuxt 框架。

解析

  • Nuxt.js:基于 Vue 的 SSR 框架,提供文件路由、自动代码分割、静态站点生成等。
  • 原理:服务器执行 Vue 组件,生成 HTML,客户端激活(hydration)使页面可交互。
  • 优点:SEO 友好、更快首屏内容。
  • 缺点:服务器负载增加、开发复杂度上升。

案例(Nuxt 3 页面):

<template> <div> <h1>{{ title }}</h1> <p>服务端渲染示例</p> </div> </template> <script setup> // 在服务端和客户端都会执行 const { data: title } = await useFetch('/api/title'); </script> 

5. 工程化与工具

5.1 Webpack 原理与配置

讲解:Webpack 是一个模块打包工具,将项目中的模块(JS、CSS、图片等)打包成静态资源。

解析

  • 核心概念
    • Entry:入口文件,依赖图起点。
    • Output:输出文件位置和名称。
    • Loader:处理非 JS 文件(如 CSS、图片),将其转换为模块。
    • Plugin:执行更广泛的任务(如压缩、提取 CSS、生成 HTML)。
    • Mode:development/production,内置优化。
  • 常用 Loaderbabel-loader(转译 ES6+)、css-loader(解析 CSS)、style-loader(注入 style 标签)、file-loader/url-loader(处理资源)。
  • 常用 PluginHtmlWebpackPlugin(生成 HTML)、MiniCssExtractPlugin(提取 CSS)、DefinePlugin(定义环境变量)、TerserPlugin(压缩 JS)。
  • 构建流程
    1. 初始化参数:从配置文件和 Shell 语句中读取合并参数。
    2. 开始编译:初始化 Compiler 对象,加载插件。
    3. 确定入口:根据 Entry 找到所有依赖模块。
    4. 编译模块:从入口开始,递归调用 Loader 转译模块。
    5. 完成模块编译:得到每个模块的最终内容和依赖关系。
    6. 输出资源:根据依赖关系组装 Chunk,生成文件列表。
    7. 写入文件系统。

案例(webpack.config.js 简化):

const HtmlWebpackPlugin =require('html-webpack-plugin');const MiniCssExtractPlugin =require('mini-css-extract-plugin'); module.exports ={entry:'./src/index.js',output:{filename:'bundle.[contenthash].js',path: path.resolve(__dirname,'dist')},module:{rules:[{test:/\.js$/,use:'babel-loader'},{test:/\.css$/,use:[MiniCssExtractPlugin.loader,'css-loader']}]},plugins:[newHtmlWebpackPlugin({template:'./src/index.html'}),newMiniCssExtractPlugin({filename:'styles.[contenthash].css'})]};

5.2 Babel 原理

讲解:Babel 是一个 JavaScript 编译器,将 ES6+ 代码转换为向后兼容的版本。

解析

  • 工作流程
    1. 解析(Parse):将源码解析为抽象语法树(AST)。
    2. 转换(Transform):遍历 AST,通过插件修改节点。
    3. 生成(Generate):将修改后的 AST 生成目标代码。
  • 预设(Presets):一组插件的集合,如 @babel/preset-env 根据目标环境自动转换。
  • 插件(Plugins):单个转换功能,如 @babel/plugin-transform-arrow-functions

案例(babel.config.js):

module.exports ={presets:[['@babel/preset-env',{targets:'> 0.25%, not dead'}]],plugins:['@babel/plugin-proposal-optional-chaining']};

5.3 模块化

讲解:模块化解决命名冲突、依赖管理等问题。

解析

  • CommonJS(Node 环境):module.exports / exports 导出,require 导入。同步加载。
  • ES Module(ES6 标准):export / export default 导出,import 导入。静态分析,异步加载,支持 Tree Shaking。
  • AMDrequire.js 实现,浏览器端异步加载。
  • UMD:兼容 CommonJS 和 AMD 的通用模块定义。

案例

// ES Module 导出exportconst name ='module';exportdefaultfunctionsayHi(){ console.log('Hi');}// 导入import sayHi,{ name }from'./module.js';

5.4 Git 工作流

讲解:Git 是分布式版本控制系统,团队协作需规范流程。

解析

  • 常用命令git clonegit addgit commitgit push/pullgit branchgit mergegit rebase
  • 分支策略
    • Git Flow:master(稳定)、develop(开发)、feature/*(功能)、release/*(发布)、hotfix/*(紧急修复)。
    • GitHub Flow:master 始终可部署,从 master 拉取功能分支,完成后提 PR 合并。
    • GitLab Flow:环境分支(pre-productionproduction)结合合并请求。
  • Merge 与 Rebase 区别merge 保留历史分支,rebase 使历史线性,但需注意公共分支不要 rebase。

案例

# 创建功能分支git checkout -b feature/new-button # 开发后提交gitadd.git commit -m"add new button"# 合并到主分支git checkout main git merge feature/new-button 

5.5 CI/CD 基础

讲解:持续集成/持续部署自动化构建、测试、部署流程。

解析

  • CI:开发频繁合并代码到主干,自动构建和测试,及早发现问题。
  • CD:通过 CI 验证后,自动部署到预发布或生产环境。
  • 常见工具:Jenkins、GitHub Actions、GitLab CI、Travis CI。
  • 流程示例:push 代码 → 触发 CI 运行测试 → 测试通过 → 构建镜像/打包 → 部署到服务器。

案例(GitHub Actions 简化):

name: CI/CD on:[push]jobs:build:runs-on: ubuntu-latest steps:-uses: actions/checkout@v2 -run: npm install -run: npm test -run: npm run build -name: Deploy uses: peaceiris/actions-gh-pages@v3 with:github_token: ${{ secrets.GITHUB_TOKEN }}publish_dir: ./dist 

6. 性能优化

6.1 加载优化

  • 减少 HTTP 请求:合并 CSS/JS 文件,使用雪碧图,内联小资源。
  • 资源压缩:Gzip/Brotli 压缩文本文件,压缩图片(WebP、压缩工具)。
  • 使用 CDN:将静态资源分布到全球节点,加速用户访问。
  • 懒加载:图片、路由组件等按需加载,减少首屏资源。
  • 预加载/预连接<link rel="preload"> 预加载关键资源,dns-prefetchpreconnect 提前解析 DNS 和建立连接。

案例

<!-- 预加载关键样式 --><linkrel="preload"href="main.css"as="style"><!-- 预连接第三方域名 --><linkrel="preconnect"href="https://api.example.com"><!-- 图片懒加载 --><imgsrc="placeholder.jpg"data-src="real.jpg"loading="lazy"alt="...">

6.2 渲染优化

  • 减少重排重绘:参见 3.2 节。
  • 避免内存泄漏:及时解绑事件、清除定时器、销毁全局变量。
  • 使用 will-change:提示浏览器准备优化某个元素的变化。
  • 长列表优化:虚拟列表(只渲染可视区域),如 vue-virtual-scroller。
  • Web Worker:将复杂计算放在后台线程,避免阻塞主线程。

案例

// 使用 will-change.animated { will-change: transform, opacity;}// Vue 中使用虚拟列表(假设有大量数据)<template><RecycleScroller :items="list":item-size="50" key-field="id" v-slot="{ item }"><div>{{ item.name }}</div></RecycleScroller></template>

6.3 打包优化

  • 代码分割:Webpack 的 splitChunks 提取公共依赖,路由懒加载。
  • Tree Shaking:移除未使用的代码,需 ES Module 支持。
  • 按需加载:第三方库如 Lodash 使用 lodash-es 或插件按需引入。
  • 压缩代码TerserPlugin 压缩 JS,CssMinimizerPlugin 压缩 CSS。
  • 图片优化:压缩图片,使用 url-loader 将小图片转为 base64。

案例

// Vue 路由懒加载const routes =[{path:'/about',component:()=>import('./views/About.vue')}];// Webpack splitChunksoptimization:{splitChunks:{chunks:'all',cacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,name:'vendors'}}}}

6.4 性能指标

讲解:以用户为中心的性能指标,用于量化体验。

解析

  • FP(First Paint):首次绘制像素。
  • FCP(First Contentful Paint):首次绘制任何内容(文本、图片)。
  • LCP(Largest Contentful Paint):最大内容绘制时间,衡量主要内容加载速度。
  • FID(First Input Delay):首次输入延迟,衡量交互响应性。
  • CLS(Cumulative Layout Shift):累计布局偏移,衡量视觉稳定性。
  • TTI(Time to Interactive):可交互时间。
  • 工具:Lighthouse、Chrome DevTools Performance 面板。

案例

// 使用 Performance API 测量 FCPnewPerformanceObserver((entryList)=>{for(const entry of entryList.getEntries()){ console.log('FCP:', entry.startTime);}}).observe({type:'paint',buffered:true});

7. 数据结构与算法(前端常考)

7.1 常见数据结构

  • 数组:连续内存,查找 O(1),插入删除 O(n)。
  • 链表:非连续,插入删除 O(1),查找 O(n)。
  • :后进先出(LIFO),如括号匹配。
  • 队列:先进先出(FIFO),如任务队列。
  • :二叉树、二叉搜索树、平衡树(红黑树)。
  • 哈希表:键值对,查找 O(1),处理冲突(链表法、开放寻址)。

案例

// 栈应用:括号匹配functionisValid(s){const stack =[];const map ={'(':')','[':']','{':'}'};for(let c of s){if(map[c]){ stack.push(c);}else{const top = stack.pop();if(map[top]!== c)returnfalse;}}return stack.length ===0;} console.log(isValid('()[]{}'));// true

7.2 排序算法

  • 冒泡排序:O(n²),稳定。
  • 快速排序:O(n log n) 平均,不稳定,分治思想。
  • 归并排序:O(n log n),稳定,分治+合并。
  • 选择排序:O(n²),不稳定。
  • 插入排序:O(n²),稳定,适合小规模数据。

案例

// 快速排序functionquickSort(arr){if(arr.length <=1)return arr;const pivot = arr[0];const left =[], right =[];for(let i =1; i < arr.length; i++){ arr[i]< pivot ? left.push(arr[i]): right.push(arr[i]);}return[...quickSort(left), pivot,...quickSort(right)];} console.log(quickSort([3,6,8,10,1,2,1]));// [1,1,2,3,6,8,10]

7.3 递归与迭代

讲解:递归函数调用自身,需有终止条件;迭代通过循环实现。

解析

  • 递归缺点:可能导致栈溢出,性能较低(可优化为尾递归)。
  • 适用场景:树的遍历、分治算法。
  • 示例:斐波那契数列、汉诺塔。

案例

// 递归求斐波那契(有大量重复计算,可优化)functionfib(n){if(n <=1)return n;returnfib(n-1)+fib(n-2);}// 迭代优化functionfibIter(n){let a =0, b =1;for(let i =2; i <= n; i++){[a, b]=[b, a + b];}return n ===0? a : b;}

7.4 常见算法题

  • 数组去重:利用 Set、filter + indexOf、reduce。
  • 数组扁平化:递归、flat(Infinity)、reduce + concat。
  • 函数柯里化:将多参数函数转换为一系列单参数函数。
  • 节流/防抖:见 2.8。
  • 深拷贝:见 2.7。
  • 手写 Promise:考察对异步的理解。
  • 查找最长无重复子串:滑动窗口。

案例

// 数组扁平化functionflatten(arr){return arr.reduce((acc, val)=> Array.isArray(val)? acc.concat(flatten(val)): acc.concat(val),[]);} console.log(flatten([1,[2,[3,4],5]]));// [1,2,3,4,5]// 函数柯里化functioncurry(fn){returnfunctioncurried(...args){if(args.length >= fn.length){returnfn.apply(this, args);}else{return(...args2)=>curried.apply(this, args.concat(args2));}};}constadd=(a,b,c)=> a+b+c;const curriedAdd =curry(add); console.log(curriedAdd(1)(2)(3));// 6

8. 设计模式与架构

8.1 常见设计模式

  • 单例模式:确保一个类只有一个实例,如全局状态管理(Pinia store)。
  • 观察者模式:主题维护观察者列表,状态变化时通知所有观察者(如 Vue 的响应式系统)。
  • 发布订阅模式:类似观察者,但通过事件中心解耦,如 EventBus。
  • 工厂模式:创建对象而不指定具体类,如 Vue 的 createApp
  • 策略模式:定义一系列算法,封装起来可互换,如表单验证策略。
  • 代理模式:为对象提供替代或占位符,控制访问,如虚拟代理(图片懒加载)。

案例(发布订阅):

classEventBus{constructor(){this.events ={};}on(event, listener){(this.events[event]||(this.events[event]=[])).push(listener);}emit(event, data){(this.events[event]||[]).forEach(listener=>listener(data));}off(event, listener){if(!this.events[event])return;this.events[event]=this.events[event].filter(l=> l !== listener);}}const bus =newEventBus(); bus.on('login',(user)=> console.log('登录:', user)); bus.emit('login',{name:'Alice'});

8.2 MVC / MVVM 模式

  • MVC:Model(数据)、View(视图)、Controller(业务逻辑)。用户操作→Controller→更新Model→更新View。
  • MVVM:Model、View、ViewModel(数据绑定器)。通过双向绑定,View 变化自动更新 Model,反之亦然。如 Vue 的响应式系统。

案例:Vue 是 MVVM 的典型实现,ViewModel 对应组件实例,Model 对应 data,View 对应模板。


9. 软技能与开放性题目

  • 项目经验:能清晰描述项目背景、技术选型、个人贡献、难点及解决方案。
  • 团队协作:沟通方式、代码审查、冲突解决。
  • 学习能力:关注新技术、阅读源码、参与社区。
  • 开放性题目:如“如果让你设计一个前端监控系统,你会怎么做?”可从数据采集(性能、错误、行为)、上报策略、数据可视化等方面展开。

案例:回答前端监控系统设计时,可提及使用 Performance API 收集指标,通过 Beacon API 上报,利用错误事件监听 JS 错误,使用 Sentry 等工具。


总结

前端面试覆盖范围广、深度要求高。本文从基础到进阶,系统梳理了 HTML/CSS、JavaScript、浏览器网络、框架(以 Vue 为例)、工程化、性能优化、算法设计模式等核心知识点,并给出了深入解析及案例。希望你能结合这些内容,举一反三,在面试中不仅“知其然”,更能“知其所以然”,展现出作为一名高级前端开发工程师的技术底蕴和解决问题的能力。祝你面试顺利!

Read more

【亲测免费】 vcredist_x86安装包简介:一键安装微软Visual C++运行时组件

vcredist_x86安装包简介:一键安装微软Visual C++运行时组件 【下载地址】vcredist_x86安装包简介本项目提供了vcredist_x86安装包的压缩文件下载,这是微软Visual C++ Redistributable Packages的32位版本。该安装包确保您的计算机能够顺利运行由Visual C++开发的应用程序,自动安装所需的运行时组件。在安装前,请确认您的操作系统为32位,并关闭不必要的程序以确保安装顺利进行。安装完成后,建议重启计算机以使所有更改生效。通过使用本项目资源,您将获得更流畅的应用程序运行体验。 项目地址: https://gitcode.com/Universal-Tool/dd775 项目介绍 在软件开发和日常使用中,经常遇到一些应用程序需要特定的运行时组件才能正常运行的情况。vcredist_x86安装包正是为了解决这一问题而诞生。该仓库提供了vcredist_x86.zip文件的下载,这是微软Visual C++ Redistributable Packages的安装程序,专门为32位(x86)操作系统设计。通过安装此包,

By Ne0inhk

终极解决方案:Visual C++ Redistributable完整修复指南

终极解决方案:Visual C++ Redistributable完整修复指南 【免费下载链接】vcredistAIO Repack for latest Microsoft Visual C++ Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 当您安装游戏或专业软件时,是否遭遇过"缺少MSVCP140.dll"或"VCRUNTIME140_1.dll丢失"等错误?作为运行C++程序的必备组件,Microsoft Visual C++ Redistributable的安装问题常常让用户束手无策。本指南将系统梳理最常见的安装失败场景,提供从自动修复到手动排障的全流程解决方案。 问题场景:识别典型故障模式 场景一:静默安装失败 情境描述:双击安装程序后无任何提示,窗口瞬间消失,

By Ne0inhk
模拟面试:C与C++最大的区别在哪里?它们又有什么共同之处呢?

模拟面试:C与C++最大的区别在哪里?它们又有什么共同之处呢?

序章:一个不寻常的情人节 空气中弥漫着玫瑰和巧克力的甜腻气息,但我,一个即将毕业的计算机系本科生,却正襟危坐在一间锃亮的会议室里,迎接我“梦中情司”的最终技术面。 坐在我对面的,是业界闻名的技术总监,江湖人称“代码道长”的李总。他身着一件格子衫,发量虽不茂密但精神矍铄,眼神中透着一股能看穿你数据结构的锐利。 “小同学,别紧张,”李总呷了一口保温杯里的枸杞茶,笑呵呵地开口,“今天是情人节,咱们也聊点有‘感情’的话题。在我看来,C语言和C++就像一对相爱相杀的兄弟。你,作为我们未来的工程师,能不能给我当个‘家庭调解员’,聊聊这对兄弟最大的区别在哪里?它们又有什么割舍不掉的共同之处呢?别背八股文,用你自己的理解,讲得生动点。” 我心里一紧,这问题看似基础,实则深不见底。但我知道,这正是我展示自己对底层技术理解深度的绝佳机会。深吸一口气,我决定将这次面试,变成一场关于C与C++的“世纪对谈”。 第一幕:血浓于水——C与C+

By Ne0inhk
Moveit2使用说明(C++)

Moveit2使用说明(C++)

Moveit安装:https://moveit.ai/如果是Ubuntu22.04 ros2-humble 系统可以参考:Ubuntu22.04 ros2-humble 源码安装 Moveit2 关于Moveit入门的官方文档:https://moveit.picknik.ai/main/index.html PS:本文基于官方文档内容,记录学习的过程,同时有一些错误做了修改。 https://github.com/moveit/moveit2_tutorials/issues/1006 由于官方声明humble版本中没有Python API,所以本文是基于C++。 目录 * 0.MoveIt2的核心架构 * 1.Tutorials——Getting Started * 2.Tutorials——MoveIt Quickstart in RViz * 步骤

By Ne0inhk