1、记一道经典的 JavaScript 面试题
1、function Foo() {
getName = function () { alert (1); };
return this;
}
2、Foo.getName = function () { alert (2);};
3、Foo.prototype.getName = function () { alert (3);};
4、var getName = function () { alert (4);};
5、function getName() { alert (5);}
//请依次写出以下输出结果:
Foo.getName(); 题一?
getName(); 题二?
Foo().getName(); 题三?
getName(); 题四?
new Foo.getName(); 题五?
new Foo().getName(); 题六?
new new Foo().getName();题七?
分析:
首先,定义了一个叫Foo的函数,函数里创建了一个叫getName的静态属性存储了一个匿名函数
之后,为Foo的原型对象创建了一个叫getName的匿名函数
之后,通过函数表达式创建了一个叫getName的函数
最后,声明了一个叫getName的函数。
题一 通过JS运算符的优先级判断,等价于(Foo.getName)();
题二 直接调用getName()方法,其实就是window.getName(),只有4和5符合条件,这里有一个点是JavaScript 解释器中存在一种变量声明被提升的机制,也就是说函数声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面。所以5会先执行,4后执行,就是说4会把5覆盖,所以输出应该是4
题三 先执行了Foo函数,然后调用Foo函数的返回值对象的getName属性函数;Foo函数里面首先对getName(getName前面没有 var,所以这是一个全局的变量)进行赋值操作,及覆盖了原来的getName,函数里面返回值为this,其实就是window对象,所以Foo().getName()就是window.Foo().getName(),及window.this.getName(),前面说了Foo()对getName()进行了重新赋值,所以输出应该是alert (1)
题四 通过题三我们知道window.getName()输出结果为1
题五 通过JS运算符的优先级判断(参考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence),点的优先级大于new,所以题五等于new (Foo.getName)();将 Foo.getName 作为构造函数调用,普通函数作为构造函数调用首先会调用一次原函数,故 Foo.getName() 被调用。(即函数2,原理同问题一)
题六 等价于(new Foo()).getName(),由于Foo()返回的是this,而this在构造函数中本来就代表当前实例化对象,最终Foo函数返回实例化对象。之后调用实例化对象的getName函数,因为在Foo构造函数中没有为实例化对象添加任何属性,当前对象的原型对象(prototype)中寻找getName函数。输出3
题七 等价于 new ((new Foo()).getName)();先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次new,所以最终结果为3
1、ajax发送异步请求的四个步骤?
1)得到xmlHttpRequest对象;
2)打开与服务器的连接(需要三个参数:请求方式,url,是否异步);
3)发送请求;
4)在对象的一个事件上注册监听器
2、servlet生命周期?
1)加载(servlet类);
2)实例化(初始化参数);
3)服务(处理请求);
4)销毁
3、JSP内置对象及作用?
1)request 封装客户端请求
2)response 服务端响应信息
3)session 一次会话
4)page 指当前jsp页面本身
5)application 实现了用户之间数据共享,开始于服务器启动直到服务器关闭
6)out 向客户端输出内容
7)config 包含servlet初始化时所要用到的参数
8)pagecontext 提供了对本页所有对象的访问
9)exception 例外对象
4、Servlet接口中有哪些方法?
Servlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关:
- void init(ServletConfig config) throws ServletException
- void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
- void destory()
- java.lang.String getServletInfo()
- ServletConfig getServletConfig()
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法。
5、转发(forward)和重定向(redirect)的区别?
forward是容器中控制权的转向,是服务器请求资源,服务器直接访问目标地址的URL,把那个URL 的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。
redirect就是服务器端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址,因此从浏览器的地址栏中可以看到跳转后的链接地址,很明显redirect无法访问到服务器保护起来资源,但是可以从一个网站redirect到其他网站。
forward更加高效,所以在满足需要时尽量使用forward(通过调用RequestDispatcher对象的forward()方法,该对象可以通过ServletRequest对象的getRequestDispatcher()方法获得),并且这样也有助于隐藏实际的链接;在有些情况下,比如需要访问一个其它服务器上的资源,则必须使用重定向(通过HttpServletResponse对象调用其sendRedirect()方法实现)。
6、get和post请求的区别?
①get请求用来从服务器上获得资源,而post是用来向服务器提交数据;
②get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用"?"连接,而各个变量之间使用"&"连接;post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指向URL;
③get传输的数据要受到URL长度限制(1024字节);而post可以传输大量的数据,上传文件通常要使用post方式;
④使用get时参数会显示在地址栏上,如果这些数据不是敏感数据,那么可以使用get;对于敏感数据还是应用使用post;
⑤get使用MIME类型application/x-www-form-urlencoded的URL编码(也叫百分号编码)文本的格式传递参数,保证被传送的参数由遵循规范的文本组成,例如一个空格的编码是"%20"。
7、jsp和servlet的区别和联系:
1)jsp经编译后就变成了Servlet.(JSP的本质就是Servlet,JVM只能识别java的类,不能识别JSP的代码,Web容器将JSP的代码编译成JVM能够识别的java类)
2)jsp更擅长表现于页面显示,servlet更擅长于逻辑控制.
3)Servlet中没有内置对象,Jsp中的内置对象都是必须通过HttpServletRequest对象,HttpServletResponse对象以及HttpServlet对象得到.
Jsp是Servlet的一种简化,使用Jsp只需要完成程序员需要输出到客户端的内容,Jsp中的Java脚本如何镶嵌到一个类中,由Jsp容器完成。而Servlet则是个完整的Java类,这个类的Service方
法用于生成对客户端的响应。
联系: JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示
层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。JSP侧重于视图,Servlet主要用于控制逻辑。
8、讲解JSP中的四种作用域。
JSP中的四种作用域包括page、request、session和application,具体来说:
- page代表与一个页面相关的对象和属性。
- request代表与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web组件;需要在页面显示的临时数据可以置于此作用域。
- session代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的session中。
- application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域。
9、如何实现JSP或Servlet的单线程模式?
对于JSP页面,可以通过page指令进行设置。
<%@page isThreadSafe=”false”%>
对于Servlet,可以让自定义的Servlet实现SingleThreadModel标识接口。
说明:如果将JSP或Servlet设置成单线程工作模式,会导致每个请求创建一个Servlet实例,这种实践将导致严重的性能问题(服务器的内存压力很大,还会导致频繁的垃圾回收),所以通常情况下并不会这么做。
10、实现会话跟踪的技术有哪些?
由于HTTP协议本身是无状态的,服务器为了区分不同的用户,就需要对用户会话进行跟踪,简单的说就是为用户进行登记,为用户分配唯一的ID,下一次用户在请求中包含此ID,服务器据此判断到底是哪一个用户。
①URL 重写:在URL中添加用户会话的信息作为请求的参数
②设置表单隐藏域:将和会话跟踪相关的字段添加到隐式表单域中,这些信息不会在浏览器中显示但是提交表单时会提交给服务器。
这两种方式很难处理跨越多个页面的信息传递,因为如果每次都要修改URL或在页面中添加隐式表单域来存储用户会话相关信息,事情将变得非常麻烦。
③cookie:在使用cookie时要注意几点:首先不要在cookie中存放敏感信息;其次cookie存储的数据量有限(4k),不能将过多的内容存储cookie中;再者浏览器通常只允许一个站点最多存放20个cookie。
④HttpSession:在所有会话跟踪技术中,HttpSession对象是最强大也是功能最多的。与上面三种方式不同的是,HttpSession放在服务器的内存中,因此不要将过大的对象放在里面,即使目前的Servlet容器可以在内存将满时将HttpSession中的对象移到其他存储设备中,但是这样势必影响性能。
**补充:**HTML5中可以使用Web Storage技术通过JavaScript来保存数据,例如可以使用localStorage和sessionStorage来保存用户会话的信息,也能够实现会话跟踪。
11、过滤器有哪些作用和用法?
对Web应用来说,过滤器是一个驻留在服务器端的Web组件,它可以截取客户端和服务器之间的请求与响应信息,并对这些信息进行过滤。当Web容器接受到一个对资源的请求时,它将判断是否有过滤器与这个资源相关联。如果有,那么容器将把请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容,或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时候,容器同样会将响应先转发给过滤器,在过滤器中你可以对响应的内容进行转换,然后再将响应发送到客户端。
常见的过滤器用途主要包括:对用户请求进行统一认证、对用户的访问请求进行记录和审核、对用户发送的数据进行过滤或替换、转换图象格式、对响应内容进行压缩以减少传输量、对请求或响应进行加解密处理、触发资源访问事件、对XML的输出应用XSLT等。
12、监听器有哪些作用和用法?
Java Web开发中的监听器(listener)就是application、session、request三个对象创建、销毁或者往其中添加修改删除属性时自动执行代码的功能组件,如下所示:
①ServletContextListener:对Servlet上下文的创建和销毁进行监听。
②ServletContextAttributeListener:监听Servlet上下文属性的添加、删除和替换。
③HttpSessionListener:对Session的创建和销毁进行监听。
补充:session的销毁有两种情况:1). session超时(可以在web.xml中通过<session-config>/<session-timeout>标签配置超时时间);2). 通过调用session对象的invalidate()方法使session失效。
④HttpSessionAttributeListener:对Session对象中属性的添加、删除和替换进行监听。
⑤ServletRequestListener:对请求对象的初始化和销毁进行监听。
⑥ServletRequestAttributeListener:对请求对象属性的添加、删除和替换进行监听。
13、web.xml文件中可以配置哪些内容?
web.xml用于配置Web应用的相关信息,如:监听器(listener)、过滤器(filter)、 Servlet、相关参数、会话超时时间、安全验证方式、错误页面等
14、你的项目中使用过哪些JSTL标签?
项目中主要使用了JSTL的核心标签库,包括<c:if>、<c:choose>、<c: when>、<c: otherwise>、<c:forEach>等,主要用于构造循环和分支结构以控制显示逻辑。
说明:虽然JSTL标签库提供了core、sql、fmt、xml等标签库,但是实际开发中建议只使用核心标签库(core),而且最好只使用分支和循环标签并辅以表达式语言(EL),这样才能真正做到数据显示和业务逻辑的分离,这才是最佳实践。
15、使用标签库有什么好处?
使用标签库的好处包括以下几个方面:
- 分离JSP页面的内容和逻辑,简化了Web开发;
- 开发者可以创建自定义标签来封装业务逻辑和显示逻辑;
- 标签具有很好的可移植性、可维护性和可重用性;
- 避免了对Scriptlet(小脚本)的使用(很多公司的项目开发都不允许在JSP中书写小脚本)
16、说一下表达式语言(EL)的隐式对象及其作用。
EL的隐式对象包括:pageContext、initParam(访问上下文参数)、param(访问请求参数)、paramValues、header(访问请求头)、headerValues、cookie(访问cookie)、applicationScope(访问application作用域)、sessionScope(访问session作用域)、requestScope(访问request作用域)、pageScope(访问page作用域)。
用法如下所示:
${pageContext.request.method}
${pageContext["request"]["method"]}
${pageContext.request["method"]}
${pageContext["request"].method}
${initParam.defaultEncoding}
${header["accept-language"]}
${headerValues["accept-language"][0]}
${cookie.jsessionid.value}
${sessionScope.loginUser.username}
补充:表达式语言的.和[]运算作用是一致的,唯一的差别在于如果访问的属性名不符合Java标识符命名规则,例如上面的accept-language就不是一个有效的Java标识符,那么这时候就只能用[]运算符而不能使用.运算符获取它的值
17、JSP中的静态包含和动态包含有什么区别?
静态包含是通过JSP的include指令包含页面,动态包含是通过JSP标准动作<jsp:forward>包含页面。静态包含是编译时包含,如果包含的页面不存在则会产生编译错误,而且两个页面的"contentType"属性应保持一致,因为两个页面会合二为一,只产生一个class文件,因此被包含页面发生的变动再包含它的页面更新前不会得到更新。动态包含是运行时包含,可以向被包含的页面传递参数,包含页面和被包含页面是独立的,会编译出两个class文件,如果被包含的页面不存在,不会产生编译错误,也不影响页面其他部分的执行。代码如下所示:
<%-- 静态包含 --%>
<%@ include file="..." %>
<%-- 动态包含 --%>
<jsp:include page="...">
<jsp:param name="..." value="..." />
</jsp:include>
18、Servlet中如何获取用户提交的查询参数或表单数据?
可以通过请求对象(HttpServletRequest)的getParameter()方法通过参数名获得参数值。如果有包含多个值的参数(例如复选框),可以通过请求对象的getParameterValues()方法获得。当然也可以通过请求对象的getParameterMap()获得一个参数名和参数值的映射(Map)。
19、Servlet中如何获取用户配置的初始化参数以及服务器上下文参数?
可以通过重写Servlet接口的init(ServletConfig)方法并通过ServletConfig对象的getInitParameter()方法来获取Servlet的初始化参数。
可以通过ServletConfig对象的getServletContext()方法获取ServletContext对象,并通过该对象的getInitParameter()方法来获取服务器上下文参数。
20、如何设置请求的编码以及响应内容的类型?
通过请求对象(ServletRequest)的setCharacterEncoding(String)方法可以设置请求的编码,其实要彻底解决乱码问题就应该让页面、服务器、请求和响应、Java程序都使用统一的编码,最好的选择当然是UTF-8;通过响应对象(ServletResponse)的setContentType(String)方法可以设置响应内容的类型,当然也可以通过HttpServletResponsed对象的setHeader(String, String)方法来设置。
21、解释一下网络应用的模式及其特点。
典型的网络应用模式大致有三类:B/S、C/S、P2P。其中B代表浏览器(Browser)、C代表客户端(Client)、S代表服务器(Server),P2P是对等模式,不区分客户端和服务器。
B/S应用模式中可以视为特殊的C/S应用模式,只是将C/S应用模式中的特殊的客户端换成了浏览器,因为几乎所有的系统上都有浏览器,那么只要打开浏览器就可以使用应用,没有安装、配置、升级客户端所带来的各种开销。
P2P应用模式中,成千上万台彼此连接的计算机都处于对等的地位,整个网络一般来说不依赖专用的集中服务器。网络中的每一台计算机既能充当网络服务的请求者,又对其它计算机的请求作出响应,提供资源和服务。通常这些资源和服务包括:信息的共享和交换、计算资源(如CPU的共享)、存储共享(如缓存和磁盘空间的使用)等,这种应用模式最大的阻力安全性、版本等问题,目前有很多应用都混合使用了多种应用模型,最常见的网络视频应用,它几乎把三种模式都用上了。
22、http协议?
(应用层的协议)支持客户/服务器模式,简单快速(发送请求时只需传送请求方法和路径),灵活(允许任意类型的数据对象),无连接性(每次连接只处理一个请求,处理完即断开,节省传输时间),无状态性(对事物处理没有记忆能力,后续处理需要重传)
23、http1.0和http1.1和http2.0区别?
1)1.0需要keep-live参数来建立一个长连接
2)1.1默认支持长连接,可以用一个长连接来发多个请求;1.1支持只发送header信息,服务端响应100后客户端再把body信息发送服务器,如果返回401客户端可以不用再发送body了,节约宽带;
3)2.0使用了多路复用的技术,使得同一个连接并发处理多个请求,处理的请求数量非常可观;1.1不支持header数据的压缩,2.0支持;2.0还支持数据推送,客户端请求的时候服务端可以顺便把客户端需要的比如静态资源一起推送到客户端,方便客户端使用
24、TCP/IP协议?
(4层:网络接口层,互联网层,传输层,应用层),针对因特网的通讯协议
25、URL和URI的区别?
前者是统一资源定位符(是个地址,可以访问到,也是一种URI),后者是统一资源标识符(只是一个名称)
26、alert();中怎么控制换行?
添加 “ \n ” 即可实现换行,有些浏览器则可能添加 “ \r\n ”,注意前后空格
27、<div><span>1</span><span>2</span><span>3</span></div>,如何获取第二个span的值?
1)使用索引选择器:$('div span:eq(1)').val(); //选择父元素为div元素下的最先出现的span元素(索引从0开始)
2)使用子元素选择器:$('div span:nth-child(2)').val(); //选择父元素为div元素下的第二个子元素,且该子元素是span元素(索引从1开始)
28、用js或者jquery获取页面上name="a" 或者 id="b" <input>输入框的值?
$("input[name='a']").val();
$("#b").val();
29、请使用jQuery将页面上的所有元素边框设置为2px宽的虚线?
$("*").css("border", "2px dotted red");
30、如何用jQuery禁用浏览器的后退按钮?
//谷歌浏览器方法,其他浏览器没试过
$(function(){
if (window.history && window.history.pushState) {
$(window).on('popstate', function () {
window.history.pushState('forward', null, '');
window.history.forward(1);
});
}
window.history.pushState('forward', null, '');
window.history.forward(1);
})
31、说几个jquery种常用的方法?
1)选择器(定位元素方法)方法:$("各种类型选择器")
2)筛选方法:$("xxx").find()等
3)对DOM元素的增、删、改方法:如append/remove/html/clone等
4)对DOM元素属性的增、删、改方法:如attr/css/val等方法
5)对集合的处理方法:如json/each等方法
6)对事件的绑定方法:如click/on/bind/live/toggle等方法
7)其它常用方法:如ajax等
32、ajax是如何传递数据的?他是同步的还是异步的?怎么实现同步?
1)人们通常认为AJAX是异步的,实际上并非如此,AJAX是避免页面在获取数据后刷新的一种技术,至于等待服务器响应的方式是同步还是异步,需要开发人员结合业务需求进行配置(虽然通常是异步的)。
2)“同步”等待响应与“异步”等待响应的区别:“同步”意味着一旦请求发出,任何后续的JavaScript代码不会再执行,“异步”则是当请求发出后,后续的JavaScript代码会继续执行,当请求成功后,会调用相应的回调函数。
我们是要获取数据还是存储数据? —— 表现为请求方式是“GET”还是“POST”
向哪里发出请求? —— 即相应的API地址
以何种方式等待相应? —— 有“同步”和“异步”两种选择
33、mvc的各个部分都有哪些技术实现?如何实现?
Model 代表的是应用的业务逻辑(通过JavaBean,EJB组件实现),
View 是应用的表示面(由JSP页面产生),
Controller 是提供应用的处理过程控制(一般是一个Servlet),
通过这种设计模型把应用逻辑,处理过程和显示逻辑分成不同的组件实现。这些组件可以进行交互和重用。