当前位置: 首页 > news >正文

前端面试准备-1

1.NodeJS的优缺点

优点:
 · 高并发(最重要的优点)
 · 适合I/O密集型应用

缺点:
 · 不适合CPU密集型应用;CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;
   解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;
 · 只支持单核CPU,不能充分利用CPU
 · 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃
   原因:单进程,单线程
   解决方案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
        (2)开多个进程监听同一个端口,使用cluster模块;
 · 开源组件库质量参差不齐,更新快,向下不兼容
 · Debug不方便,错误没有stack trace

2.文件上传的优化

  • 文件压缩。对图片、视频等资源,使用前端压缩(如使用 compressorjs)减少上传体积。
  • 分片上传(大文件)。将大文件拆分成多个小块分片上传。
  • 并发上传控制。控制并发数(如最多同时上传 3 个文件)防止资源占用过高;使用 Promise.allSettled、任务队列或限制上传并发工具(如 p-limit)。

3.切片上传的要点

核心思想是:将大文件拆成若干小片段分批上传,最终由后端合并还原成完整文件。

  • 切片策略:切片大小设置,然后使用 File.slice() API 切割
  • 文件唯一标识(fileId):为了正确合并和续传,需要为文件生成唯一标识(通常基于文件名 + 文件大小 + hash)
  • 上传控制逻辑:顺序或并发上传切片,通常采用 并发上传(5~10 并发) 提高性能;同时携带元信息,每个切片应携带fileId、当前分片索引(chunkIndex)、分片总数(totalChunks)、是否为最后一块、可选的 MD5 校验值
  • 后端配合

4.ES6 特性

①:let和const

  • let: 块级作用域,允许变量重新赋值

  • const: 块级作用域,不允许重新赋值(但对象内容可变)

②:symbol

Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值,不能与其他数据类型进行运算。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列。

③:模板字符串

  • 在ES6之前,处理模板字符串:通过“\”和“+”来构建模板
  • 对ES6来说:用${}来界定;反引号(``)直接搞定;
<script>url="x"// es6之前let html="<div>"+" <a>"+url+"</a>"+"</div>";//es6let eshtml=`<div><a>${url}</a></div>`
</script>

④:解构表达式

解构赋值是对赋值运算符的扩展。它是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。字符串、以及ES6新增的Map和Set 都可以使用解构表达式

//数组解构let [a,b,c] = [1,2,3];
console.log(a,b,c);    //1,2,3let [a,b,c] = [1,,3];
console.log(a,b,c);    //1,undefined,3let [a,,b] = [1,2,3];
console.log(a,b);//1,3let [a,..b] = [1,2,3];  //...是剩余运算符,表示赋值运算符右边除第一个值外剩余的都赋值给b
console.log(a,b);//1,[2,3]//对象解构
let obj = { name: "山里", age: 18, sex: "m" 
};let { name, age, sex } = obj;
console.log(name, age, sex); //'山里' 18 'm'let { name: myName, age: myAge, sex: mySex } = obj; //自定义变量名
console.log(myName, myAge, mySex); //'山里' 18 'm'

⑤:Map和Set属于es6新增加的对象

  • Map对象用于保存键值对,任何值JavaScript支持的值都可以作为一个键(key)或者一个值(value)。
  • Set对象和Map对象类似,但它存储不是键值对。类似数组,但它的每个元素都是唯一的
const set = new Set([1, 2, 2, 3]); // 去重
const map = new Map([['a', 1], ['b', 2]]);

⑥:函数增强

  • 默认参数
//默认参数
function greet(name = '游客') {console.log(`你好,${name}`);
}
  • 箭头函数。箭头函数实现了一种更加简洁的书写方式。箭头函数内部没有arguments,也没有prototype属性,所以不能用new关键字调用箭头函数。
    箭头函数和普通函数最大的区别在于其内部this永远指向其父级对象的this。(重点)
let add = (a,b) => {return a+b;
}
let print = () => {console.log('hi');
}
let fn = a => a * a;
//当只有一个参数时,括号可以省略,函数体只有单行return语句时,大括号也可以省略。

