九十六:你会用什么工具测试你的代码功能?
测试工具Jasmine等等
九十七:单元测试与功能/集成测试的区别是什么?
单元测试:
单元测试是对软件基本组成单元(软件设计的最小单位)进行正确性检验的测试工作,如函数、过程(function,procedure)或一个类的方法(method)。
集成测试:
集成测试是在单元测试的基础上,将所有模块按照概要设计要求组装成为子系统或系统,验证组装后功能以及模块间接口是否正确的测试工作。集成测试也叫组装测试、联合测试、子系统测试或部件测试。
九十八:代码风格 linting 工具的作用是什么?
检查和测试代码来发现任何潜在错误,从而在放到网站上之前及时消除错误是一个非常重要的过程。代码检查的过程也俗称为是Web设计师 和开发者之间的linting。作为一个设计师,如果你想要写出高度优化的代码,那么你一定需要linting工具。有两种类型的代码检查工具。一种是在 执行时间检查代码中的错误和bug。另一种是使用静态代码分析技术并在执行前检查码。后者因为可以节省时间和麻烦显然更佳
九十九:你会用什么工具来查找代码中的性能问题?
JSLint
一百:你会用什么方式来增强网站的页面滚动效能?
你应该是最外层用了 postion:absolute的布局了,最外层要用 relative的布局才不会这样,如果你实在要在最外层搞absolute得话那么你得在滚动的那一层上加 -webkit-overflow-scrolling: touch;
一百零一:请解释 layout,painting 和 compositing 的区别
layout:表示布局图,规划图等
painting:指油画,上颜色的画。。
compositing:指影像。。
一百零二:为什么传统上利用多个域名来提供网站资源会更有效?
- 静态内容和动态内容分服务器存放,使用不同的服务器处理请求。处理动态内容的只处理动态内容,不处理别的,提高效率,这样使得CDN(内容分发网络)缓存更方便
2、 突破浏览器并发限制 (你随便挑一个 G家的 url: https://lh4.googleusercontent.com/- si4dh2myPWk/T81YkSi__AI/AAAAAAAAQ5o/LlwbBRpp58Q/w497-h373/IMG_20120603_163233.jpg, 把前面的 lh4换成 lh3,lh6 啥的,都照样能够访问,像地图之类的需要大量并发下载图片的站点,这个非常重要。)
3、跨域不会传cookie,节省宽带;举例说一下:
twitter 的主站 http://twitter.com ,用户的每次访问,都会带上自己的cookie ,挺大的。假如twitter 的图片放在主站域名下,那么用户每次访问图片时,request header 里就会带有自己的cookie ,header 里的cookie 还不能压缩,而图片是不需要知道用户的cookie 的,所以这部分带宽就白白浪费了。
写主站程序时,set-cookie 也不要set 到图片的域名上。
在小流量的网站,这个cookie 其实节省不了多少带宽,当流量如facebook twitter 时,节省下来就很可观了。
一百零三:请尽可能完整得描述从输入 URL 到整个网页加载完毕及显示在屏幕上的整个流程。
1)用户输入网址
2)浏览器通过DNS获取网站的IP地址
3)浏览器尝试与服务器建立连接
4)服务器发送永久重定向
5)浏览器跟踪从定向地址
7)服务器处理请求
8)服务器发送HTML响应
9)浏览器开始显示HTML
10)浏览器发送获取嵌套在html中的元素
关于页面渲染过程:
1)解析HTML代码,生成一棵DOM树
2)解析CSS文件
3)生成渲染树(受样式影响,包含不可见元素)
4)渲染树中的节点
1)把URL分割成几个部分:协议、网络地址、资源路径。其中网络地址指示该连接网络上哪一台计算机,可以是域名或者IP地址,可以包括端口号;协议是从该计算机获取资源的方式,常见的是HTTP、FTP,不同协议有不同的通讯内容格式;资源路径指示从服务器上获取哪一项资源。
例如:http://www.guokr.com/question/554991/
协议部分:http
网络地址:www.guokr.com
资源路径:/question/554991/
2)如果地址不是一个IP地址,通过DNS(域名系统)将该地址解析成IP地址。IP地址对应着网络上一台计算机,DNS服务器本身也有IP,你的网络设置包含DNS服务器的IP。
例如:www.guokr.com 不是一个IP,向DNS询问请求www.guokr.com 对应的IP,获得IP: 111.13.57.142。这个过程里,你的电脑直接询问的DNS服务器可能没有www.guokr.com 对应的IP,就会向它的上级服务器询问,上级服务器同样可能没有,就依此一层层向上找,最高可达根节点,找到或者全部找不到为止。
3)如果地址不包含端口号,根据协议的默认端口号确定一个。端口号之于计算机就像窗口号之于银行,一家银行有多个窗口,每个窗口都有个号码,不同窗口可以负责不同的服务。端口只是一个逻辑概念,和计算机硬件没有关系。
例如:www.guokr.com 不包含端口号,http协议默认端口号是80。如果你输入的url是http://www.guokr.com:8080/ ,那表示不使用默认的端口号,而使用指定的端口号8080。
4)向2和3确定的IP和端口号发起网络连接。
例如:向111.13.57.142的80端口发起连接
5)根据http协议要求,组织一个请求的数据包,里面包含大量请求信息,包括请求的资源路径、你的身份
例如:用自然语言来表达这个数据包,大概就是:请求 /question/554991/ ,我的身份是xxxxxxx。
6)服务器响应请求,将数据返回给浏览器。数据可能是根据HTML协议组织的网页,里面包含页面的布局、文字。数据也可能是图片、脚本程序等。现在你可以用浏览器的“查看源代码”功能,感受一下服务器返回的是什么东东。如果资源路径指示的资源不存在,服务器就会返回著名的404错误。
7)如果(6)返回的是一个页面,根据页面里一些外链的URL,例如图片的地址,按照(1)-(6)再次获取。
8)开始根据资源的类型,将资源组织成屏幕上显示的图像,这个过程叫渲染,网页渲染是浏览器最复杂、最核心的功能。
9)将渲染好的页面图像显示出来,并开始响应用户的操作。
一百零四:Long-Polling、Websockets 和 Server-Sent Event 之间有什么区别?
AJAX Long-Polling:
客户端使用普通的http方式向服务器端请求网页
客户端执行网页中的JavaScript脚本,向服务器发送数据、请求信息
服务器并不是立即就对客户端的请求作出响应,而是等待有效的更新
当信息是有效的更新时,服务器才会把数据推送给客户端
当客户端接收到服务器的通知时,立即会发送一个新的请求,进入到下一次的轮询
HTML5 Server Sent Events (SSE) / EventSource:
客户端使用普通的http方式向服务器端请求网页
客户端执行网页中的JavaScript脚本,与服务器之间建立了一个连接
当服务器端有有效的更新时,会发送一个事件到客户端
服务器到客户端数据的实时推送,大多数内容是你需要的
你需要一台可以做Event Loop的服务器
不允许跨域的连接
如果你觉得这些还不够,想要了解更多,可以参考下面的文件和手册
HTML5 Websockets:
客户端使用普通的http方式向服务器端请求网页
客户端执行网页中的JavaScript脚本,与服务器之间建立了一个连接
服务器和客户端之间,可以双向的发送有效数据到对方
服务器可以实时的发送数据到客户端,同时客户端也可以实时的发送数据到服务器
你需要一台可以做Event Loop的服务器
使用 WebSockets 允许跨域的建立连接
它同样支持第三方的websocket主机服务器,例如Pusher或者其它。这样你只需要关心客户端的实现 ,降低了开发难度。
如果你觉得这些还不够,想要了解更多,可以参考下面的文件和手册
一百零五:请描述以下 request 和 response headers:
Diff. between Expires, Date, Age and If-Modified-...
Do Not Track
Cache-Control
Transfer-Encoding
ETag
X-Frame-Options
1.Expires(过期时间)HTTP头信息Expires(过期时间) 属性是HTTP控制缓存的基本手段,这个属性告诉缓存器:相关副本在多长时间内是新鲜的。过了这个时间,缓存器就会向源服务器发送请求,检查文档是否被修 改。几乎所有的缓存服务器都支持Expires(过期时间)属性;
2.Cache-Control响应头信息包括:
max-age=[秒] — 执行缓存被认为是最新的最长时间。类似于过期时间,这个参数是基于请求时间的相对时间间隔,而不是绝对过期时间,[秒]是一个数字,单位是秒:从请求时间 开始到过期时间之间的秒数。
s-maxage=[秒] — 类似于max-age属性,除了他应用于共享(如:代理服务器)缓存
public — 标记认证内容也可以被缓存,一般来说: 经过HTTP认证才能访问的内容,输出是自动不可以缓存的;
no-cache — 强制每次请求直接发送给源服务器,而不经过本地缓存版本的校验。这对于需要确认认证应用很有用(可以和public结合使用),或者严格要求使用最新数据 的应用(不惜牺牲使用缓存的所有好处);
no-store — 强制缓存在任何情况下都不要保留任何副本
must-revalidate — 告诉缓存必须遵循所有你给予副本的新鲜度的,HTTP允许缓存在某些特定情况下返回过期数据,指定了这个属性,你高速缓存,你希望严格的遵循你的规则。
proxy-revalidate — 和 must-revalidate类似,除了他只对缓存代理服务器起作用
举例:
Cache-Control: max-age=3600, must-revalidate
3:Last-modified:如果你第二次 (或第三次,或第四次) 请求相同的数据,你可以告诉服务器你上一次获得的最后修改日期:在你的请求中发送一个 If-Modified-Since 头信息,它包含了上一次从服务器连同数据所获得的日期。如果数据从那时起没有改变,服务器将返回一个特殊的 HTTP 状态代码 304,这意味着 “从上一次请求后这个数据没有改变”。这一点有何进步呢?当服务器发送状态编码 304 时,不再重新发送数据。您仅仅获得了这个状态代码。所以当数据没有更新时,你不需要一次又一次地下载相同的数据;服务器假定你有本地的缓存数据。
所有现代的浏览器都支持最近修改 (last-modified) 的数据检查。如果你曾经访问过某页,一天后重新访问相同的页时发现它没有变化,并奇怪第二次访问时页面加载得如此之快——这就是原因所在。你的浏览器首次 访问时会在本地缓存页面内容,当你第二次访问,浏览器自动发送首次访问时从服务器获得的最近修改日期。服务器简单地返回 304: Not Modified (没有修改),因此浏览器就会知道从本地缓存加载页面。在这一点上,Web 服务也如此智能
4:ETag 是实现与最近修改数据检查同样的功能的另一种方法:没有变化时不重新下载数据。其工作方式是:服务器发送你所请求的数据的同时,发送某种数据的 hash (在 ETag 头信息中给出)。hash 的确定完全取决于服务器。当第二次请求相同的数据时,你需要在 If-None-Match: 头信息中包含 ETag hash,如果数据没有改变,服务器将返回 304 状态代码。与最近修改数据检查相同,服务器仅仅 发送 304 状态代码;第二次将不为你发送相同的数据。在第二次请求时,通过包含 ETag hash,你告诉服务器:如果 hash 仍旧匹配就没有必要重新发送相同的数据,因为你还有上一次访问过的数据。
5:使用 X-Frame-Options
X-Frame-Options 有三个值:
DENY
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN
表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM uri
表示该页面可以在指定来源的 frame 中展示。
换一句话说,如果设置为 DENY,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为 SAMEORIGIN,那么页面就可以在同域名页面的 frame 中嵌套。
Transfer-Encoding:解决报文发送结束标志的问题,https://imququ.com/post/transfer-encoding-header-in-http.html
一百零六:什么是 HTTP method?请罗列出你所知道的所有 HTTP method,并给出解释。
1.安全方法
HTTP定义了一组被称为安全方法的方法。GET方法和HEAD方法都被认为是安全的,这就意味着使用GET或HEAD方法的HTTP请求都不会产生什么动作。
安全方法并不一定什么动作都不执行(由web开发者决定)
使用安全方法的目的就是当使用可能引发某一动作的不安全方法时,运行HTTP应用程序开发者通知用户。
2.GET方法
通常用于请求服务器发送某个资源。HTTP/1.1实现此方法。
3.HEAD方法
HEAD方法与GET方法的行为很类似,但服务器在响应中只返回首部。不会反回实体的主体部分。这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查。
使用HEAD,可以:
在不获取资源的情况下,了解资源的情况
通过查看响应中的状态码,看看某个对象是否存在
通过查看首部,测试资源是否被修改
服务器开发者必须确保返回的首部与GET请求返回的首部完全相同
4.PUT方法
与GET方法从服务器读取文档相反,PUT方法会向服务器写入文档。有些发布系统允许用户创建WEB页面,并用PUT直接将其安装到WEB服务器上。
5.POST方法
POST方法起初是用来向服务器写入数据的。实际上,通常会用它来支持HTML的表单。表单中填好的数据通常会被发送给服务器,然后服务器将其发送到他要去的地方。
6.TRACE方法
TRACE方法允许客户端在最终将请求发送给服务器时,看看他变成了什么样子。
TRACE请求最终会在目的服务器发起一个回环诊断,行程最后一站的服务器会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间HTTP程序组成的请求响应链上,原始报文是否以及如何被毁坏或修改过。
TRACE方法主要用于诊断
中间应用程序会自行决定对TRACE请求的处理方式
TRACE请求不能带有实体的主体部分。TRACE响应的实体主体部分包含了响应服务器收到的请求的精确副本。
7.OPTIONS方法
OPTIONS方法请求WEB服务器告知其支持的各种功能。
可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
使用OPTIONS方法的请求和响应示例:
请求报文
OPTIONS http://www.cnivi.com.cn/ HTTP/1.1
Accept-Encoding: gzip,deflate
Host: www.cnivi.com.cn
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
响应报文
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Thu, 09 Oct 2014 04:20:09 GMT
8.DELETE方法
DELETE方法所做的事情就是请服务器删除请求URL所指定的资源。
但是客户端应用程序无法保证删除操作一定会执行。因为HTTP规范允许服务器在不通知客户端的情况下撤销请求。
下面是扩展方法(WebDAV HTTP扩展)
9.LOCK方法
允许用户锁定资源,比如可以再编辑某个资源时将其锁定,以防别人同时对其进行编辑。
10.MKCOL方法
允许用户创建资源
11.COPY方法
便于用户在服务器上复制资源
12.MOVE方法
在服务器上移动资源
一百零七:代码
var foo = 10 + '20';
foo = "1020"
function add(a, b){
return a + b;
}
function(a){
return function(b){
return a + b;
}
}
"i'm a lasagna hog".split("").reverse().join("");
得到:goh angasal a m'i
( window.foo || ( window.foo = "bar" ) );
执行结果: "bar" 原因:foo未得到,所以执行后面的赋值操作,复制之后foo为bar
var foo = 1;
function bar() {
foo = 10;
return;
function foo() {}
}
bar();
alert(foo);
输出1,因为function foo() {}提升至函数上面,foo成为局部变量
function bar() {
return foo;
foo = 10;
function foo() {}
var foo = 11;
}
alert(typeof bar());
输出function(var foo = 11 虽然定义放在后面,但是变量会提升,所以最后的结果是function)
var x = 3;
var foo = {
x: 2,
baz: {
x: 1,
bar: function() {
return this.x;
}
}
}
var go = foo.baz.bar;
alert(go());
alert(foo.baz.bar());
答:3,1.
go = foo.baz.bar; go()此时this指向的是widow. window.x的值是3;foo.baz.bar()此时this指向的是baz,baz.x的值是1.
var x = 4,
obj = {
x: 3,
bar: function() {
var x = 2;
setTimeout(function() {
var x = 1;
alert(this.x);
}, 1000);
}
};
obj.bar();
答:输出4.
setTimeout方法是挂在window对象下的。setTimeout(匿名函数,time),这里的匿名函数形成了一个闭包,从而能访问到外层函数的局部变量。也就是window中的x。(参考)
x = 1;
function bar() {
this.x = 2;
return x;
}
var foo = new bar();
alert(foo.x);
答:输出2.
这里的this指向的是bar的对象实例。
var arr = [];
arr[0] = 'a';
arr[1] = 'b';
arr.foo = 'c';
alert(arr.length);
2
function foo(){}
delete foo.length;
alert(typeof foo.length);
答:number;foo.length的值还是0。delete无法删除,参考
13.问:以下代码中,
var name="the window";
var object={
name:"my object",
getName: function(){
return this.name;
}
}
通过以下调用
object.getName();
(object.getName)();
(object.getName = object.getName)()
结果是?
my object
my object
the window
第一行的代码,this指向的就是object,所以毫无疑问;第二行代码虽然加上括号,就好像只是在引用一个函数,但this的值得到了维持。因为object.getName和(object.getName)的定义相同。第三行代码,先执行一条赋值语句,然后再调用赋值后的结果。因为这个赋值表达式的值是函数本身,所以this的值不能得到维持,结果就返回the window.
var foo = "Hello";
(function() {
var bar = " World";
alert(foo + bar);
})();
alert(foo + bar);
Hello world
报错:bar is not defined
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
foo.x的值是undefined,因为二次赋值,foo = {n:2}没有x属性
正则表达式判断邮箱
function test(){
var temp = document.getElementById("text1");
//对电子邮件的验证
var myreg = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
if(!myreg.test(temp.value))
{
alert('提示\n\n请输入有效的E_mail!');
myreg.focus();
return false;
}
//由于方法相同,一下只写出相关的正则表达式
//对于手机号码的验证(提供了两种方法)
var mobile=/^((13[0-9]{1})|159|153)+\d{8}$/;
var mobile1=/^(13+\d{9})|(159+\d{8})|(153+\d{8})$/;
//对于区号的验证
var phoneAreaNum = /^\d{3,4}$/;
//对于电话号码的验证
var phone =/^\d{7,8}$/;
}