俺这只小菜鸡🐔终于也快迎来曙光了!😀
俺现在是一名大三学生,渴望能获得一份大厂的实习机会呜呜呜,所以不自量力的投了一下阿里跟腾讯。阿里是提前批就开始面了的。很多部门都面了一下下,面了啥也忘了哈哈哈哈。也多亏了提前批,让俺知道哪些地方还需要再补补。
阿里这边最终选择了盒马,盒马的面试官都好好,好和蔼,给了好多建议,没有因为我菜就嫌弃我呜呜呜,太感动了。而且!看到这张“屁股脸”难道不想加入换一套限量公仔/手办吗!
初面是聊得最久的一次了,一个多小时了吧,不过初面的面试官真的很让人感动一直在鼓励我,“好啊好啊”,“没关系没关系”,啊太棒了,给俺这个小菜鸡很多信心hhhh
一面俺就放放笔试题还有俺自己做的情况吧哈哈哈哈,一面的面试官跟俺说拓扑排序,俺才知道原来还有这种东西(流泪...
ProjectA - a@0.1.0 - d@0.2.0 - c@0.1.0 - b@0.1.1 - e@0.1.2 - c@0.1.2 - c@0.2.0 复制代码
则其中一种输出的依赖优先级排序为:
['d@0.2.0', 'c@0.2.0', 'a@0.1.0', 'e@0.1.2', 'b@0.1.1']
输出分析: 为了让 a 加载后可以争取执行,则必须先加载 d 和 c,b 的加载同理,又因为在整个依赖关系下,c 的最新版本为 0.2.0 于是有了如上的输出结果。
const cycle1 = function (node) { let set = new Set() while (node) { if (set.has(node)) return true else set.add(node) node = node.next } return false }; const cycle2 = function (node) { let start = node let end = node.next while (start !== end) { // 没有环就null if (end === null || end.next === null) return false start = start.next end = end.next.next } return true } 复制代码
这题有大佬在评论区指出错误啦!之前那个版本是比较字符串,但是忽略了多位数字版本的情况,例如
b@0.2.22
与b@0.2.3
,结果应该是前者,但之前版本是输出后者,现在修改了一下!好嘞!
function update(npmList) { let versions = {} let res = [] // 比较版本号 function cmp(a, b) { const versionListA = getVersion(a).split('.') const versionListB = getVersion(b).split('.') for (let index = 0; index < 3; index++) { const versionA = parseInt(versionListA[index]) const versionB = parseInt(versionListB[index]) if (versionA > versionB) return a else if (versionA === versionB) continue else return b } return a } // 获得版本号 function getVersion(str) { return str.substr(str.indexOf('@') + 1) } function dfs(npmList) { if (npmList.length === 0) return npmList.forEach((npm) => { const { name, deps = [] } = npm // 先遍历他们的依赖 dfs(deps) let key = name.substr(0, name.indexOf('@')) // 如果依赖不存在则添加,若已存在,则取最新版 if (!versions[key]) { versions[key] = name } else { versions[key] = cmp(versions[key], name) } // 添加进最后的加载列表 res.push(key) }) return } dfs(npmList) // 去除重复项,然后将包名转换为依赖名,eg: a -> a@0.1.0 return [...new Set(res)].map(key => versions[key]) } 复制代码
// 第三题React部分第三题React部分第三题React部分第三题React部分第三题React部分 import React, { Component } from 'react'; import './input.css' function debounce(fn, delay = 500) { let timeout = null return function (e, ...args) { e.persist && e.persist() timeout && clearTimeout(timeout) timeout = setTimeout(() => { fn.call(this, e, ...args) }, delay) } } class Tips extends Component { render() { const { tipsList } = this.props return tipsList && tipsList.length !== 0 ? ( <div className="tips__container"> {tipsList.map((item, index) => { return ( <a href="#" key={index} className="link">{item}</a> ) })} </div> ) : <div></div> } } export default class Input extends Component { constructor(props) { super(props); this.state = { keyWords: [ '前端工程师1', '前端高级开发1', '后端工程师1', '测试开发1', '项目主管1', 'dress', 'Recent', '123456', 'awdad1' ], inputValue: '', inputType: 'text', inputMaxLen: 20, wordsList: [] } this.handleInput = debounce(this.handleInput, 200) this.handleMaxLenChange = debounce(this.handleMaxLenChange, 400) } handleInput = (e) => { const { target: { value } } = e const { keyWords } = this.state const tipsList = !value ? [] : keyWords.filter(item => { const res = item.search(new RegExp(value, 'i')) return res !== -1 }) this.setState({ inputValue: value, tipsList }) } handleTypeClick = (e) => { const { target: { name } } = e this.setState({ inputType: name }) } handleMaxLenChange = (e) => { const { target: { value } } = e const { inputValue } = this.state const newInputValue = inputValue.substr(0, +value) // 如果设置最大长度小于现在关键词的长度,则截取一下 this.input.value = newInputValue this.setState({ inputMaxLen: value, inputValue: newInputValue }) } render() { const { tipsList, inputType, inputMaxLen } = this.state return ( <div className="container"> <div className="control__container" onClick={this.handleTypeClick}> <button name="text">文本</button> <button name="number">数字</button> <span>最大长度: </span> <input type="number" placeholder="默认: 20" onInput={this.handleMaxLenChange} /> </div> <div className="input__container"> <div className="input__wrap"> <input ref={input => this.input = input} placeholder="请输入关键词" type={inputType} maxLength={inputMaxLen} onInput={this.handleInput} /> <button>搜索</button> </div> <Tips tipsList={tipsList} /> </div> </div> ) } } 复制代码
// 第三题CSS部分第三题CSS部分第三题CSS部分第三题CSS部分第三题CSS部分第三题CSS部分 .container { width: 600px; height: 400px; margin: 0 auto; padding: 30px; background: #fff; } .input__container { margin-top: 30px; } .input__wrap { display: flex; align-items: center; } .input__wrap input { box-sizing: border-box; width: 85%; height: 50px; padding: 0 10px; border: #666 1px solid; border-right: 0; outline: none; } .input__wrap button { cursor: pointer; box-sizing: border-box; width: 15%; height: 50px; color: #fff; font-size: 20px; border: none; border: #666 1px solid; outline: none; background: #1890ff; } .control__container { display: flex; align-items: center; } .control__container button { cursor: pointer; width: 50px; height: 30px; margin-right: 10px; color: #fff; outline: none; border: #333 1px solid; border-radius: 8px; background: #1890ff; } .control__container span { margin-left: auto; margin-right: 10px; color: #666; font-size: 14px; } .tips__container { overflow-y: scroll; max-height: 200px; border: #333 1px solid; border-top: 0; } .tips__container .link { display: block; height: 30px; padding: 5px 10px; color: #666; line-height: 30px; text-decoration: none; } .tips__container .link:hover { color: #fff; background: #666; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { display: none; } 复制代码
二面主要是结合项目来问的,抓住一个功能发散开来,例如我项目的聊天室的功能,吓得我好慌好慌hhh,不过面试官人很好一直引导我,特别是那些场景题,引导我去思考,啊,太感动了!!!
这一面也是结合项目来问的。啊,三面的面试官真的太好了,期初我的小项目没什么难点(我都以为凉透透了呜呜呜),然后面试官给了提了几个建议,让我多去深入思考思考,面试完之后去找他请教问题,也一直很有耐心给我指导指导,啊,太棒了吧🤭
四面应该是总监面,还是得感谢三面的面试官给我提的建议,之后做出来之后,发现这个东东可以作为项目的一个难点来吹哈哈哈!四面主要还是围绕项目来问,我个人觉得关注的更是自己的思维、对技术的认识、对自己未来的发展规划等宏观的内容
五面是交叉面,心惊胆跳呜呜呜,希望不要挂我...五面问的大多是基础方面的内容,不过也是结合项目来问的,这一面面试官主要关注的是
性能
方面的内容,例如数据埋点啊、页面加载时间、接口响应时间等一系列关于性能方面的问题,他希望的是数据量化的一个东东,具体的实现,达成了什么目标等
一面是笔试 + 面试,俺也放放题目跟俺的答案吧!
var x = [0, 1, 2, 3] reverse(x, 4) // x = [3, 2, 1, 0] var y = [1, 2, 3, 4, 1] reverse(y, 5) // y = [1, 4, 3, 2, 1] var tree1 = { value: 1, left: { value: 2 }, right: { value: 3 } } countLongest(tree1) // 2 var tree2 = { value: 1, left: { value: 2, left: { value: 3, left: { value: 6 } }, right: { value: 4 } }, right: { value: 5 } } countLongest(tree2) // 4 复制代码
样例
var tree1 = { name: 'main.js', require: [{ name: 'A.js' }, { name: 'B.js' }] } resolve(tree1) // ['A.js', 'B.js', 'main.js'] var tree2 = { name: 'page.js', require: [{ name: 'A.js', require: [{ name: 'B.js', require: [{ name: 'C.js' }] }] }, { name: 'D.js', require: [{ name: 'C.js' }, { name: 'E.js' }] }] } resolve(tree2) // ['C.js', 'E.js', 'D.js', 'B.js', 'A.js', 'page.js'] 复制代码
样例
var x = [1, 4, 5, 3] countMax(x) // 7 var y = [3, 12, 6, 2, 4] countMax(y) // 16 复制代码
function reverse(arr) { let len = arr.length for (let start = 0; start < Math.floor(len / 2); start++) { let end = len - start - 1; [arr[start], arr[end]] = [arr[end], arr[start]] } return arr } 复制代码
function countLongest(tree) { if (!tree) return 0 let res = 0 function dfs(node) { if (!node) return 0 const leftMax = dfs(node.left) const rightMax = dfs(node.right) res = Math.max(leftMax + rightMax, res) return Math.max(leftMax, rightMax) + 1 } dfs(tree) return res } console.log(countLongest({ value: 1, left: { value: 2 }, right: { value: 3 } })) console.log(countLongest({ value: 1, left: { value: 2, left: { value: 3, left: { value: 6 } }, right: { value: 4 } }, right: { value: 5 } })) 复制代码
function resolve(npmList) { const res = [] function dfs(npmList) { if (npmList.length === 0) return npmList.forEach((npm) => { const { name, require = [] } = npm dfs(require) !res.includes(name) && res.push(name) }) return } dfs(npmList) return res } console.log(resolve([{ name: 'page.js', require: [{ name: 'A.js', require: [{ name: 'B.js', require: [{ name: 'C.js' }] }] }, { name: 'D.js', require: [{ name: 'C.js' }, { name: 'E.js' }] }] }])) 复制代码
function countMax(arr) { const len = arr.length const dp = new Array(len).fill(0); dp[0] = arr[0] dp[1] = arr[1] dp[2] = arr[0] + arr[2] for (let i = 3; i < len; i++) { dp[i] = arr[i] + Math.max(dp[i - 2], dp[i - 3]) } return Math.max(dp[len - 1], dp[len - 2]) } console.log(countMax2([1, 4, 5, 3])) console.log(countMax2([3, 12, 6, 2, 4])) 复制代码
二面基本都是一些基础吧,但是就有些地方会深入去挖这样子
三面感觉还不够二面难,问的比较常见吧应该说,然后也是问问项目这样子
自己还是太菜了呜呜呜😭
希望HR面的时候放俺一条生路可好...
还是觉得面试不要慌,慌也没有用,不如让自己冷静一下,然后每次回答问题的时候想一下应该怎么表达会更清晰(我就是表达不行,面试官都理解不了俺在说啥hhhhh)。问的问题除了结合项目来发散,还喜欢出一些情景题,现场设计一个组件啊、一个缓存策略啊、一套权限控制啊之类的内容。到时候就随机应变,想一下再说出来就好啦!
最后还是祝愿大家春招早日结束战斗!!拿到心爱的offer!!