⑦:类(Class)

class 作为对象的模板被引入ES6,你可以通过 class 关键字定义类。class 的本质依然是一个函数。

//类的定义和继承
class Person {constructor(name) {this.name = name;}sayHi() {console.log(`Hi, I'm ${this.name}`);}
}class Student extends Person {constructor(name, grade) {super(name);this.grade = grade;}
}

⑧:模块化(Module)

优点:1.防止命名冲突;2.复用性强

// a.js
export const PI = 3.14;
export default function add(a, b) { return a + b; }// b.js
import add, { PI } from './a.js';

⑨:Promise 异步处理

const p = new Promise((resolve, reject) => {setTimeout(() => resolve('成功'), 1000);
});
p.then(result => console.log(result));

5. async-await 和 Promise的关系

async/awaitPromise 是 JavaScript 中处理异步操作的两种方式。其中,async/await 是建立在 Promise 之上的语法糖

特性Promiseasync/await
语法形式.then() / .catch()async 函数 + await
可读性回调链(可能嵌套过多)更像同步代码,结构清晰
错误处理.catch()try...catch
基础依赖原生特性构建于 Promise 之上
// Promise 写法
function getData() {return new Promise((resolve, reject) => {setTimeout(() => resolve('数据已获取'), 1000);});
}getData().then(res => {console.log(res);}).catch(err => {console.error(err);});
// async/await 写法
function getData() {return new Promise((resolve, reject) => {setTimeout(() => resolve('数据已获取'), 1000);});
}async function fetchData() {try {const res = await getData(); // 等待 Promise 完成console.log(res);} catch (err) {console.error(err);}
}fetchData();//await 后面跟的是一个 Promise
//async/await 实际上是对 Promise 的封装与优化

6.async-await原理

async/await 是基于 Promise 的语法糖,使得异步代码看起来像同步代码。async 函数返回一个 Promise 对象,await 表达式用于等待一个 Promise 完成。

async/await 的底层实现可以类比于生成器(Generator)函数和自动执行器。生成器函数可以在执行过程中暂停和恢复,这为实现异步流程控制提供了可能。

7.箭头函数和普通函数

特性普通函数箭头函数
this 指向动态绑定,由调用方式决定静态绑定,取决于定义时所在作用域
arguments 对象arguments 对象没有 arguments,可用 rest 参数代替
构造函数可作为构造函数(new Fn()❌ 不可作为构造函数,不能 new
原型 prototype.prototype 属性没有 .prototype 属性
代码简洁性相对冗长更加简洁,适合写匿名函数或回调
能否绑定 this可使用 bind, call, apply 绑定无效,this 永远固定(词法作用域)

*this 指向:普通函数:调用时决定 this。箭头函数:定义时决定 this(继承外层作用域)

8.lodash的深拷贝怎么实现

在JavaScript中,我们经常需要复制对象。但是,JavaScript的对象复制通常只是浅复制,这意味着它只复制对象的最顶层属性,而不复制嵌套对象或数组的内部元素。这就是为什么我们有时需要深拷贝的原因。深拷贝将复制对象的所有层级,包括嵌套的对象和数组。

在使用 Lodash 时,可以通过 _.cloneDeep 方法实现 深拷贝(deep copy),这是 Lodash 提供的内置方法,用于递归地克隆一个值,包括嵌套的对象、数组等复杂数据结构。

9.对象环引用的检测

①:设置检查标记。可以给每个对象设置一个标记;或者使用 WeakSet 代替显式打标。

②:将对象引用地址存入数组,检测是否已存在。可以改进用 Set 代替数组。

10.vue中的computed和watch

①:computed(计算属性)

  • 作用:基于响应式依赖进行缓存的派生计算

  • 特点

    • 返回一个值

    • 仅在依赖变化时重新计算

    • 用于模板中展示或复杂逻辑封装

  • <template><div>总价:{{ totalPrice }}</div>
    </template><script setup>
    import { ref, computed } from 'vue';const price = ref(100);
    const count = ref(2);//  自动依赖 price 和 count,且具备缓存
    const totalPrice = computed(() => price.value * count.value);
    </script>

②:watch(侦听器)

  • 作用:在数据变化时执行副作用逻辑

  • 特点

    • 适合执行异步操作、手动处理逻辑

    • 可以侦听多个源或深层属性

  • <script setup>
    import { ref, watch } from 'vue';const searchText = ref('');// 监听输入内容变化,做防抖搜索等副作用处理
    watch(searchText, (newVal, oldVal) => {console.log(`搜索内容从 "${oldVal}" 变为 "${newVal}"`);// 可调用 API 等操作
    });
    </script>
    

11.reactive

在 Vue 3 中,reactive 是 Composition API 中用于创建响应式对象的核心方法。它可以将一个普通的 JavaScript 对象转换为响应式对象,从而在数据发生变化时自动更新视图。

ref 的区别:

特性reactiveref
用于对象、数组、嵌套结构原始值(字符串、数字等)或任意值
响应式访问直接访问属性.value 获取/设置
结构深度响应深层响应 深层对象需搭配 reactive
// reactive 示例
const obj = reactive({ count: 1 });
obj.count++; // 自动响应视图更新// ref 示例
const num = ref(1);
num.value++; // 注意:需要 .value

12.vue2和vue3的区别

①:响应式系统的改变

Vue2 使用 Object.defineProperty 实现响应式,无法直接监听数组下标变动或对象属性的添加/删除。而 Vue3 改为使用 Proxy,可以实现对对象任意属性的监听,性能更高、限制更少,也更易于维护。

②:组合式 API 的引入

Vue2 使用“选项式 API”,即通过 datamethodscomputedwatch 等分散定义组件逻辑,导致逻辑难以复用和维护。

Vue3 引入了“组合式 API”,通过 setup() 函数配合 refreactivecomputed 等函数来组织逻辑,更加灵活,便于逻辑复用和 TypeScript 支持。

③:性能优化

④:TypeScript 支持增强

⑤:新特性的引入

13.模板和JSX

  • JSX 是 JavaScript XML 的缩写,是 React 框架中的一种语法扩展。它允许开发者在 JavaScript 代码中直接编写类似 HTML 的语法,从而更直观地构建用户界面。
  • 模板 (Template) 通常是指在前端框架中使用的一种定义 UI 结构的方式。它们通常与特定的框架绑定,例如 Vue.js 中的模板语法,Angular 中的模板语法等。

①:JSX 的优点
更强的 JavaScript 集成:JSX 是 JavaScript 的一部分,可以在 JSX 代码中编写任意 JavaScript 表达式。这个特性使得组件逻辑和视图可以紧密结合。

单文件组件:使用 JSX 时,组件的模板、逻辑和样式通常在同一个文件中,这使得组件更加自包含,易于管理和重用。

React 生态系统:JSX 是 React 的核心部分,因此使用 JSX 可以更好地利用 React 提供的各种工具和库。

②:JSX 的缺点
学习曲线:对于没有 React 经验的开发者来说,JSX 可能有一定的学习难度,尤其是在理解 JavaScript 和 JSX 之间的转换时。

可读性:虽然 JSX 使得 JavaScript 和模板代码混合在一起,但对于习惯于分离视图和逻辑的开发者来说,这种方式可能会降低代码的可读性。

③:模板的优点
分离关注点:模板语法通常将视图和逻辑分开,保持代码的清晰和可维护性。例如,在 Vue.js 中,模板负责定义视图,而逻辑和数据绑定在组件脚本部分处理。

直观的语法:模板语法通常类似于 HTML,这使得前端开发者尤其是设计师更容易上手和理解。

框架支持:模板语法通常与框架紧密集成,提供丰富的指令和绑定机制,简化了常见的 UI 操作。

④:模板的缺点
灵活性较差:由于模板语法通常是框架特定的,它们在处理复杂逻辑时可能不如 JSX 灵活。

单文件组件限制:虽然模板语法也支持单文件组件,但在某些框架中,模板、逻辑和样式分离在不同的部分,这可能会导致管理上的不便。
 

14.vite和Webpack

15.常用git命令

  • git init   初始化本地 Git 仓库
  • git clone <url>      克隆远程仓库到本地
  • git status         查看当前工作区状态
  • git add .        添加所有修改过的文件到暂存区
  • git commit -m "说明"​​​          提交暂存区到本地仓库​​​​
  •  git branch       查看本地分支
  • git branch <分支名>       创建新分支
  •  git checkout <分支名>          切换分支
  • git push         推送本地改动到远程
  • git log         查看提交历史

16.Vue修改数据后能获取最新的dom?

在 Vue 中,修改数据后不能立即获取最新的 DOM,因为 Vue 的 DOM 更新是异步的。这意味着在你更改响应式数据后,Vue 会在下一个“tick”(事件循环的下一个微任务队列中)统一执行 DOM 更新。

正确获取最新 DOM 的方法:使用 nextTick

这是 Vue 提供的官方方式,等 DOM 更新后再执行回调。

import { nextTick } from 'vue'await nextTick()
// 或
nextTick(() => {// DOM 已更新
})

17.后端传递过来十条数据,前端需要制作一个垂直的无限循环滚动展示的效果。如何实现?

使用 CSS 动画 + JavaScript DOM 克隆机制。将列表复制一份接在原始列表之后,形成“头尾连接”。然后使用 CSS 动画持续向上滚动整个容器,当滚动到底部(即一轮滚完),立即跳回顶部,继续滚动。

<template><div class="news-wrapper"><ul class="news-list" ref="newsList"><li v-for="(news, index) in renderList" :key="index">{{ news }}</li></ul></div>
</template><script setup>
import { ref, onMounted } from 'vue'const news = ["新闻1", "新闻2", "新闻3", "新闻4", "新闻5","新闻6", "新闻7", "新闻8", "新闻9", "新闻10"
]const renderList = [...news, ...news] // 克隆一份实现无缝滚动
</script><style scoped>
.news-wrapper {height: 300px;overflow: hidden;
}
.news-list {animation: scrollUp 10s linear infinite;padding: 0;margin: 0;
}
.news-list li {height: 30px;line-height: 30px;border-bottom: 1px solid #eee;list-style: none;
}@keyframes scrollUp {0% { transform: translateY(0); }100% { transform: translateY(-50%); }
}
</style>

相关文章:

  • 算法 Arrays.sort()函数自定义排序(Comparator 接口)
  • XCTF-web-fileinclude
  • 在 MATLAB 2015a 中如何调用 Python
  • Golang | gRPC demo
  • JS 逆向太费劲,试试 JS 注入!
  • 题海拾贝:P1208 [USACO1.3] 混合牛奶 Mixing Milk
  • 流程自动化引擎:让业务自己奔跑
  • 深入理解设计模式之职责链模式
  • 2025年电气工程与轨道交通国际会议:绿色能源与智能交通的创新之路
  • IACEES 2025:创新材料与能源模式,迎接未来的挑战
  • 多元素纳米颗粒:开启能源催化新纪元
  • 【AI算法工程师面试指北】大模型微调中的灾难性遗忘该如何避免?
  • 登高架设作业考试中常见的安全规范考点是什么?
  • element-plus主题换色
  • Ubuntu22.04 重装后,串口无响应
  • tauri2项目打开某个文件夹,类似于mac系统中的 open ./
  • 【Pandas】pandas DataFrame between_time
  • 域名解析怎么查询?有哪些域名解析查询方式?
  • DAX权威指南5:筛选上下文、表操作函数与层级结构
  • c语言实现Linux命令行补全机制
  • 网站托管服务合同/网络营销课程介绍
  • 企业网站设计能否以/seo职业培训班
  • 成都政务网站建设/百度搜索推广开户
  • 湖北现代城市建设集团网站/西点培训班一般要多少学费
  • 惠安网站建设/搜索引擎营销的内容
  • 有没有教做川菜的网站/网站要怎么创建