一、自我介绍
HR你好,我叫Harry,现就读于XXXX大学大四,是一名软件工程专业的学生。本人是在大二的时候通过一本名为《HTML&CSS设计与构建网站》的书接触到前端开发的,当时主要以兴趣为主,学习了一些基本的HTML、CSS,写了一些简单的页面来玩。到了大三,因为觉得前端比后端更有趣,所以选择了前端的职业路线。在此期间,开始系统学习如JavaScript、ES6、Nodejs、Vue2、小程序等。最近刚学完Typescript,打算接着学习Vue3、Vite等技术;近期也做了几个练手项目,但是个人觉得自己的项目还没达到实际企业要求,所以希望通过实习了解企业级前端项目开发,从中提升自己的专业技能。
二、栈内存和堆内存的区别
相关问题:
-
内存泄漏的理解
-
内存泄漏产生原因(讲了全局变量,闭包,未关闭的定时器延时器,但面试官好像想听到更多的答案)
-
如何应对内存泄漏问题
-
如何检测内存泄漏问题(真没想过)
参考文章:
三、深浅拷贝的区别、实现方法有哪些
千万不要用JSON.stringify()去实现深拷贝!有巨坑!!
四、深拷贝的循环引用如何解决
五、递归和尾递归的区别
六、开发中递归的场景
在云办公项目中,由于存在权限,不同登录者的导航栏是不同的,我们是通过接口到后端查询该登陆者的导航栏数据,根据返回的JSON路由数据进行格式化,这其中就运用到了递归。因为导航栏中每个导航都可能包含子导航,当存在子导航时,就会递归格式化子导航路由对象;这其中没有进行尾递归优化,主要是因为导航栏数量不会超过浏览器的最大递归次数;
import { getRequest } from "./api";
export const initMenu = (router, store)=>{
// 判断store.routes是否有值
if(store.state.routes.length > 0){
return;
}
// 发送请求并处理
getRequest('/system/cfg/menu').then(data=>{
if(data){
// 格式化路由
let fmtRoutes = formatRoutes(data.obj);
// 添加路由
router.addRoutes(fmtRoutes);
// 将数据存入vuex
store.commit('initRoutes', fmtRoutes);
// 连接Socket
store.dispatch('connect')
}
})
}
// 格式化路由的函数
export const formatRoutes = (routes)=>{
let fmtRoutes = [];
routes.forEach(router=>{
if(router.name != '所有'){
let {
path,
component,
name,
iconCls,
children
} = router;
if(children && children instanceof Array){
children = formatRoutes(children)
}
// 格式化好后的对象
let fmRouter = {
path: path,
name: name,
iconCls: iconCls,
children: children,
// 路由组件懒加载ES5
component(resolve){
if(component.startsWith('Home')){
require(['../views/'+component+'.vue'], resolve)
}else if(component.startsWith('Emp')){
require(['../views/emp/'+component+'.vue'], resolve)
}else if(component.startsWith('Per')){
require(['../views/per/'+component+'.vue'], resolve)
}else if(component.startsWith('Sal')){
require(['../views/sal/'+component+'.vue'], resolve)
}else if(component.startsWith('Sta')){
require(['../views/sta/'+component+'.vue'], resolve)
}else if(component.startsWith('Sys')){
require(['../views/sys/'+component+'.vue'], resolve)
}
}
// ES6
// component: () => import ('../views/'+component+'.vue')
}
// 存入数组并返回
fmtRoutes.push(fmRouter)
}
});
// console.log(fmtRoutes);
return fmtRoutes;
}
七、浏览器多标签页之间通信的方式
八、类选择器和标签选择器的性能差异
九、scpoed原理
十、css module和scoped的区别
十一、如何写高质量的css代码
十二、常见的行内元素和块级元素有哪些?
十三、如何转换行内元素和块级元素,如何设置他们的宽高属性?
-
display:block ,定义元素为块级元素
- 每个块级元素都是独自占一行;
- 高度,行高,外边距(margin)以及内边距(padding)都可以控制;
- 元素的宽度如果不设置的话,默认为父元素的宽度(父元素宽度100%;
- 多个块状元素标签写在一起,默认排列方式为从上至下;
-
display : inline ,定义元素为行内元素
- 不会独占一行,相邻的行内元素会排列在同一行里,直到一行排不下才会自动换行,其宽度随元素的内容而变化;
- 高宽无效,对外边距(margin)和内边距(padding)仅设置左右方向有效 上下无效;
- 设置行高有效,等同于给父级元素设置行高;
- 元素的宽度就是它包含的文字或图片的宽度,不可改变;
- 行内元素中不能放块级元素,a 链接里面不能再放链接;
-
display:inline-block,定义元素为行内块级元素
- 高度、行高、外边距以及内边距都可以控制;
- 默认宽度就是它本身内容的宽度,不独占一行,但是之间会有空白缝隙,设置它上一级的 font-size 为 0,才会消除间隙;
十四、css实现隐藏元素的方式有哪些?
十五、如何实现元素垂直居中,有哪些方式?
十六、什么是重排和重绘,怎么减少?
十七、meta是什么原理,什么作用?
十八、跨域解决方法
十九、nginx反向代理如何配置
二十、防抖和节流原理,具体如何实现用代码表示
function debounce(fn, delay=300){
let timer = 0;
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments);
timer = 0;
}, delay);
}
};
function throttle(fn, delay=300){
let timer = 0;
return function(){
if(timer){
return;
}
timer = setTimeout(function(){
fn.apply(this, arguments);
timer = 0;
}, delay)
}
}
二十一、如何交换两个变量的值,不用第三方变量
面试官在“逗”你系列:不借助第三变量交换两个变量值的方案你有几种?
二十二、从输入url到显示网页,整个流程发生了什么
二十三、三个promise实例对象,怎么做才能按照一定顺序输出
有3个异步函数A/B/C,请使用Promise实现ABC的顺序执行
二十四、关于axios和前后端交互的一些问题
二十五、怎么实现懒加载
二十六、Https优缺点
二十七、Http2.0
二十八、js动画怎么实现
- 获取DOM元素,根据动画需求修改CSS样式,并使用transition作过渡
二十九、nodejs原生模块用过哪些
相关问题:用过fs模块的哪些api?readFileSync的参数是什么?
三十、vue生命周期,介绍生命周期中钩子函数等流程
三十一、vuex的一些细节问题
三十二、Vue组件间的通信方式
三十三、v-model原理
- 数据劫持+发布者-订阅者模式
- 通过Object.defineProperty()进行数据劫持(包含getter和setter)
- Observer 给属性加了个监听器,属性值变化的时候,监听器会监听到,从而触发数据劫持中的setter,发出通知
- 订阅器Dep接收到通知后,通知Watcher属性发生变化,之后Watcher触发视图更新函数
三十四、为什么 v-for + key
三十五、常用的git命令
- git add .
- git commit -m ''
- git remote add git@harrylee13/cloud-office
- git push - u origin master
- git pull
- git log
三十六、开发中,同事把你写的代码扒下来然后弄出错了,你怎么解决?
- 进行版本回退
三十七、你还有什么问题?
- 公司项目?
- 技术栈?