2019独角兽企业重金招聘Python工程师标准>>>
人人公司的一面还是比较而基础的,基本上都是之前已经复习好到了的知识点(但是由于我的简历上写了熟悉c++和sql,所以对于这两点没有做准备,然后面试完就把简历上这两条给删了)
- 人人网面试经验
-
- js设计模式(这点我在简历上写了)
-
- 工厂模式
- 单体(单例)模式
- 模块模式
- 观察者模式
- 装饰者模式
- 跨域的几种方式
- 对html5的理解
- 如何让一个div实现水平垂直居中
-
- 文字,图片以及内联元素
- 对于已经设置宽高的元素
- 多行文字
- 浮动元素
- 绝对定位和fixed定位的元素
- 行内元素和块级元素的区别
- jquery中的选择器
-
- localstorage 和cookie的区别
js设计模式(这点我在简历上写了)
之前有看过js设计模式这本书,所以还是记得几种设计模式,现在列举如下
正如您在阅读的这份文档,它使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接或一个脚注[^demo]。下面列举了几个高级功能,更多语法请按Ctrl + /
查看帮助。
工厂模式
工厂模式在《JavaScript高级程序设计》中,被列为是第一种构造对象实例的方法,代码如下:
function CreatePerson(name,age,sex) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.sayName = function(){
return this.name;
}
return obj;
}
工厂模式是为了解决多个类似对象声明的问题;也就是为了解决实列化对象产生重复的问题
优点:能解决多个相似的问题。
缺点:不能知道对象识别的问题(对象的类型不知道)。
单体(单例)模式
单例模式是指在实例不存在的时候,可以通过一个方法创建一个类来实现创建类的新实例,但是如果该实例已经存在,它只会返回该对象的引用
基本的代码模式如下:
// 单体模式
var Singleton = function(name){
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function(){
return this.name;
}
// 获取实例对象
function getInstance(name) {
if(!this.instance) { //这里是关键,通过这个来限制单体
this.instance = new Singleton(name);
}
return this.instance;
}
// 测试单体模式的实例
var a = getInstance("aa");
var b = getInstance("bb");
模块模式
模块模式是使用闭包封装“私有”状态和组织。它提供了一种包装混合公有/私有方法和变量的方式,防止其泄露至全局作用域,并与别的开发人员的接口发生冲突。通过该模式,只需返回一个公有的API,而其他的一起都维持在私有闭包中
基本代码如下
var singleMode = (function(){
// 创建私有变量
var privateNum = 112;
// 创建私有函数
function privateFunc(){
// 实现自己的业务逻辑代码
}
// 返回一个对象包含公有方法和属性
return {
publicMethod1: publicMethod1,
publicMethod2: publicMethod1
};
})();
注意:最后只允许通过singleMode这个变量访问里面的私有变量
观察者模式
观察者模式( 又叫发布者-订阅者模式 )是指一个对象维持一系列依赖于它(观察者)的对象,将有关状态的任何变更自动通知给它们,下面是在jquery中的实现:
(function ($) {
var o = $({});
$.subscribe = function () {
o.on.apply(o, arguments);
};
$.unsubscribe = function () {
o.off.apply(o, arguments);
};
$.publish = function () {
o.trigger.apply(o, arguments);
};
} (jQuery));
详细的可以了解《javascript设计模式》中的第9章第五小节,还可以戳链接
优点:(1)支持简单的广播通信,自动通知所有已经订阅过的对象;
(2)页面载入后发布者很容易与订阅者存在一种动态关联,增加了灵活性;
(3)发布者与订阅者之间的抽象耦合关系能够单独扩展以及重用。
缺点:(1)创建订阅者本身要消耗一定的时间和内存,而且当你订阅一个消息后,也许此消息最后都未发生,但这个订阅者会始终存在于内存中;
(2)虽然可以弱化对象之间的联系,但如果过度使用的话,对象和对象之间的必要联系也将被深埋在背后,会导致程序难以跟踪维护和理解。
装饰者模式
通常,装饰者提供了将行为动态添加至系统的现有类的能力,其想法是,装饰本身对于类原有的基本功能来说并不是必要的,否则,它就可以被合并到超类本身了
function ABicycle(){ }
ABicycle.prototype = {
wash : function(){ },
ride : function(){ },
getPrice : function(){
return 999;
}
}
function bicycleBell( bicycle ){
var price= bicycle.getPrice();
bicycle.bell = function(){
console.log("ding! ding! ding!");
};
bicycle.getPrice = function(){ //重新装饰了该对象
return price + 100;
};
return bicycle;
}
var bicycleA = new ABicycle();
bicycleA = bicycleBell( bicycleA );
注意:装饰者模式有如下特点:
1. 不修改原对象的原本结构来进行功能添加。
2. 装饰对象和原对象具有相同的接口,可以使客户以与原对象相同的方式使用装饰对象。
3. 装饰对象中包含原对象的引用,即装饰对象为真正的原对象在此包装的对象。
跨域的几种方式
这个基本上是耳熟能详的面试题了,详细可以戳链接
面试官具体问了jsonp的优缺点,总结如下:
优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。
点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
对html5的理解
这个比较宽泛,个人觉得就是从html5的语义化和新增特性入手,这里有一个链接 是介绍html5的新特性的
如何让一个div实现水平垂直居中
文字,图片以及内联元素
span{
text-align:center;
}
对于已经设置宽高的元素
div{
margin:0 auto;
height:200px;
width:200px;
line-height:200px; //和height一样
}
多行文字
p{
width:200px;
height:200px;
text-align:center;
display:table-cell;
vertical-align:middle;
}
浮动元素
可以设置css样式如下:
.parent{ //不需要设置父元素的宽高
position:relative;
float:left;
left:50%;
}
.child{
heigth:200px;
width:200px;
float:left;
left:50%;
position:relative;
}
绝对定位和fixed定位的元素
有如下两种方式:
.one{
position:absolute;
width:200px;
height:200px;
top:50%;
left:50%;
margin-left:-100px; //宽度的一半
margin-top:-100px; //高度的一半
}
//第二种方式
.two{
position:absolute/fixed;
width:140px;
height:140px;
top:0;
left:0;
bottom:0;
right:0;
margin:auto;
}
行内元素和块级元素的区别
行内元素与块级元素直观上的区别
(1) 行内元素会在一条直线上排列,都是同一行的,水平方向排列
块级元素各占据一行,垂直方向排列。块级元素从新行开始结束接着一个断行。
(2) 块级元素可以包含行内元素和块级元素。行内元素不能包含块级元素。
(3) 行内元素与块级元素属性的不同,主要是盒模型属性上
jquery中的选择器
当我们使用选择器的时候$(selector,content),就会执行init(selectot,content),我们看看inti中是怎样执行的:
if ( typeof selector == "string" )
{
//正则匹配,看是不是HTML代码或者是#id
var match = quickExpr.exec( selector );
//没有作为待查找的 DOM 元素集、文档或 jQuery 对象。
//selector是#id的形式
if ( match && (match[1] || !context) )
{
// HANDLE: $(html) -> $(array)
//HTML代码,调用clean补全HTML代码
if ( match[1] ){
selector = jQuery.clean( [ match[1] ], context );
}
// 是: $("#id")
else {
//判断id的Dom是不是加载完成
var elem = document.getElementById( match[3] );
if ( elem ){
if ( elem.id != match[3] )
return jQuery().find( selector );
return jQuery( elem );//执行完毕return
}
selector = [];
}
//非id的形式.在context中或者是全文查找
}
else{
return jQuery( context ).find( selector );
}
}
这里就说明只有选择器写成
$('#id')
的时候最快,相当于执行了一次getElementById,后边的程序就不用再执行了。当然往往我们需要的选择器并不是这么简单,比如我们需要id下的CSS为className, 有这样的写法$('#id.className')
和$('#id').find('.className')
;这两种写法的执行结果都是一样的,比如
,返回的肯定都是,但是执行的效率是完全不一样的。
在分析一下上边的代码,如果不是$(‘#id’)这样的简单选择器的话,都会执行find函数,那我们再看看find到底是做用的:
find: function( selector ) {
//在当前的对象中查找
var elems = jQuery.map(this, function(elem){
return jQuery.find( selector, elem );
});
//下边的代码可以忽略,只是做一些处理
//这里应用了js的正则对象的静态方法test
//indexOf("..")需要了解一下xpath的语法,就是判断selector中包含父节点的写法
//本意就是过滤数组的重复元素
return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
jQuery.unique( elems ) :
elems );
}
详细请看链接
localstorage 和cookie的区别
这个也是老生常谈的话题了,在这里不列出了,详细看链接
这次的面试感觉还是没有问得太深,都是之前复习过的,只有设计模式还有jquery选择器这两者之前没有怎么看过