面经

一面

自我介绍
由自我介绍延伸到实习中遇到的困难,怎么解决的
css盒模型,标准盒模型
写一个无限旋转的css动画
js基本类型,判断类型的方法引申到instance of,引申到原型链,写一个instance_of方法实现instance of

function instance_of(L, R) {
	if (L.prototype !== Object.prototype) {  // Object.prototype写法可能是错的,只是表达这个意思
		if (L.__proto__ === R.prototype) {
			return true
		}
		return instance_of(L.__proto__, R)
	}
	return false
}

根据js浏览器事件循环机制判断下列代码输出

console.log('script start')
let promise1 = new Promise(function (resolve) {
	console.log('promise1')
	resolve();
	console.log('promise1 end')
}).then(function () {
	console.log('promise2')
})
setTimeout(function () {
	console.log('setTimeout')
})
console.log('script end')

promise1.then().then()

判断代码输出,并写_bind方法来实现bind(答错了,并且_bind方法因为考虑的太多实现的有问题,后经指正实现)

function fn() {
	console.log(this.x)
}
const a = {x: 1}
const b = {x: 2}
var test = fn.bind(a).bind(b)
test()
// 正确输出  1
Function.prototype._bind = function (ctx) {
	return () => this.call(ctx)   // 当时想太多,考虑原型,this.arguments等等实现的不太准确,后经面试官指点,因为是使用的时候才绑定this,这些无需考虑
}

链表反转

节点构造函数
function ListNode(val) {
	this.val = al
	this.next = null
}
输入:1->2->3->4->5->null
输出:5->4->3->2->1->null
function reverseList(head) {
	const list = []
	const getNode = node => {
		list.push(node)
		if (node.next) {
			getNode(node.next)
		}
	}
	getNode(head)
	return list.map((item, index) => ({
		...item,
		next: list[index - 1]
	}))[list.length - 1]
}

讲解nginx配置中的upstream
讲解webpack的一些知识点 tree shaking loader和plugin的执行时机和先后顺序
讲解react hook的一些知识
浏览器渲染流程
回流与重绘, 分别有哪些行为导致

二面(面的时间最长,记得的问题最少)

自我介绍
引申到项目难点,最后的解决方案
写输出(人菜,过于烧脑,只答对了百分之60)

function Foo() {
	getName = function () {
		console.log(1)
	}
	console.log('this is ' + this)
	return this
}
Foo.getName = function () {
	console.log(2)
}
Foo.prototype.getName = function () {
	console.log(3)
}
var getName = function () {
	console.log(4)
}
function getName() {
	console.log(5)
}
Foo.getName()
getName()
Foo().getName()
getName()
new Foo.getName()
new Foo().getName()
new new Foo().getName()

域名反转问题

输入'www.toutiao.com'
输出'com.toutiao.www'
空间复杂度为o(1)
不允许使用字符串库函数

先上面试官期待的答案

function reverse(str) {
	const rever = (x, y) => {
		for (let k = x; k < y/2; k++) {
			let t = str[y - (k - x)]
			str[y - (k - x)] = stc[k]
			stc[k] = t
		}
	}
	rever(0, str.length - 1)
	let start = 0
	for(let i = 0; i < str.length; i++) {
		if (str[i] === '.') {
			rever(start, 1)
			start = i
		}
	}
	return str
}

自己思考的方案是采用递归的方式,但没有得到面试官的采纳

function reverse(str) {
	const index = 0
	const run = result => {
		if (!str[index]) return result
		const childHost = code => {
			if (code !== '.' && code) {
				return code + childHost(str[++index])
			}
		}
		run(childHost(str[index]) + '.' + result)
	}
	run(str[index])
}
// 大致思路是childHost递归正向添加字符串,拿到域名的每一段
// run递归反向加childHost得出的每一段

http缓存, 优先级
http状态码, 重定向请求头中哪个字段带有目标url(redict-url?大概这么写,记不太清)
移动端中布局问题
答:viewport方案, rem方案等
面试官补充百分比属性值等
追问:如何监听视口改变?
答:onresize
跨域,大致讲解了jsonp和cors
react的生命周期等,react优化方案和措施
剩下的记不得了。。。。。

三面

自我介绍
引申到项目难点,解决方案,这里提到了一个canvas处理生成图片的问题,对图像内容小于图片大小,有透明填充时通过计算像素值识别透明区域大小,并做裁剪,使得图像内容与容器完全贴合的案例,结果被问假设内容区域是不规则的,要怎么处理呢。。。。因为我实在是没有见过矩形以外形状的图片,因此我放弃了。。。。。。。。。。。

sass 、less的引入是为了解决什么问题呢
回答:当时的回答分别从变量以及嵌套语法带来的便利两方面来讲,但被打断,要求抽象出两个预处理语言的出现的意义???
试探性的回答:意义是解决了css存在的编写困难的缺陷
追问:那css的缺陷是什么呢?
回答:命名空间不足,容易出现覆盖和冲突,重构时工作量大且容易出错,选择器会存在很大的隐患
面试官:…

如何判断一个空对象?

答了两个,信心不足最后放弃。。。

obj.__proto__ === null.__proto__
// 此做法被质疑了
function isNull(obj) {
	for (let key in obj) {
		obj[key] && return true
	}
	return false
}
// 此做法被质疑了 + 1
// 马后炮做法
JSON.stringify(obj) === '{}'

接着被问 for in 和for of的区别
答:区别可能在于一个会遍历原型上的做法一个不会
追问:哪个会哪个不会
答:in不会,of会(错,正好相反)

http缓存
讲讲跨域?
答:常用的jsonp和cors并分别讲了讲
追问:说一下跨域的那几个响应头分别叫啥?
答:…记不清
追问:如何会触发跨域?
答:不同协议头,不同ip,不同端口
追问:不同ip?
答:嗯嗯
面试官: …

http请求方法?
讲了get,post等常用的,并引申了一下put,delete等不常用方法
追问:那讲讲options方法
答:预检请求,获取服务器配置
追问:具体讲讲?使用场景?
答:不太清楚。。
追问:…
答:可能是用来进行协商缓存?(正确答案是跨域预检请求,判断支持哪些请求方法)
面试官:…

讲讲http2.0?
答:emmm,不太了解

讲讲webpack的tree shaking还有webpack优化?

答:tree shaking不太了解,优化的话,分包,压缩等,extarnal(可能拼错了)这个可以把一些库不打包进去,使用时用网络请求加载
面试官:…

讲讲react中的key?
答:是循环渲染时使用的那个key吗?
面试官:啊?就是react组件的key啊
答:emmm我了解有限,目前只了解循环渲染的那个key,那个的话确保循环渲染时每个item的唯一性,有了这个唯一标识,可以避免一些不必要的渲染,进行复用。
追问:复用?
答: 就是当props没有发生改变时,就直接使用原来的,不用重新渲染
面试官:…,那我们进入下一题吧

写到算法题吧,合并a,b两个有序链表

答:

function reduce(a, b) {
	const getNode = (head, x, y) => {
		if (!x || !y) {
			head.next = x || y
			return
		}
		if (x.val < y.val) {
			head.next = x
			getNode(head.next, x.next, y)
		} else {
			head.next = y
			getNode(head.next, x, y.next)
		}
	}
	const minHead = a.val < b.val ? a : b
	getNode(minHead)
	return minHead
}
// 中途被打断过两次质疑我在写啥。。。

结束,三面挂掉

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值