前端面试灵魂提问(1)
1.自我介绍
2.在实习中,你负责那一模块
3.any与unknow的异同
相同点:any和unkonwn 可以接受任何值
不同点:any会丢掉类型限制,可以用any
类型的变量随意做任何事情。unknown
变量会强制执行类型检查,所以在使用一个 unknown
类型的变量之前,你需要进行类型检查。
4. type 与 interface 和 class 的异同
Class是用于定义对象的结构和行为,它是数据和行为的封装(实现方法)。
Interface是用于描述对象的结构和行为的规范,它是对类的抽象。接口定义了对象应具备的属性和方法,但不提供实现。 接口可以用来描述类的公共部分,并且类可以实现一个或多个接口。
Type是用于定义数据的形状和结构,它是对数据的抽象。
Class用于创建对象,Interface用于定义规范,而Type用于定义数据类型。
class与interface的区别
type
是 TypeScript 中用于定义类型别名、联合类型、交叉类型等复杂类型的声明方式。type 和 interface 定义的类型信息在编译后的 JavaScript 代码中被移除,因为它们仅在编译阶段用于类型检查。换句话说,type
不需要运行时信息。相比之下,class 定义的类型信息会保留在编译后的代码中,因为它们包含实际的属性和方法实现,这些信息在运行时是必需的。interface
主要用于定义对象的类型和结构,不提供具体实现。它支持继承extends和实现implements。
interface与type的区别
- interface 使用 extends 实现继承, type 使用交叉类型实现继承。
- type 可以,类型别名会给一个类型起个新名字,声明基本类型、联合类型、交叉类型、元组。interface 不行。
-
interface可以合并重复声明,type 不行,重复声明 type ,就报错了
interface Person {
name: string
}
type Person = {
name: string
}
interface Student extends Person {
grade: number
}
interface Student extends Person {
grade: number
}
type Student = Person & { grade: number } 用交叉类型
type Student = Person & { grade: number } 用交叉类型
const person:Student = {
name: 'lin',
grade: 100
}
type Name = string // 基本类型
type arrItem = number | string // 联合类型
const arr: arrItem[] = [1,'2', 3]
type Person = {
name: Name
}
type Student = Person & { grade: number } // 交叉类型
type Teacher = Person & { major: string }
type StudentAndTeacherList = [Student, Teacher] // 元组类型
const list:StudentAndTeacherList = [
{ name: 'lin', grade: 100 },
{ name: 'liu', major: 'Chinese' }
]
interface Person {
name: string
}
interface Person { // 重复声明 interface,就合并了
age: number
}
const person: Person = {
name: 'lin',
age: 18
}
type Person = {
name: string
}
type Person = { // Duplicate identifier 'Person'
age: number
}
5.vue的最佳实践
编码风格
- 命名组件时用多个单词,避免跟现有及未来的
HTML
元素相冲突 prop
属性定义应尽量详细,至少要指定类型- 组件
data
必须是个函数,避免多个组件数据互相影响 - 使用
v-for
务必加上key
,且避免和v-if
写在一起 - 为组件样式设置作用域,使用
scoped
属性,使用 BEM 约定 - 私有
property
名,使用$_
前缀,避免产生冲突
最佳实践(性能优化)
1、组件按需加载
const Home = () => import('@/components/home')
使用 import
动态导入,配合 webpack
tree-shaking
摇树功能,没有用到的组件就不会打包到 chunk
,从而提升加载性能。
2、提升首屏加载速度
参考:【Vue】从实际开发出发,浅谈vue的最佳实践 - 掘金 (juejin.cn)
2.1、webpack体积优化
2.1.1、编译优化
1)配置module.noParse,比如 JQuery、Lodash 已经是可以直接运行在浏览器的文件,就不必再搜索解析。告诉webpack不必解析某些文件。
2)配置loader,通过test、include、exclude缩小搜索范围,例如:
module.exports = {
//...
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
include: [resolve('src')],
exclude: /node_modules/,
}
]
}
}
3)解析loader开启多进程,使用thread-loader,
只要把 thread-loader 放置在其他 loader 之前。
4)合理利用缓存,对性能开销较大的 loader启用缓存(保存和读取这些缓存文件会有一些时间开销),比如使用loader本身的缓存或使用cache-loader
2.1.2、代码压缩打包时间过久的优化方式
1)terser-webpack-plugin 或uglifyjs-webpack-plugin压缩代码插件开启多进程并行、缓存模式
2.1.3、构建体积
bundle文件里包含了很多较大的第三方依赖包、业务代码js/css、以及图片资源等。配置externals,防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。
module.exports = {
//...
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
axios: 'axios',
...
},
};
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vuex/3.0.1/vuex.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.0.1/vue-router.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.0/axios.min.js"></script>
2.2、可改造成SSR,减少首屏加载时间
使用SSR
服务端渲染,将组件或是页面通过服务器生成html
字符串,再发送到浏览器,这样可以加快首屏加载渲染的速度,提前显示文档内容。
在服务器配置SSR,项目中在激活模式下挂载应用,我们应该使用 createSSRApp() 而不是 createApp()
:
3、不需要更新的内容静态化
可以将不需要更新的节点内容静态化,这样可以优化更新性能。
4、尽量减少DOM层级嵌套
diff算法比较,dom的性能消耗很大
5、不活动的组件,可用<keep-alive>
缓存
6、让传给子组件的 props 尽量保持稳定
只要需要修改的子组件的props会发生变化
7、大数据量的渲染优化
虚拟列表
其实是按需显示的一种实现,即只对可见区域
进行渲染,对非可见区域
中的数据不渲染。实际上就是在首屏加载时,只加载可视区域的列表项,当滚动发生时,动态计算获取可视区域内的列表项,并将非可视区域的列表项删除。当滚动后,由于渲染区域
相对于可视区域
已经发生了偏移,此时我需要获取一个偏移量startOffset
,通过样式控制将渲染区域
偏移至可视区域
中。
参考:「前端进阶」高性能渲染十万条数据(虚拟列表) - 掘金 (juejin.cn)
6、画一个平行四边形
.button {
background-color: aqua;
transform: skewX(-45deg);
}
.button>div {
transform: skewX(45deg);
}
<div class="button">
<div>Click me</div>
</div>
7、早期服务端渲染--客户端渲染--服务端渲染
参考:(一文带你入门SSR)从传统服务端渲染到客户端渲染再到现代化的服务端渲染 - 掘金 (juejin.cn)
1.早期Web页面渲染都是在服务端完成的,应用的前后端部分完全耦合在一起,内容都是在服务端动态生成的,所以服务端的压力较大;
2.基于客户端渲染的 SPA 应用,把【数据处理】和【页码渲染】分开,也就是【后 端】负责数据处理,【前端】负责页面渲染。因为 HTML 中没有内容,等到 JavaScript 加载,首屏渲染慢,SEO 问题。
3.服务端渲染或同构渲染即【服务端渲染】 + 【客户端渲染】,
8.图片懒加载
8、伪元数选择器
DNS会发生域名与ip的转化,或发生IP与mac的转化吗?
不受跨域限制的标签