原来又到了校招季,一个前端新人的回忆

6,599 阅读13分钟

写在最前

昨天和一个童鞋聊到很晚,才意识到现在又是新的一轮校招季了,他像当时的我一样,自己出于喜欢学习了前端,但又不知自己处在了什么水平,也由于知识、眼界的限制不知道路在哪里(真的前端发展到现在知识面太广)而担惊受怕。在和他交谈的同时也回想起当时的自己,像我一个普通的本科生从接触到决定其作为自己未来很多很多年的职业,殊不知要经历些什么才能下定了决心一往无前。时间很快,离我上次参加面试也经过了一年多的时间,在工作里也在不停的对于以往只在面试中“背”过的知识有了些新的认识,同时那些面试题在我之后的工作中也让我受益匪浅,并且从中可能又多了些心得。故借此写一个分享,分享一些以前遇到的题目以及可能包括之后在工作中对其的一些新认识。希望可以帮助到有志在前端领域有所建树的童鞋们。#另有些分享欢迎关注我的github

html

1. 原生方法对于dom节点的一些操作

例如:增删改查dom节点属性

2. dom的事件机制

冒泡、捕获的原理;stopPropagation、preventDefault

比如这篇关于事件的基础知识的文章,红包书中的解释大家需要多多理解。

3. 关于事件委托 到底什么时候用委托

要知道委托是方便,但是什么时候必须要委托呢?是当你动态添加节点的时候,你之前为该节点所绑的事件是无法在之后的节点也进行绑定的。所以要通过委托来进行绑定。
一篇关于事件委托的文章

css

1. 多列,引发的具体需求下多列的合理实现

多列布局的几种方式就不赘述了,只是在这个问题后结合现实需求就可能会有了一些新的布局方式。下面来看这张图:

可能有些同学会说,可以给一个右边距然后将元素4,8的右边距去掉。这件事本身很容易但是我们要考虑到这个页面如果放到线上就可能会进行模板嵌套。在模板中这些元素都是诸如以下方式渲染出来的

for( i in 元素数组) {
    return <div class="xxx"> 元素数组[i] </div>
}

