大家好,我是若川。最近组织了源码共读活动《1个月,200+人,一起读了4周源码》,已经有超50+人提交了笔记,群里已经有超1200人,感兴趣的可以点此链接扫码加我微信 ruochuan12
本文经作者@lxcan 授权转载,未经授权请勿直接转载。
原文标题:《三年经验前端社招——Shopee》
原文链接:https://zhuanlan.zhihu.com/p/405752877
文末点击阅读原文
直达
前言
本人毕业学校是双非二本,非计算机科班出身,大学时自学的前端相关技能。截止2021年8月,有3年前端开发经验,技术栈为 vue 全家桶,求职意向城市是深圳。想着找一个更大的平台寻求发展(技术沉淀、涨薪),所以出来接受社会的毒打了。。。
本文的目的是记录自己的面试经历,各位路过的兄dei也可以参考一下,也让自己有个回顾和反思。路漫漫其修远兮,吾将上下而求索
下面的题目,都会标明每一题的性质,部分题目也会给出一些参考思路和参考回答,希望各位大佬不吝赐教~
描述:对概念、过程的描述,纯理论性问答题为主
举例:说出应用场景,或者是自己团队实践的情况
伪代码:写代码,但不需要跑起来,甚至可以随便写伪代码,主要目的是描述思路
编程:真正的写代码,需要跑起来,有测试用例,要看到效果
HR面的话,是一些日常、项目回顾(少说技术细节)、职业规划、你的优势和缺点、为什么跑路、为什么选择这边、目前薪资和职级、期望薪资,HR面基本离不开这些问题。
一面
1、编程题,改造 Person 使其在非new调用时抛出错误【编程】
function Person(name) {this.name = name
}
Person("Hello")
new Person("Hello")
参考答案:
function Person(name) {if (!(this instanceof Person)) {throw Error('error msg')}this.name = name
}
2、实现 instanceof 方法【编程】
参考答案:
function myIntanceOf (left, right) {left = left.__proto__var prototype = right.prototypewhile (true) {if (left ==null ) return falseif (left === prototype) return trueleft = left.__proto__}
}
function Foo () {}
var f = new Foo()
console.log(myInstanceof(f, Foo)); // true
console.log(myInstanceof(f, Object)); // true
console.log(myInstanceof([1,2], Array)); // true
console.log(myInstanceof({ a: 1 }, Array)); // false
3、结合第1题,Person 是什么类型的对象?是否有 __proto__ 属性?【描述】
Person 是函数对象,有 __proto__ 属性,Person 的隐式原型等于它的构造函数的显式原型Person.__proto__ === Function.prototype
4、说下 prototype 和 __proto__ 的区别【描述】
5条原型规则:
所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了"null")以外
所有的引用类型(数组、对象、函数),都有一个__proto__ (隐式原型)属性,属性值是一个普通的对象
所有的函数,都有一个 prototype (显式原型)属性,属性值也是一个普通的对象
所有的引用类型(数组、对象、函数),__proto__ 属性值指向它的构造函数的 prototype 属性值
当试图得到一个对象(引用类型)的某个属性时,如果这个对象本身没有这个属性,那么会去它的 __proto__(即它的构造函数的 prototype)中寻找
5、实现 Student 方法,Student 继承 Person ,也有自己的属性和方法【编程】
参考答案:
function Student(grade, name) {Person.call(this)this.grade = gradethis.name = name
}
Student.prototype = Object.create(Person.prototype)
Student.prototype.Constructor = Student
Student.prototype.getGrade = function () {return this.grade
}
6、完成一个 sum 函数,实现如下功能【编程】
/*
* 编写函数sum
* sum(1)(2).count() // 3
* sum(1)(2)(3).count() // 6
*/
参考答案:
function sum () {let args = [...arguments]let add = function () {args.push(...arguments)return add}add.count = function () {return args.reduce((acc, cur) => acc + cur)}return add
}
console.log(sum(1)(2).count()); // 3
console.log(sum(1)(2)(3).count()); // 6
其他版本,调用方式形如:sum(1)(2)() // 3
function curry (fn) {let args = []return function f (...newArgs) {if (newArgs.length) {args = [...args, ...newArgs]return f} else {let res = fn(...args)args = []return res}}
}
function count (...args) {return args.reduce((a,c) => a+c)
}
let sum = curry(count)
sum(1)(2)() // 3
sum(1)(2)(3)() // 6
7、完成如下 findPath 函数,输入一个对象和对象上的一个节点或子节点的值(值唯一,值类型为字符串),输出该值对应在该对象的key的路径【编程】
const obj = {a: {a_1: {a_1_1: 'abc',a_1_2: 'efg'}},b: {b_1: 'xyz',b_2: '111'},c: '000'
}
const result = findPath(obj, 'xyz') // ['b', 'b_1']
参考答案:
function flatObj (obj, key = '', res = {}) {for (let [k, v] of Object.entries(obj)) {if (Object.prototype.toString.call(v) === '[object Object]') {let temp = key + k + '.'flatObj(v, temp, res)} else {let temp = key + kres[temp] = v}}return res
}function findPath(obj, value) {let o = flatObj(obj)// k == 'a.a_1.a_1_1'for (let [k, v] in Object.entries(o)) {if (v === value) {return k.split('.')}}return []
}
最后
Shopee 深圳虾皮信息科技有限公司,是东南亚领航电商平台。听说公司里面都是腾讯、阿里、字节的大佬居多,技术前沿,福利好,各方面都不错。一面是视频面试,是在虾皮自有的平台上视频面+写编程题,自我感觉基本都写出来了,可能不是最优解吧,没跑测试用例,一面之后没后续了,不管怎样,菜是原罪,继续加油吧~
往期回顾:
三年经验前端社招——朴朴科技
三年经验前端社招——腾讯微保
三年经验前端社招——丰巢科技
三年经验前端社招——众安保险
三年经验前端社招——有赞
三年经验前端社招——慧择网
天生我材必有用,千金散尽还复来
最近组建了一个湖南人的前端交流群,如果你是湖南人可以加我微信 ruochuan12 私信 湖南 拉你进群。
推荐阅读
1个月,200+人,一起读了4周源码
我读源码的经历
老姚浅谈:怎么学JavaScript?
我在阿里招前端,该怎么帮你(可进面试群)
················· 若川简介 ·················
你好,我是若川,毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列
从2014年起,每年都会写一篇年度总结,已经写了7篇,点击查看年度总结。
同时,最近组织了源码共读活动
识别上方二维码加我微信、拉你进源码共读群
今日话题
略。欢迎分享、收藏、点赞、在看我的公众号文章~