面试+题+技巧
简历介绍
简单介绍的自己的经历????
当然不是了,简历要体现你会什么,能做什么,做过什么,能不能够承担公司分配的任务。
1简历名称-工作年限-web前端工程师-名字(性别)
2简历内容
●个人信息
胡XX
性别:男电话:147-XXX-8987籍贯:湖北黄冈
●最好加上毕业院校-万一有校友呢。
●年龄:21-25- 推断工作年限
3求职意向
求职意向
北京
意向岗位:前端开发工程师意向城市:
期望薪资:12-15K求职类型:全职
北京 上海 深圳 杭州 南京 广州 成都
目前缩减HeadCount, 人员流动率慢了
期望薪资:面议
4. 个人技能
4.
4. 工作经历
明确工作时间-公司名称
黑马头条-移动H5的
-
vant组件库
3-4个项目比较好
- 两个后台管理一个移动端。
简历-是一个人的脸面,唯一了解你的方式。
提前准备
哪个项目让你最满意、代表你的最高水平?如何做的?
- 让你印象最深刻的一个(技术)难点,害的你搞了很久,最后怎么解决的,有什么心得?
- 你做的时间最久的一个项目(或产品),你看到这个项目有哪些问题,你能做什么?
- 你能给我们团队或者产品带来什么?
问面试官
** 贵公司主营业务是什么,目前正在做什么项目
- 目前技术团队有几人(8 ),分工是什么样的,后台是什么语言(如果有前端开发,可以问一下目前前端使用的是什么技
术栈)
-
如果我到贵公司,那么主要负责哪一块内容
-
贵公司晋升机制是什么样的?
-
是否双休?是否有五险一金?
**
1.就业加强课内容介绍
- 面试 + 就业
- 一天讲面试-准备-面试内容-面试回答-面试技巧-谈薪资
- 一天讲就业-工作准备-上班内容-攻克难题-挺过试用期
2.什么是面试-interview
去一个公司推销自己,说服对方,让对方雇佣自己,一个双方都满意的价钱。
-
稳定-说话靠谱,“实事求是”,一定要说话。多受几次打击。
-
踏实- 给人一种老实人的印象
-
自信-技术自信-Vuex
-
坦然-加班干不干?
-
麻木-当你什么都不在乎的时候,工作就来了。
-
准备简历- 简历要过关-有人搭理你才是过关。
- 投递简历-有公司的邀约- 如果没有公司邀约,简历不过关
- 约定面试时间-赴约- 线上-线下- 线上线下有区别-线上更看重准备,线下更看重发挥
- 线下-到公司-前台登记-写下访问者联系方式(这一步可以忽略不计)
- 线下-到公司-行政人员-领导面试会议室-单独的房间
- 线下- 到房间之后 1. 等一下,把简历交上去,叫面试官 2. 等一下,拿一份面试题你做一下
- 等面试官过程-忐忑-兴奋-激动-焦虑- 面试官进屋- 面试官从 工位-会议室 了解你简历所有的时间-了解不超过一分钟
- 进到会议室-面试官坐定-开始面试
- 面试官看着你的简历-低着头-思索几秒钟,说:好咱们开始面试
- 第一个问题: 请先做一下自我介绍
- 面试者:巴拉巴拉-重点介绍自己的什么内容
自我介绍: 我叫xxx, 今年多少岁,来自哪个城市,毕业于哪个大学哪个专业(不是本专业也可以说,现在转行的人不计其数,根本没有必要担心), 从事前端开发多长时间- (有过工作经验-最好弄,年龄说的过去, 年龄小,将实习经历当过工作经验), 目前主要的技术栈是 vue/react/小程序, 最常用的 最常做的可能就是
vue-element-admin为底层的后台管理项目的开发,当然, React类组件和hooks目前也在开发一些小项目,比如最近做了一个内容管理系统,采用的是 ReactHooks+RTK+antd的技术栈,另外,jquery一些传统型的项目也开过一些项目,但是目前传统项目越来越少,那些传统项目只是维护,没有什么新需求了, 大概也就这些。
-
面试者说完上述自我介绍之后,面试官有一个起码的印象分-可高可低
-
面试官开始做面试
-
基础面试 + 项目面试
3. 基础面试+ 项目面试
正常前端面试中-确定这个人ok的前提是基础过关- 1. 深厚的基础 2. 差不多的基础
- 深厚的基础面试-问的都是计算机的底层+ 操作系统+ 前端浏览器-网络-js-框架的底层的内容
多见于大厂-狂刷面试题八股文-要求学历-985 211
- 差不多面试-前端的一些基本概念,闭包-跨域-代理- MVVM, 路由-鉴权-ES6-组件传值-状态共享
需要人干活,找一些基础OK的人来做-中小公司-大厂外包
- 差的多面试- 这种情况也有- 公司刚创建-没人去的公司-团队就一两个人,不好招人,给offer都不想去的这种
有可能面试都不问啥,因为他也不会,他就想找一个人,赶紧把摊子支起来。不属于骗子公司,但属于一个人要做很久。
项目面试 + 场景面试
至关重要的一环,直接决定offer的产出
任何公司招聘的都是干活的人,要人来接手项目,通过你对项目的描述来判定你能否接手公司当下的任务。
细节决定成败,项目描述的越清楚,越细节,越具体,越自信拿到offer的概率越高。
比如,会问你,vue中的你的状态是如何共享的
面试回答: Vuex - 0分
满分面试者回答: 首先明确状态是不是需要多组件使用,因为并不是所有的状态都需要共享。如果需要多组件共享,会看组件之间是不是完成没有层级关系,因为Provide 和 eject也可以实现组件共享,可以使用Vuex解决,
使用Vuex又分几种,比如类似token这种,它需要做持久化-又涉及到Vuex的持久化应用。 一些常用状态,可能还会涉及分模块处理,比如用户的信息,比如权限的信息,比如应用的信息,对应的action就需要提供的响应的API.
至于他们的之间的关系,state, mutation, actions, getters, modules的关系,我是非常清楚的,如果你需要,我发给你详细解释一下。 满分回答
比如,面试官问:你的动态路由是如何实现的
面试者回答: RBAC-基于角色的权限控制- 权限分配给角色,用户分配角色, 用户自动拥有角色所拥有的权限。但是,光有权限还不行,前端页面需要routes 来进行路由导航, 需要在路由切换时,获取用户的权限信息,
将用户的权限点转化成对应的路由-通过addRoutes动态加载到 页面中。... 细节。
面试官最终确定的就一点,你做没做过这个项目,这个项目的点满不满足我的要求。
4. 场景面试
场景面试-面试官抛出一种开发场景,问你该怎么做
忌讳:切记说不会,没有想法,即使说错了,也没关系,能想到什么就说什么
考察面试者的即时反应能力和思考的能动性,几分钟思考一个完美的解决方案是不可能的,要结合自己的开发历史,从开发历史中找对应的场景,直接说自己的想法-按照自己的经验。
场景题一般都是面试官他遇到的一些难题,他费了半天劲解决了,想听的你的方案,看看你的水平高还是低
比如封装一个组件,组件的封装原则是什么
了解需求- 组件完成的功能-有哪些可以复用的一些参数,参数-props传值-插槽传模板内容,props传回调函数暴露对应的方法
开发组件- 有可能需要第三方插件来实现,
百分之九十的功能都有第三方实现
比如现在有一个接口是收费,两个小时有效期,怎么保证既能完成任务,又省钱
想法是 这个接口不能频繁调用,只要在两个小时之内,就将数据缓存起来,记录一个时间戳,等获取的数据的时候判断一下时间戳,超过两个小时再次调用接口-并没有真正的技术实现。
面试官最忌讳,你不会,还特别有理。
把自己会的全盘拖出,怎么想怎么说。
5.谈薪水和入职
面试过程中-建议全程录音
如果通过了以上的面试-通过-不通过
面试官会问: 你还有什么问题要问我吗?
第一种情况,面试凉了,给一些台阶,满足一下求知欲- 占比60-70%
给大家建议:把刚刚面试中没回答上的问题反问一遍- 比如场景题
- 扳回信心
- 查缺补漏
- 问一下您觉得我还差在哪里-面试官会实事求是的告诉你-比如哪个题没有答上让我很失望
第二种情况:面试通过了,可能要立刻给offer了
给大家建议: 问 公司对于我们这种开发的职业规划是什么?公司的发展前景如何?
1.并不是给offer就立刻上班,建议一周的准备的时间 7-10 天的入职准备期(可以接着面试-接着拿offer)
不用担心有offer不去,会不会有诚信问题? 不会!!! 爽约的多了去了
谈薪水
一个公司里面-前端工程师的岗位的薪资-不是固定的,只会有一个范围,不超过这个范围即可。
目前北京初中级工程师的薪资范围 8- 16k之间
6-12k
给大家的建议薪资 10-14k之间
(hr)面试官问:你的期望薪资是多少钱
-
如果是hr, 直接要上限 14k
-
如果是面试官,如果你觉得面试官对你很满意,可以要上限,否则适当的调整一下
比如你的期望薪资是12k, 一定要说期望是14,多的属于谈论的空间, 如果是10k,那就是12k
如果说;面试官说你的水平不值这个钱,我们给不到,只能给到10k
面试者:忍了?还是拒绝!
拒绝: 这个差距有点超过我的心里接受的区间了,只能不好意思了,不适用所有人
接受:上一家的工资至少是11.5,我可能接受不了还比上一家低,如果比上一家高一点,我差不多能接受。
原则:面试是双向选择-不是随意的被别人压榨
js中的new做了什么事
问法: js中new做了什么事
: 如果使用一个方法来实例化一个对象
:如何实现面向对象
实例化对象- 构造函数
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.run = function () {
console.log(this.name, "在奔跑")
}
new Person("张三", 18) // new做了什么事
function createPerson(name, age) {
// 1. 得到一个新对象
const o = {}
// 2. 改变构造函数的this => 新对象
// Person.call(o, name, age)
Person.apply(o, [...arguments])
// call 和 apply的区别
// 3. 继承构造函数的原型属性给新对象的隐士原型
o.__proto__ = Person.prototype
// 4. 返回这个对象
return o
}
性能优化
- 代码压缩 gzip压缩 加载速度提升
- 代码-按需加载-首屏加载
spa首屏会慢的原因- 所有的组件和资源都打成了一个js文件
- 100 个路由组件 打包到一起 1.2M
- 单个的10k-100k之间
只有切换页面的时候,才会加载,只会加载一次,不会重复加载。
- CDN加速
一个项目中有很多的包,Vue-element-xlsx-插件
使用CDN的方式加载一些第三方的插件,提升第三方插件的加载速度
- 合并请求
一个图片就是一次请求,
CSS Sprites 图片精灵
多见于-性能优化
客户端渲染-服务端渲染
CSR- Client Render -SSR Server Render
- 客户端渲染- 只有一个元素div, 会请求一堆js文件
等到js加载完了,js开始执行-动态渲染- 属于在客户端完成渲染
- 服务端渲染- 请求回来的页面直接是已经写好的dom元素, -属于在服务端完成渲染
肯定是服务端渲染会更快。
将 很多图片聚合到一张上,将多次的图片请求集合于一点,省了很多的带宽,具体需要对图片进行定位
background-position 定位 具体的图片位置
7.服务端渲染框架 Nuxt.js
- 创建一个nuxt项目
$ yarn create nuxt-app <项目名>
json-server
可以立刻把json文件变成 增删改查的接口
$ npx json-server --watch ./db.json --port 9999
6. link和 import的区别
link属于html标签,html渲染时,遇到link标签就会加载,匹配样式
import属于css中的关键字 ,会等到css文件加载完成,才回去加载对应的css文件
7. 解释一下js中的变量提升
console.log(a) // 直接报错a 没有定义
console.log(a) // undefined
var a = "张三"
js引擎在运行代码之前,将所有的声明的变量提升到最顶层, 所以上面的代码由于变量提升的存在就变成了
var a = undefined
console.log(a)
a = "张三"
执行代码之前,会将整个作用域中的所有变量和函数声明先处理完毕-提升到最前方-编译过程
// console.log(a)
test() // 正确打印
test1() // 报错
// var a = "a"
// 函数声明
function test() {
console.log("hello 老高")
}
// 声明变量 = 匿名函数
var test1 = () => {
console.log("hello 老高a")
}
8. null和 undeifned的区别
null: 空类型,代表一个空值,空对象的指针, 你可以特殊的对象值
undefined: undefined类型,声明变量没有初始化值的时候,就是undefined
undefind是一个空的变量- 访问一个未初始化变量时返回的值
null是空的对象- 访问一个尚未存在的对象时所返回的值
typeof null // object 特殊的对象 对象为空
typeof undefined // undefind 变量尚未初始化
let a = null // a给了一个空对象
let b // b没有做初始化,它属于undefined
经常把函数的引用设置为null,释放内存空间
new Person()
delete
9. 值类型,引用类型的区别
值类型- 字符串- 数字- 布尔值- null- undefined-Symbol
var a = 1
a = 2 // 设置或者读取 都改的a的本身。存于栈中
- 值类型存于 栈中,设置和获取的是值的本身
- 可以通过typeof获取值的类型
引用类型 对象 Object 数组 Array, 函数 Function
- 引用类型存于堆
- 设置和读取的是指向对象的一个指针- 并没有直接复制值
var obj = {
name: "张三",
}
var obj2 = obj // 声明obj2变量2 - 和obj指向了同一个地址
// var obj2 = { ...obj } 浅拷贝
obj2.name = "李四"
console.log(obj.name)
如何解决引用关系?
- 浅拷贝
复制数据-只复制最外一层数据-不论你的内层数据是什么类型-值类型-引用类型
var obj = {
a: 1,
b: 2,
c: {
d: 3,
e: {
f: 5
}
}
}
var obj2 = { ...obj } // obj2 中的 a和b 和原来的a 和 b没有关系
// 第二层- 如果是引用类型 依然会有引用关系 obj2 中的c 和 obj中的公用的是一个地址
- 深拷贝
不论有多少层,100 层也好,10000层也罢,直到找到所有的值类型为止,值类型是拷贝值, 找到没有引用类型为止- 深拷贝-
- 最暴力的方式
JSON.parse(JSON.stringify(obj)) // 暴力深拷贝
- 自己写递归
- 使用lodash-现成的深拷贝的方法
10.什么是闭包
- 考察对于闭包的基本概念
- 对于闭包的应用
js中的基础概念都可以去查MDN官方解释
闭包-可以在内层函数访问外层函数的作用域
闭包的应用
闭包最大的作用-变量私有化
- 闭包的变量只能通过函数内部访问,外部无法访问,变量私有!
闭包也会带来问题-闭包的gc没有执行清理,内存一直拥有这个变量
- 当已经不需要使用闭包的变量的时候,要将函数的引用清除掉
function init() {
let count = 0
return () => {
return ++count
}
}
let callback = init()
// 正常的垃圾回收 gc garbage collection count应该被销毁
// 如果使用了闭包 变量不会被销毁,因为还有用
console.log(callback())
console.log(callback())
console.log(callback())
callback = null // 清除原来的引用 清除函数的引用也就意味着清除了闭包的变量引用
11. Vue中computed和 watch的区别是什么
- 计算属性 computed
- watch 监听变量变化
写法的不同
export default {
watch: {
"data/props名称": (newValue, oldValue) => {
// 做任何的操作
// this指向当前的vue实例
// 异步操作
// 没有返回值
},
// 监听层级较深
"a.b.c.d": () => {},
"obj": {
handler() {
// obj里面发生任何变化 都会触发这个函数
},
immediate: true, // 开启之后 立刻执行
deep: true // 表示深度监听
}
},
computed: {
// 纯getter形式的
// 自定义名称
customName () {
// 必须实现返回值
return this.name
}
}
}
watch可以做异步操作, 没有返回值,监听值的变化
计算属性必须有返回值- 不能做异步操作
计算属性有智能更新功能- 依赖data或者props数据- 第一次计算会将计算结果存入缓存,如果依赖的数据不再发生任何变化, 那么计算属性永远不会再执行
计算属性还有第二种写法
export default {
computed: {
name: {
get() {
// 原来的怎么return 现在还这么return
return this.name
}
set(value) {
// 将value值 设置给 其他的属性
this.name = value
}
}
}
}
计算属性也可以使用v-model来进行绑定
12. Vue中常见的传值方式有哪些
- 父传子- props
- 子传父-$emit
- vuex
- ref-通过获取实例
- provide和inject
- eventbus-事件总线-类似发布订阅
- props的回调函数- 父组件子组件传一个函数- 子组件调用该函数传值-类似于React
- children- children是一个数组
13.父组件的钩子函数-子组件钩子函数的执行顺序
<parent>
<child></child>
<parent>
- parent的 beforeCreate ->parent的 created -> parent的beforeMount -> 开始渲染子组件 -> child的beforeCreate- child的creatd-> child的beforeMount -> child的mounted -> parent的mounted
class Component {
state = {
}
render () {
this.state
}
}
new Component()
14.面向对象的解释
class Student {
constructor(name, age) {
this.name = name
this.age = age
}
name = ""
age = 20
fightUser = null // 打架对象
fight (user) {
this.fightUser = user
}
}
const s1 = new Student("王光涛",20)
const s2 = new Student("孙本珍",14)
s1.fight(s2)
// s1
s1.fightUser
- OOP
万物皆对象,一切的东西都可以作为对象来解释。
老高在给黑马的学生上课
- 老高是一个对象-上课是老高这个对象的一个方法
- 黑马也是一个对象
- 学生也是一个对象-学生的依赖关系中有黑马的引用
class Person {
// 人的对象
}
class Teacher extends Person {
// 老师的类
teach () {
}
}
class Student extends Person {
}
class School {
name = ""
students = [] // 学校的学生
teachers = [] // 学校的老师
}
const laogao = new Teacher("老高") // 实例对象
const chaipeng = new Teacher("柴鹏") // 实例对象
const stu = new Student("学生")
const Heima = new School("黑马")
Heima.students.push(stu)
Heima.teachers.push(laogao)
laogao.teach() // 上课
对象里面 属性和方法-对象之间会有联系和依赖关系
面向对象的三大特性- 封装-继承-多态
Vue2-React类组件 完成应用了面向对象的编程思想
用到this-指的是当前运行环境的上下文对象- 一定用到了面向对象的思想
篮球场上看别人打球
- 篮球场是一个对象
- 打球的人是一个对象
- 球是一个对象
- 篮筐是一个对象
- 投篮- 人对象里的方法
- 犯规- 人对象的方法
- 长得丑- 人对象的一个属性
- 球脏了- 球对象的一个属性
15. 跨域的解决方案
- cors
需要浏览器支持-需要后端支持-后端在响应头中- headers- access-control-allow-origin
access-control-allow-origin: *
-
- 表示所有人都可以访问
星号仅限于测试中,真正的项目不会这样做,
- 还可以限定- 访问前端的域名
refer是当前客户端-浏览器的访问地址-refer地址满足 后端响应回来的域名才可以访问
比如:
access-control-allow-origin: http://localhost:8888
以上的意味就是说:只有http://localhost:8888才可以访问接口,其他的均被同源策略挡回来
反向代理-同源策略只是浏览器的一种安全策略-通过服务来搞
localhost:8888 => localhost:8888/api/xxx => 跨域的地址发送请求 => 等到的结果 => 前端
开发环境代理- proxy代理-vue-react项目开发环境-一旦打包-打出来的是 html/css/js
生产环境代理- 还需要配置生产环境代理- ngix- 修改ngix配置文件-一般运维做
jsonp- 利用了 同源策略对script标签的没有影响的一个效果
手写jsonp的代码
function jsonp(url) {
return new Promise(function (resolve, reject) {
try {
const script = document.createElement("script")
const callBackName = "func" + Date.now()
script.src = url + "?callback=" + callBackName
window[callBackName] = function (data) {
resolve(data)
document.body.removeChild(script) // 删除页面中的标签
delete window[callBackName] // 销毁方法
}
document.body.append(script)
} catch (error) {
reject(error)
}
})
}
- 跨域的传值方式-iframe-使用w3c新增的api的 postMessage来进行通信