在这种情况下我们不太可能去一一控制第几个元素你把右边距给我去了对吧。所以也由这道面试题,引发了一个新的认识即margin负边距。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <style>
    body,ul,li{ padding:0; margin:0;}
    ul,li{ list-style:none;}
    .container{ height:210px; width:460px; border:5px solid #000;}
    ul{ height:210px; overflow:hidden; margin-right:-20px;}/*一个负的margin-right,相当于把ul的宽度增加了20px*/
    li{ height:100px; width:100px; background:#09F; float:left; margin-right:20px; margin-bottom:10px;}
</style>
</head>
<body>
<div class="container">
    <ul>
        <li>子元素1</li>
        <li>子元素2</li>
        <li>子元素3</li>
        <li>子元素4</li>
        <li>子元素5</li>
        <li>子元素6</li>
        <li>子元素7</li>
        <li>子元素8</li>
    </ul>
</div>
</body>
</html>

对于负边距可以看看这篇文章

2. 盒模型

盒模型有几种?MDN下对盒模型的讲解

3. flex-box

必会!自己好好写个demo,简直太好用。要不是有兼容性问题...不过一切都会变好的

阮一峰老师关于flex的讲解

4. 居中

万古不变的话题,但要关注的是需求中到底知不知道高度和宽度,实现起来有什么不一样的地方。

js

基础

这个基础部分推荐一本书《你不知道的JavaScript》,里面的叙述很详尽,其中关于this的用法我觉得总结的很到位。

算法

这个算法不是二叉树什么红黑树那种算法,那些和前端也确实没啥关系。前端层面最需要关注的其实就是对于后端返回的json进行解析的操作。从中获取到需要的数据。也就是对于对象和数组的操作居多。大概会有以下的一些算法:

深入原生API

随着es6、es7语法的不断变革,API的不断更新,我们有了越来越多的快捷操作手段,同时老版本的浏览器在不断退出市场,但是直到现在还没有完全退出。而如果想进一线公司,兼容性是个无法避免的问题。你不能说在ie6下就不能开百度吧?
不过像应届生真的直接问兼容性问题的几率应该没那么大,即便问了可能也是背的没有什么意义。毕竟我的电脑里都没有ie我怎么测?但是兼容性的考察可以以polyfill的方式来进行,这点也非常考验开发人员的功底。比如bind的实现;
对不起,推荐一下我写的对bind的重新学习Javascript之bind;在对bind自己实现的过程中,会涉及原型链继承等概念的运用,使用这种方式顺带着还问了你基础知识,何乐不为。
抛个砖引个玉:

冴羽老师的一些深入系列

  1. 拖拽

这个效果要关注的核心就是三个函数

touchStart、touchMove、touchEnd

如果有兴趣深入的同学可以试试看写一个拖拽排序,github上也有很多关于其的开源项目。MDN上关于touch事件的介绍

  1. 轮播

轮播可以说是最常见的基础实现了,轮播也分为很多种,移动端&PC端,滚动&淡入淡出,一屏&多屏,有限&无限循环,同时使用原生手法和使用框架如react下面的实现思路又不尽相同。在这里可以做一个小的总结,轮播图的核心思路可以定义为对于整个轮播图其横轴坐标的控制(假设轮播图横向滑动)。那么这个值就定义为left,对于原生手段开发而言我们需要关注轮播图当前的索引(即第几张图)和left之间的关系,通过各种判断来实现其left值的反复变化。相当于我们需要关注索引与left之间的关系,是一个强耦合的形式。如果采用react而言(因为作者只用react写过)索引是可以与left进行解耦的,通过使用state来绑定索引值的变化,然后left会自行根据state进行改变,从而使开发者只需要关注索引值,也就是轮播图的url数组中各个url其索引值的改变。#纸上得来终觉浅这部分届时作者会出一个分享来对比通过原生或框架来实现轮播图思路中的异同。

效果实现有太多种可能,这种demo无法做到各个都知道,但我们可以掌握分析问题的方式。个人认为判断一个程序员功底的方式之一是看其多久可以从一个需求中发现问题的本质然后庖丁九牛般一步步分析出思路。

ES6

先推荐阮一峰老师ES6入门系列

根据28原则,个人感觉可以先学习

let const
解构
() => {}
Promise
class
async
...etc

主要是是否自己在实践中使用了ES6?如果使用了ES6那么必定要对webpack&gulp有些了解,可以自己尝试着配置一份webpack,打包一下less|sass,ES6试试,在自己配置的时候一定收获匪浅

网络层

http协议

必须要了解的,也是在工作中和后端工程师交涉的时候不可避免的一个环节。那么其和https的关系是?可以来看看这篇文章https时代来了,你却还一无所知?

跨域!跨域!跨域!

很重要。至少jsonp给明白吧,还有其背后的原理。自己写一个jsonp?核心是通过script标签的src去请求跨域的服务器,传递其一个callback回调函数,后端在这个回调函数中塞入需要的数据。

GET POST

私密与不私密的关系,限制于不限制大小的关系。注意jsonp走的是GET请求,这一点你从network里是可以看到的。

最后推荐一篇不错的讲解从前端到后端的科普文
在淘宝上买件东西,背后发生了什么?

后端(node)

仁者见仁智者见智了。可以从express玩起,这方面我也不太擅长就闭嘴了。。

推荐朴灵大大的《Nodejs深入浅出》

另分享一篇有关域名的文章
浅谈域名发散与域名收敛

框架/项目

关于框架

大佬三只手 react vue angular以及必会的jq

先分享下作者自己使用其中两个框架写的小实践

关于jq

jq已经十年了,你有看过它的源码么,对不起我也没有...以后我会看的。对于jq个人感觉如果你把它写到了简历里,如果面试官想问你那么问的一定会深入一些。因为那些大佬用的最熟的可能就是jq。在这里抛砖引玉一些可能忽略掉的地方。诸如:jq上的事件委托、bind&on各种绑定事件的区别、jq对象与原生对象间的关联转换等等

关于现代框架

如果学习过react、vue、angular三者之一我认为肯定在面试中会有一定的优势,因为如果你使用了这种框架来进行开发,那么一定会涉及到打包编译es6包括可能使用node做后端等等的尝试,同时现在很多大公司也正是使用这些技术来实现需求,所以如果你了解一下那么肯定是有好处的。区别可能就是自己的实践从量级、优化上还远远不足于线上产品。但是有过组件化或者双向绑定技术的实践对你之后面向正规开发会容易上手很多。毕竟做开发虽然我们的梦想是造轮子但是第一层境界也只是站在巨人的肩膀上使用工具感受工具带来的魅力而已。记得阿里去年有一道题让我手动实现一个angular的依赖注入。对不起我没用过angular...

关于项目

  1. 会重点听取你项目的核心是什么,并找到这个核心,然后问你如何实现的
  2. 基于你如何实现的,能进行优化么,你自己一定知道哪里还需要进行优化吧

举例:

去年一次电面,一位阿里的工程师对于我写的移动端react版本的轮播图组件上提出了一个我开发时候思考过的的一个问题。就是当手指滑动后,该张图片应该还有一个滚动动画,那么这个动画如何判断其滚动完成呢。其实这件事情如果熟悉原生开发或者有过RN开发经验一定不是难事,原生下面会有一个生命周期函数来告诉你滚动已经停止了,但是这件事情在网页上来说不是那么好断定。

粗暴的方法:setTimeout

我在那个组件中由于可能带来的兼容性原因加上没想到更好的实现方式,所以选择了比较粗略的定时器方式。大致用法为

this.setState({
    ... //这个状态下动画正在执行,预计300ms
},() => {
    setTimeout(() =>{
        //断定动画结束执行之后的操作
    }, 300)
})

为什么说是粗略呢?这个时候就应该重新关注一下setTimeout事件到底是如何执行的,定时和定时器中的操作一定是定时器到时间了里面就一定执行么,答案是否定的想了解setTimeout运行机制可以看下这篇你所不知道的setTimeout,函数真正执行的时间和定时器定的时间其实没有关系。总的来说定时器定的时间只是在那个时间点把你的事件扔进事件回调队列中,如果前面排着的事件计算量复杂,那么真到你那个定时器函数执行的时候也许黄花菜都凉了。所以“慎用定时器”,然而我...haveto?

兼容性可能带来问题的方法:-webkit-animation

有关-webkit-animation请戳这里

回想起来阿里的工程师面试还是很厉害的,虽然可能和我做的东西太常见有关,不过我觉得能从别人的项目中一下子找到实现的一些痛点的经验,也必定是要长期累月进行积累后才能游刃有余吧。

后记

写的很匆忙,但也算回顾了一年多工作中间的小心得吧。希望可以有所帮助大家多多交流。

最后分享一句从冴羽老师文章中看到的话,我个人觉得很有道理:

“曾经团队邀请过 Nodejs 领域一个非常著名的大神来分享,这里便不说是谁了。当知道是他后,简直是粉丝的心情。但是课讲得确实一般,也许是第一次讲,准备不是很充足吧,以至于我都觉得我能讲得比他好,但是有两次,让我觉得这是真正的大神。一次就是,当有同事问到今年有什么流行的前端框架吗?这些框架有怎样的适用场景?该如何抉择?我以为大神一定会回答当时正火的 React、以及小鲜肉 Vue 之类,然后老生常谈的比较一番,但是他回答道:“I dont't care!因为这些并不重要,真正重要的是底层,当你了解了底层,你就能很轻松的明白这些框架的原理,当你明白了原理,这些框架又有什么意思呢?”