@yacent
2016-10-24T15:22:04.000000Z
字数 4948
阅读 1008
面试题目
2016.03.24
很惊喜自己上一轮有些没答得太好,还是幸运地进入到了美团的二面。在这里,应
该是要感谢当时给我面试的师兄吧,他人挺好的,然后面试完了还一直在 帮我分
析(可能刚好是遇到身为广东的师兄面试到广东小伙伴的缘由,觉得很兴奋吧。
好的,下面话不多说,咱们直接进入到面试过程中的问题。
首先还是万年不变的自我介绍环节,面了一些,发现自我介绍环节,其实就自己讲
讲自己的一些经历就好,其实面试官在这段时间会看你的简历,然后准备 问题,
亦或者如果你的自我介绍有亮点的地方,不妨你自己多讲讲,比如做了哪些好的项
目,有什么创新点的地方等等,都是可以主动讲出来的。
我基本上都只是讲我个人信息,然后大一到现在经历以及如何学习并且做过的一些
项目。(我觉得 面试官比较会喜欢 爱学习 爱思考 爱动手的孩子) 怎么表现出来
就是自己去琢磨吧,总有方法能够旁敲侧击告诉他,我爱学习爱思考
OK 面试题开始了
组件化
问:请你说一说对于组件化的理解,以及在项目中如何进行实现的。
大致说了一下组件化,我所理解的组件化就是比如一个电视,是有很多个小零件组
成的,每个小零件都是一个完整的东西,整个电视就由这些小零件拼合起来。具体
到页面上,就比如一个sidebar,单独出来,然后在文件当中写上相应的html,写上
一些样式以及js之后,这就是一个sidebar组件, 然后别的页面上需要改组件,只
需要进行拼凑就好了。(其实是因为自己并没有玩过组件化,所以会说的有点虚,
真不知道自己为何当初脑残写了个组件化 上去,后来发现是因为自己理解的组件
化和实际的组件化不同。好吧,真的不要给自己挖坑,不然会gg,一定要确保自己
写在上面的东西都要知道。然后 我又说了一些,可以实现组件化的框架,比如
vue.js、react、angular.js、component等等都可以实现。
这道题因为自己也没有对组件化特别深入,所以面试官也没有继续追问下去。
设计模式
问:
请你说说你所了解设计模式
我当时就说了 工厂、单例、观察者模式,一定要说自己知道确切实现方式的
会比较好,不要给自己挖坑。
单例模式(singleton)
实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了
再返回,这就确保了一个类只有一个实例对象
var createMask = (function() {var mask;return function() {return mask || (mask =document.body.appendChild(document.createElement("div")));}})();
可以从上面看出,此处用了一个简单的闭包,将mask包起来,对于createMask函数
来讲,其为封闭的。
我们可以修改一下,将单例模式修改为另外一种模式 桥接模式,即函数作为
参数传入,具体如下
var singleton = function(fn) {var result;return function() {return result || (result = fn.apply(this, arguments));}}var createMask = singleton(function() {return document.body.appendChild(document.createElement("div"));});
工厂模式
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥
有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在
执行期决定的情况。 说的通俗点,就像公司茶水间的饮料机,要咖啡还是牛奶取
决于你按哪个按钮。
function createPerson(name, age, job) {var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function() {alert(this.name);};return o;}var person1 = createPerson("Nic", 29, "teacher");var person2 = createPerson("Yic", 21, "doctor");
工厂模式适用的场景:
1. 对象的构建复杂、繁琐
2. 需要依赖具体环境创建不同的实例
3. 处理大量具有相同属性的小对象
观察者模式(发布者-订阅者模式)
主题负责发布事件,同时观察者通过订阅这些事件来观察该主体
在我们所接触的事件,即为一种观察者模式
// div为发布者,onclick事件为订阅者div.onclick = function() {alert("click");}
我们为什么要用观察者模式呢,主要是可以实现松散耦合的代码,什么意思?就是
主体和订阅者之间是相互独立的,其二者可以独立运行。
举个例子说明一下,使用观察者模式的好处。如下
某团队正在开发一个H5的游戏,游戏开始前,会先进行一些图片的加载,图片加在
完成后,会进行地图的加载以及Gamer模块的记载,具体代码如下
loadImage(imgAry, function() {Map.init();Gamer.init();});
然后,需求改变了,需要再给游戏添加上声音的功能,可是,写该模块的同事去外
地旅游了,于是就要打电话给他,问loadImage的函数写在哪啊,能不能 改一下,
改了之后有没有副作用……此时,代码又会如下,但是心中是各种不淡定,不知道会
不会发生什么问题。
loadImage(imgAry, function() {Map.init();Gamer.init();Sound.init();});
要是采取观察者模式来进行写这个东西,就不关心会发生什么改变,对事件
进行监听并且在合适的时候触发该事件即可
loadImage.addHandler("ready", function() {Map.init();});loadImage.fire("ready")
但是观察者模式从概念上来说是简单的,就是添加一个观察的以及触发的事
件,但是具体实现呢?我比较喜欢用用自定义事件来模拟实现 观察者模式,如下
function EventTarget() {this.handlers = {};}EventTarget.prototype = {constructor: EventTarget,addHandler: function(type, handler) {if (typeof this.handlers[type] == "undefined") {this.handlers[type] = []}this.handlers[type].push(handler);},fire: function(event) {if (!event.target) {event.target = this;}if (this.handlers[event.type] instanceof Array) {var handlers = this.handlers[event.type];for (var i = 0, len = handlers.length; i < len; i++) {handlers[i](event);}}},remove: function(type, handler) {if (this.handlers[type] instanceof Array) {var handlers = this.handlers[type];for (var i = 0, len = handlers.length; i < len; i++) {if (handlers[i] === handler) {break;}}handlers.splice(i, 1);}}};
推荐看:http://blog.jobbole.com/29454/ 或者看原著《Javascript设计模式》
deepEquals
问:
我现在出一道题目给你,然后具体如下
function deepEqual() {// code here}// 测试deepEqual({a:1}, {a:1}); // truedeepEqual([1,2], [1, 2]); // truedeepEqual([1, {a:1}], [1, {a:1}]); // true
这题出给我之后,大致理解一下题目,就是说,要自己实现一个deepEqual的函
数,然后能够判别两个object是相等与否,两个array 相等否,以及array当中是
可以嵌套object的,object当中也是可以嵌套object的。
短时间内,我觉得是很难写完整的,关键思想是要怎么处理 → 嵌套
要体现出思想我觉得就OK了
function deepEqual(a, b) {// produce Arrayif (isArray(a) && isArray(b)) {return isSameArray(a, b);}// produce objectif (isObject(a) && isObject(b)) {return isSameObject(a, b);}if (a.toString() === b.toString()) {return true;}return false;}function isArray(a) {return (Object.prototype.toString.call(a) === "[object Array]");}function isObject(a) {return (typeof a === "object");}function getKeys(obj) {var keys = [];for (var k in obj) {keys.push(k);}return keys;}function isSameArray(a, b) {if (a.length !== b.length) {return false;}for (var i = 0, len = a.length; i < len; i++) {if (!deepEqual(a[i], b[i])) {return false;}}return true;}function isSameObject(a, b) {var aKeys = getKeys(a);var bKeys = getKeys(b);if (aKeys.length !== bKeys.length) {return false;}//sortaKeys.sort();bKeys.sort();for (var i = 0, len = aKeys.length; i < len; i++) {var k = aKeys[i];// recursive deep equalif (!deepEqual(a[k], b[k])) {return false;}}return true;}// 测试deepEqual({a:1}, {a:1}); // truedeepEqual([1,2], [1, 2]); // truedeepEqual([1, {a:1}], [1, {a:1}]); // true
CSS垂直水平居中
问:
我要实现一个元素的垂直水平都居中,你会怎么去实现。
这道题应该还是中规中矩的,就挺正常的经典考题,我经常使用的是两种方
法,如下
////// html //////<div class="outer"><div class="inner"></div></div>////// css ///////.outer {position: relative;width: 300px;height: 300px;border: 1px solid black;}/* method 1*/.inner {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}/* method 2*/.inner {position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;}
以上两种方法是我平常所最爱使用过的垂直水平居中的办法,当然还有许许多多其
他的办法,比如知道确切width和height的时候,也可以用 margin来进行调整固定
的长度。
如果是行内元素的垂直水平居中,比较简单,只需要用 text-align以及
line-height两个属性就可以完成了。具体可以自己查询一下。