部分参考html
http://www.importnew.com/22083.html前端
面向对象的四个特征java
抽象,封装,继承,多态ajax
抽象:能够说他是把一类事务的共同特征总结出构造工程包括数据抽象和行为抽象,抽象只关心对象有哪些属性和行为正则表达式
封装:封装也就是说把客观的事务分装成抽象的类,而且类只让本身可信的类进行访问对不可信的类进行信息隐藏算法
继承:只一个类的所用功能,不须要去从新编写的状况下对这些功能进行扩展,经过继承建立的类为子类,被继承的类为父类,继承也就是从通常到特殊的过程。sql
多态:简单的来讲一样的对象引用一样的方法却作了不一样的事情数据库
生活中多态的例子编程
打印机 打印机又能够分为彩色打印机和黑白打印机,那么他们都是打印机可是实现的功能不同json
多态的体现形式
接口和接口的实现 类和类的继承 重写 重载
Java的基本数据类型
Byte,Shot,int,long,float,double,char,boolean
String属于类类型 被Final修饰String类不能够被继承。
int 和 Integer 有什么区别?
int 是基本类型32位长度的整数
Integer 是类类型,是int的封装类
int和Integer之间能够经过自动装箱 自动拆箱 互相转换
GET与POST区别
GET和POST都属于HTTP的交互协议
传值方面来讲:GET传递消息时会将咱们的数据按照明文的形式去添加到URL地址中 GET方式提交的话数据信息会被浏览器缓存,而POST是将数据放在HTTP的消息体中。正由于这样咱们的POST的安全性能就要高于GET
GET传输量小通常都会受限制,而POST传输量通常不受限制,但从执行效率上来讲GET效率会高于POST
String StringBuffer StringBuilder区别
String是个常量因此对于每次+=赋值都会产生一个新的对象,StringBuffer和StringBuilder是都是可变的,当进行字符串拼接时都会采用Append方法,在原来的基础上进行追加因此从性能上来讲比String要好。
String适合少许的字符串进行操做
StringBuffer 适合多线程下对字符缓存区下对大量字符串进行操做
StringBuilder 适合单线程下对字符缓存区下对大量字符串进行操做
HashMap与Hashtable
HashMap能够看作HashTable的一个轻量级的实现HashMap和HashTable都是Map下的一个接口区别在于HashMap是非线程安全的因此他容许键值为空而HashTable是线程安全的因此他不容许键值为空,从效率上来讲HashMap的执行效率高于HashTable。HashTable继承于Dictionary,而HashMap是JAVA2引进来的一个Map接口的实现。Hashtable的方法是被Synchronized修饰的,而HashMap不是,因此多个线程访问Hashtable时,不须要本身为它的方法实现同步,而HashMap 就必须为之提供外同(Collections.synchronizedMap)。
ConcurrentHashMap固然能够代替HashTable,可是HashTable提供更强的线程安全性。
HashMap原理实现
HashMap其实是一个数组和链表的结合体。
HashMap 在底层将 key-value 当成一个总体进行处理,这个总体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存全部的 key-value 对,当须要存储一个 Entry 对象时,会根据 hash 算法来决定其在数组中的存储位置,在根据 equals 方法决定其在该数组位置上的链表中的存储位置;当须要取出一个Entry 时,也会根据 hash 算法找到其在数组中的存储位置,再根据 equals 方法从该位置上的链表中取出该Entry。
GET操做的原理就比较简单,只须要根据key
的hashcode
算出元素在数组中的下标,以后遍历Entry
对象链表,直到找到元素为止。
构造器是否可以被重写?
答:构造器不可以被继承,所以不能被重写,但能够被重载。
解释堆栈
栈里面通常存放的变量,对象的引用,而堆里面存放的是new出来的对象也就是对象的实例,还有构造器都是放在堆中。栈空间操做起来最快可是栈很小,那么一般存放对象的堆空间理论上整个内存没有被其余的进程使用的空间或者是硬盘上的虚拟机内存均可以当作堆空间使用
堆会自动增长大小的,因此不须要指定大小,可是存取相对较慢
栈是固定大小的,而且是FILO 先入后出的顺序,而且存取速度比较快
进程与线程
进程是具备必定独立功能的程序,能够说他是一个有关于某个集合上的一次运动,是操做系统进行资源分配和调度的一个独立单位,线程能够说是进程的一个实体,一个进程能够拥有多个线程,是比进程更小的可以去独立运行的基本单位。进程在执行时一般都会拥有独立的内存单元。而线程之间能够共享数据和内存,那么对于多线程编程可以给用户带来更好的体验,可是并非线程越多就越好,由于线程之间的切换可能会占用大量的CPU的时间。
脏读,不可重复读,幻读
脏读:A事务读取B事务还没有提交数据并在此基础上进行操做,而B事务执行回滚,那么A事务读取到的数据就是脏数据
不可重复读:事务A从新读取到过的数据,发现该数据已经被另外一个事务B修改过了
幻读:事务A从新执行一个查询,返回一系列符合条件的查询的行,发现其中插入的数据被事务B提交的行
JVM加载Class文件的原理
Java中的类是有Java虚拟机中的类加载器和他的子类来实现的,Java的类加载器是Java的很重要的一个很重要的运行时组件,他负责在运行时查找和装入类文件中的类,因为Java的跨平台性编译后的Java源文件并非一个能够直接运行的程序,而是多个类文件,那么当咱们的Java的程序须要某个类时,Java的虚拟机就要确保这个类被加载,链接,而且初始化过。类加载是把类文件的数据读取到内存中,Java虚拟机一般会去建立一个字节数组来去读取类文件,而后去产生对应的类对象,这时类还不可用。当类加载以后就会进入链接阶段,这一阶段包括验证,准备和解析,最后虚拟机会对类进行初始化
类的加载是由类加载器完成的,类加载器包括:根加载器,扩展加载器,系统自带的加载器和用户自定义的加载器,JAVA2开始那么就采用了父类委托的机制(PDM),PDM可以更好的保证Java的安全性类加载器首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。
数据类型转换
字符串互转基本数据类型
调用parseXXX(String)或者是ValueOf(String)便可返回相应的基本类型
抽象类和接口有什么异同abstract / interface
抽象类和接口都不可以去被实例化,可是能够定义接口的类型的引用,一个类若是继承了抽象类和接口即必须都要去把他们的抽象方法所有实现.不然这个类必须继续声明为抽象类,接口比抽象类更加的抽象,由于抽象类中能够定义构造器,能够有抽象的方法,能够是Private,默认,protected,public,而接口中的成员都是public,接口中定义的成员变量实际上都是常量,有抽象方法的类必须声明为抽象类,而抽象类未必有抽象方法。
重载和重写的区别,重载的方法可否根据返回类型的区分
方法的重载和重写都是实现多态的方式,区别在于重载实现的是编译时多态性,然后者实现的是运行时的多态性,重载发生同一个类中,同名的方法若是有不一样的参数列表则视为重载,重写发生在子类与父类之间,重写要求子类被重写方法与父类有相同的返回类型,子类比父类重写方法更好的访问,不能比父类重写方法声明更多的异常,重载对返回类型没有特殊的要求。
Java中会存在内存泄漏吗?
理论上来讲Java有GC的机制不会存在内存泄漏的问题,但在实际开发中可能会达到一种无用但可达的现象,这些对象不会被GC回收,所以也会致使内存泄漏,例如Hibernate的session缓存中对象属于持久化状态,那么垃圾回收器不会去回收这些对象,然而这些对象就会存在无用的垃圾对象,若是不及时的关闭或者是清空,就可能致使内存泄漏。
GC是垃圾回收的意思,Java提供了自动回收的机制能够自动的监测对象是否超过做用域历来达到内存回收的效果。System.gc();
JSP9大隐式做用域对象
request:封装客户端的请求,包括GET/POST请求参数
response:封装服务器对客户端的一个响应;
pageContext:经过该对象能够获取其余对象
session:封装用户会话对象
application:封装服务器的运行环境
out:输出服务器响应的输出流的对象
config:WEB应用的配置对象
Page:JSP页面自己
Exception:错误异常对象
JSP四大做用域
包括 Page,Request,Application,Session
做用域从大到小application--request--session--page
application全局做用域范围,session会话做用域,request请求做用域,page一个JSP页面
ForWard和Redirect区别
Forward是容器中的控制权的转向,是服务器请求资源,服务器之间访问目标地址URL,把那个响应的URL内容读取出来而后再发送给浏览器,浏览器不知道这个地址从哪里来因此地址仍是原来的那个地址,Redirect是服务器端根据逻辑发送一个状态码,告诉浏览器去请求那个地址,因此浏览器会去看到那个请求地址的连接地址,很明显redirect没法访问到服务器保护起来的资源,可是能够从一个网站转跳到另外一个网站。可是我认为forward更高效一点,由于经过调用getRequestDispatch()方法得到这样的话有助于隐藏实际的地址,那么在有些状况下好比须要访问一个其余服务器上的资源就必须使用重定向。
定义文档有几种形式?本质区别在哪里?解析XML文档有哪几种方式
XML文档定义为DTD和Schema两种形式,均可以去对XML语法进行约束,其本质上的区别在于Schema自己也是XML文件,能够被XML解析,并且能够为XML承载的数据定义类型,约束的能力比DTD大一些。
对XML主要有DOM,SAX,DOM解析方式必须在解析以前把整个文档都装入内存中适合对XML随机访问,SAX是事件驱动型的XML解析方式,SAX是按照顺序去读取,不须要一次性所有加载这个文件处理的方式会更加灵活一些
XML主要做用
XML主要做用有两个方面:数据交互和信息配置,在作数据交互时,XML将数据用标签组装起来,而后压缩打包加密后经过网络传输传给接收者,接收者解密后再从XML文件还原相关的配置信息。不过如今被JSON代替,固然目前不少软件仍是在使用XML,咱们在作项目的时候也会将配置信息做为硬代码写入在XML中
JSON一种轻量级的交互格式,他有助于建立一种自描述,独立的,以轻的方式呈现交互数据,容易转换成JavaScript(脚本语言)
XML和JSON相同点
都是数据传输的载体而且具备垮平台语言的特性,区别在于XML的传输量比JSON要大。
实现会话跟踪技术
因为HTTP协议自己是无状态的,服务器为了区分不一样的用户,就须要对用户的会话进行跟踪,简单的说为了用户进行登记,为用户分配一个惟一的ID,那么用户下一次用户在请求中就会包含此ID,服务器就能够去判断究竟是哪个用户
4种方式 cookie,session,Url重写,设置隐藏域的表单
URL重写:在URL中去添加用户会话的信息做为请求参数,或者是将惟一的会话ID添加到URL结尾以标识一个会话
设置隐藏域的表单:将和会话跟踪相关的字段添加到表单中,这些信息不会在浏览器中显示可是在提交表单的时候会提交给服务器
cookie:cookie有两种会话cookie和持久化cookie,会话cookie的生命周期是和浏览器是一致的,浏览器关闭了那么cookie中存储的信息也就消失了,持久化cookie是将信息存储到临时文件夹中或者是硬盘中而且能够设置一个保存的时间,当用户与服务器创建一次链接会话后,会话ID的信息就会被记录下来,那就意味着只要时间没有超时那么这个会话ID又会提交给服务器让服务器识别身份。那么cookie对于一些敏感的信息就不适合保存。cookie的容量有限一个cookie大概可以存放4k左右。
session:session与三种方式不一样,session会把用户的信息存储到到服务器中,那么从安全的性能上来讲,session安全级别很是的高,可是不能存储过多内容,那么存储过的信息就会势必影响服务器的性能。session能够经过调用getSession的方法获取session的值经过session的setAttribute方法能够将一个值放在session中,同时传入属性名既能够获取到保存在session中内容。
final finally finalize区别
- final:修饰符(关键字)有三种用法:若是一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,所以它和abstract是反义词。将变量声明为final,能够保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在之后的引用中只能读取不可修改。被声明为final的方法也一样只能使用,不能在子类中被重写。
- finally:一般放在try…catch…的后面构造老是执行代码块,这就意味着程序不管正常执行仍是发生异常,这里的代码只要JVM不关闭都能执行,能够将释放外部资源的代码写在finally块中。
- finalize:Object类中定义的方法,Java中容许使用finalize()方法在垃圾收集器将对象从内存中清除出去以前作必要的清理工做。这个方法是由垃圾收集器在销毁对象时调用的,经过重写finalize()方法能够整理系统资源或者执行其余清理工做。
List,Set,Collection,Collections
List,Set都是Collection下的一个实现List是一个线性结构的容器而容许有重复的值 Set存储的零散的元素且不容许有重复元素 Collections一个封装了众多工具类包括对容器的排序,搜索以及线程安全
ArrayList 和Vector都是使用数组方式存储数据此数组元素数大于实际存储的数据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组元素移动等内存操做,因此索引数据快而插入数据慢,Vector中的方法因为添加了synchronized修饰,所以Vector是线程安全的容器,但性能上较ArrayList差,LinkedList使用双向链表实现存储按序号索引数据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。
Ajax-
Ajax全称是异步JavaScript及XML
工做原理:至关于在用户和服务器加了一个中间层,使用户操做与服务器之间异步化并非全部的用户请求到会发送到浏览器中去,好比数据验证和数据的一些处理都是有Ajax本身去处理,只有肯定从服务器调用数据时,才会去请求服务器读取新数据由Ajax引擎提交请求。Ajax并非一个新的语言而是一种基于标准化的并被普遍支持的技术,使用Ajax能使咱们的程序不用重载页面的状况下去与服务器进行交互。也可使咱们客户端和服务器之间使用异步传输的方式来进行HTTP的请求,请求少许信息减轻服务器压力,提高网站的性能。
ajax出现请求跨域错误问题,主要缘由是由于浏览器的“同源策略”
解决问题
JSONP,CORS,代理请求的方式
在JS中,咱们直接用XMLHttpRequest请求不一样域上的数据时,是不能够的。可是,在页面上引入不一样域上的js脚本文件倒是能够的,Jsonp正是利用这个特性来实现的。经过script标签引入一个js文件,这个js文件载入成功后会执行咱们在url参数中指定的函数,而且会把咱们须要的json数据做为参数传入。因此jsonp是须要服务器端的页面进行相应的配合的。
Error和Exception区别
Error是系统级别的错误和程序没必要须处理的错误,通常发生了就不可逆的错误,好比说内存泄漏,线程死亡,程序本身也不会去处理的错误,Exception表示须要去捕捉的或者须要程序去抛出异常的,是一种设计或者是思想上的错误,若是程序可以运行,那么就不会发生。Exception分为运行时异常和非运行时异常
运行时异常包括IndexOutofBoundsException NullPointerException,ArrayOutOfBoundsException,ClassNotFoundException
非运行时异常包括SQLException,IOException,FileNotFound
两种常见的回收机制:
1. 定时回收
每隔30分钟进行一次回收,这种机制的弊端是若是垃圾产生的比较快,有可能30分钟以内垃圾已经把内存占用光了,致使性能变慢
2. 当垃圾占到某个百分比的时候,进行回收
好比,当垃圾占到70%的时候,进行回收。 这种机制的弊端是,若是垃圾产生的频率很快,那么JVM就必须高频率的进行垃圾回收。 而在垃圾回收的过程当中, JVM会停顿下来,只作垃圾回收,而影响业务功能的正常运行。通常说来 JVM会采用两种机制结合的方式进行垃圾回收。
java中有几种类型的流?
Java中全部的流都是基于字节流,因此最基本的流是
输入输出字节流
InputStream
OutputStream
在字节流的基础上,封装了字符流
Reader
Writer
进一步,又封装了缓存流
BufferedReader
PrintWriter
以及数据流
DataInputStream
DataOutputStream
对象流
ObjectInputStream
ObjectOutputStream
sleep() 和 wait() 有什么区别?
sleep 是Thread类的方法,指的是当前线程暂停。
wait 是Object类的方法, 指的占用当前对象的线程临时释放对当前对象的占用,以使得其余线程有机会占用当前对象。 因此调用wait方法必定是在synchronized 中进行
死锁
死锁是指多个进程因竞争资源而形成的一种僵局,若无外力这些进程都将没法向前推动
Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现,Lock是代码层面的实现
Lock能够选择性的获取锁,若是一段时间获取不到,能够放弃。synchronized不行,会一根筋一直获取下去。 借助Lock的这个特性,就可以规避死锁,synchronized必须经过谨慎和良好的设计,才能减小死锁的发生。
synchronized在发生异常和同步块结束的时候,会自动释放锁。而Lock必须手动释放, 因此若是忘记了释放锁,同样会形成死锁。
Thread类的sleep()方法和对象的wait()方法均可以让线程暂停执行,它们有什么区别?
答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其余线程,可是对象的锁依然保持,所以休眠时间结束后会自动恢复
线程的sleep()方法和yield()方法有什么区别?
答:
① sleep()方法给其余线程运行机会时不考虑线程的优先级,所以会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操做系统CPU调度相关)具备更好的可移植性。
请说出与线程同步以及线程调度相关的方法。
答:
- wait():使一个线程处于等待(阻塞)状态,而且释放所持有的对象的锁;
- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
- notify():唤醒一个处于等待状态的线程,固然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM肯定唤醒哪一个线程,并且与优先级无关;
- notityAll():唤醒全部处于等待状态的线程,该方法并非将对象的锁给全部线程,而是让它们竞争,只有得到锁的线程才能进入就绪状态;
Java中如何实现序列化,有什么意义?
答:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操做时可能引起的问题
Java中有几种类型的流?
答:字节流和字符流。字节流继承于InputStream、OutputStream,字符流继承于Reader、Writer。在java.io 包中还有许多其余的流,主要是为了提升性能和使用方便。关于Java的I/O须要注意的有两点:一是两种对称性(输入和输出的对称性,字节和字符的对称性);二是两种设计模式(适配器模式和装潢模式)。另外Java中的流不一样于C#的是它只有一个维度一个方向。
Statement和PreparedStatement有什么区别?哪一个性能更好?
答:与Statement相比,①PreparedStatement接口表明预编译的语句,它主要的优点在于能够减小SQL的编译错误并增长SQL的安全性(减小SQL注射攻击的可能性);②PreparedStatement中的SQL语句是能够带参数的,避免了用字符串链接拼接SQL语句的麻烦和不安全;③当批量处理SQL或频繁执行相同的查询时,PreparedStatement有明显的性能上的优点,因为数据库能够将编译优化后的SQL语句缓存起来,下次执行相同结构的语句时就会很快(不用再次编译和生成执行计划)
什么是DAO模式?
答:DAO(Data Access Object)顾名思义是一个为数据库或其余持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各类数据访问操做。在实际的开发中,应该将全部对数据源的访问操做进行抽象化后封装在一个公共API中。用程序设计语言来讲,就是创建一个接口,接口中定义了此应用程序中将会用到的全部事务方法。在这个应用程序中,当须要和数据源进行交互的时候则使用这个接口,而且编写一个单独的类来实现这个接口,在逻辑上该类对应一个特定的数据存储。DAO模式实际上包含了两个模式,一是Data Accessor(数据访问器),二是Data Object(数据对象),前者要解决如何访问数据的问题,然后者要解决的是如何用对象封装数据。
事务的ACID是指什么?
答:
- 原子性(Atomic):事务中各项操做,要么全作要么全不作,任何一项操做的失败都会致使整个事务的失败;
- 一致性(Consistent):事务结束后系统状态是一致的;
- 隔离性(Isolated):并发执行的事务彼此没法看到对方的中间状态;
- 持久性(Durable):事务完成后所作的改动都会被持久化,即便发生灾难性的失败。经过日志和同步备份能够在故障发生后重建数据。
事务隔离级别和数据访问的并发性是对立的,事务隔离级别越高并发性就越差。因此要根据具体的应用来肯定合适的事务隔离级别,这个地方没有万能的原则。
为此数据库为用户提供了自动锁机制,只要用户指定会话的事务隔离级别,数据库就会经过分析SQL语句而后为事务访问的资源加上合适的锁
单例模式
public
class
Singleton {
private
Singleton(){}
private
static
Singleton instance =
new
Singleton();
public
static
Singleton getInstance(){
return
instance;
}
}
谈一下拦截器和过滤器的区别。
答:拦截器和过滤器均可以用来实现横切关注功能,其区别主要在于:
①拦截器是基于Java反射机制的,而过滤器是基于接口回调的。
②过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器。
③拦截器只能对Action请求起做用,而过滤器能够对全部请求起做用。
④拦截器能够访问Action上下文、值栈里的对象,而过滤器不能。
SessionFactory是线程安全的吗?Session是线程安全的吗,两个线程可以共享同一个Session吗?
答:SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,能够被多个线程并发访问。SessionFactory通常只会在启动的时候构建。对于应用程序,最好将SessionFactory经过单例的模式进行封装以便于访问。Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工做单元。Session是由SessionFactory建立的,在任务完成以后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库链接(也就是在须要的时候才会获取)。为了不建立太多的session,可使用ThreadLocal来取得当前的session,不管你调用多少次getCurrentSession()方法,返回的都是同一个session。
锁机制有什么用?简述Hibernate的悲观锁和乐观锁机制。
答:有些业务逻辑在执行过程当中每每须要保证数据访问的排他性,因而须要经过一些机制保证在此过程当中数据被锁住不会被外界修改,这就是所谓的锁机制。
Hibernate支持悲观锁和乐观锁两种锁机制。悲观锁,顾名思义,它悲观的认为在数据处理过程当中必定存在修改数据的并发事务(包括本系统的其余事务或来自外部系统的事务),因而将处理的数据设置为锁定状态。悲观锁必须依赖数据库自己的锁机制才能真正保证数据访问的排他性。乐观锁,顾名思义,对并发事务持乐观态度(认为对数据的并发操做不多发生),经过更加宽松的锁机制解决悲观锁排他的数据访问对系统性能形成的严重影响。最多见的乐观锁是经过数据版本标识来实现的,读取数据时得到数据的版本号,更新数据时将此版本号加1,而后和数据库表对应记录的当前版本号进行比较,若是提交的数据版本号大于数据库中此记录的当前版本号则更新数据,不然认为是过时数据。
你使用过的应用服务器优化技术有哪些?
答:
① 分布式缓存:缓存的本质就是内存中的哈希表,若是设计一个优质的哈希函数,那么理论上哈希表读写的渐近时间复杂度为O(1)。缓存主要用来存放那些读写比很高、变化不多的数据,这样应用程序读取数据时先到缓存中读取,若是没有或者数据已经失效再去访问数据库或文件系统,并根据拟定的规则将数据写入缓存。对网站数据的访问也符合二八定律(Pareto分布,幂律分布),即80%的访问都集中在20%的数据上,若是可以将这20%的数据缓存起来,那么系统的性能将获得显著的改善。固然,使用缓存须要解决如下几个问题:
- 频繁修改的数据;
- 数据不一致与脏读;
- 缓存雪崩(能够采用分布式缓存服务器集群加以解决,memcached是普遍采用的解决方案);
- 缓存预热;
- 缓存穿透(恶意持续请求不存在的数据)。
② 异步操做:可使用消息队列将调用异步化,经过异步处理将短期高并发产生的事件消息存储在消息队列中,从而起到削峰做用。电商网站在进行促销活动时,能够将用户的订单请求存入消息队列,这样能够抵御大量的并发订单请求对系统和数据库的冲击。目前,绝大多数的电商网站即使不进行促销活动,订单系统都采用了消息队列来处理。
③ 使用集群。
④ 代码优化:
- 多线程:基于Java的Web开发基本上都经过多线程的方式响应用户的并发请求,使用多线程技术在编程上要解决线程安全问题,主要能够考虑如下几个方面:A. 将对象设计为无状态对象(这和面向对象的编程观点是矛盾的,在面向对象的世界中被视为不良设计),这样就不会存在并发访问时对象状态不一致的问题。B. 在方法内部建立对象,这样对象由进入方法的线程建立,不会出现多个线程访问同一对象的问题。使用ThreadLocal将对象与线程绑定也是很好的作法,这一点在前面已经探讨过了。C. 对资源进行并发访问时应当使用合理的锁机制。
- 非阻塞I/O: 使用单线程和非阻塞I/O是目前公认的比多线程的方式更能充分发挥服务器性能的应用模式,基于Node.js构建的服务器就采用了这样的方式。Java在JDK 1.4中就引入了NIO(Non-blocking I/O),在Servlet 3规范中又引入了异步Servlet的概念,这些都为在服务器端采用非阻塞I/O提供了必要的基础。
- 资源复用:资源复用主要有两种方式,一是单例,二是对象池,咱们使用的数据库链接池、线程池都是对象池化技术,这是典型的用空间换取时间的策略,另外一方面也实现对资源的复用,从而避免了没必要要的建立和释放资源所带来的开销。
16八、什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?
答:
- XSS(Cross Site Script,跨站脚本攻击)是向网页中注入恶意脚本在用户浏览网页时在用户浏览器中执行恶意脚本的攻击方式。跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意脚本的连接以达到攻击的目标,目前有不少攻击者利用论坛、微博发布含有恶意脚本的URL就属于这种方式)和持久型攻击(将恶意脚本提交到被攻击网站的数据库中,用户浏览网页时,恶意脚本从数据库中被加载到页面执行,QQ邮箱的早期版本就曾经被利用做为持久型跨站脚本攻击的平台)。XSS虽然不是什么新鲜玩意,可是攻击的手法却不断翻新,防范XSS主要有两方面:消毒(对危险字符进行转义)和HttpOnly(防范XSS攻击者窃取Cookie数据)。
- SQL注入攻击是注入攻击最多见的形式(此外还有OS注入攻击(Struts 2的高危漏洞就是经过OGNL实施OS注入攻击致使的)),当服务器使用请求参数构造SQL语句时,恶意的SQL被嵌入到SQL中交给数据库执行。SQL注入攻击须要攻击者对数据库结构有所了解才能进行,攻击者想要得到表结构有多种方式:(1)若是使用开源系统搭建网站,数据库结构也是公开的(目前有不少现成的系统能够直接搭建论坛,电商网站,虽然方便快捷可是风险是必需要认真评估的);(2)错误回显(若是将服务器的错误信息直接显示在页面上,攻击者能够经过非法参数引起页面错误从而经过错误信息了解数据库结构,Web应用应当设置友好的错误页,一方面符合最小惊讶原则,一方面屏蔽掉可能给系统带来危险的错误回显信息);(3)盲注。防范SQL注入攻击也能够采用消毒的方式,经过正则表达式对请求参数进行验证,此外,参数绑定也是很好的手段,这样恶意的SQL会被当作SQL的参数而不是命令被执行,JDBC中的PreparedStatement就是支持参数绑定的语句对象,从性能和安全性上都明显优于Statement。
- CSRF攻击(Cross Site Request Forgery,跨站请求伪造)是攻击者经过跨站请求,以合法的用户身份进行非法操做(如转帐或发帖等)。CSRF的原理是利用浏览器的Cookie或服务器的Session,盗取用户身份,其原理以下图所示。防范CSRF的主要手段是识别请求者的身份,主要有如下几种方式:(1)在表单中添加令牌(token);(2)验证码;(3)检查请求头中的Referer(前面提到防图片盗连接也是用的这种方式)。令牌和验证都具备一次消费性的特征,所以在原理上一致的,可是验证码是一种糟糕的用户体验,不是必要的状况下不要轻易使用验证码,目前不少网站的作法是若是在短期内屡次提交一个表单未得到成功后才要求提供验证码,这样会得到较好的用户体验。
什么是ORM?
答:对象关系映射(Object-Relational Mapping,简称ORM)是一种为了解决程序的面向对象模型与数据库的关系模型互不匹配问题的技术;简单的说,ORM是经过使用描述对象和数据库之间映射的元数据(在Java中能够用XML或者是注解),将程序中的对象自动持久化到关系数据库中或者将关系数据库表中的行转换成Java对象,其本质上就是将数据从一种形式转换到另一种形式。
MyBatis的一级缓存和二级缓存
Mybatis首先去缓存中查询结果集,若是没有则查询数据库,若是有则从缓存取出返回结果集就不走数据库。Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
Mybatis的二级缓存即查询缓存,它的做用域是一个mapper的namespace,即在同一个namespace中查询sql能够从缓存中获取数据。二级缓存是能够跨SqlSession的。
什么是Spring
Spring是一个开源的,轻量级的应用开发的框架,其目的是用于简化企业级应用的开发,减小侵入。Spring的核心是IOC容器,DI依赖注入。Spring发明的主要目的可以使咱们使JavaEE更容易使用
Spring工做流程(异步为例)
整个请求从HTTP开始,HTTP找到前端的总控制器DispatchServlet,而后根据DispatchServlet找到HandlerMapping处理器映射(HandlerMapping主要负责请求和处理对应的关系)而后找到对应的Controller处理器返回数据对象@ResponseBody使用Gson/Jackson工具包,将对象转换成JSON字符串并响应输出JSON字符串,由Ajax回调函数,最后显示给用户
Spring功能的主要作用
SpringIOC
能够这样说IOC并非一种技术,能够绝不犹豫的说他是一种编程的思想,一个重要的面向对象的编程法则。那么没有使用Spring以前咱们一般在类中建立依赖的对象,这样的话不利于咱们Java编程的思想,Java编程在必定程度上追求的是“高内聚,低耦合”,那么在类中自主的建立依赖对象很明显的是不知足的,SpringIOC出现就解决了这一问题,咱们就能够把建立和查找的权限都交给了咱们的IOC容器进行注入,那么类和类之间的话减小了依赖关系,更好为咱们提供了测试环境,也能够方便的为咱们对代码的维护和可扩展性。那么对于整个程序来讲由于有了SpringIOC整个体系都显得很是的灵活,IOC对于咱们编程来讲最大的改变不是在技术上而是在思想上。程序原本为主须要什么内容主动去获取。那么如今有了IOC/DI,咱们的程序就变得被动起来,须要去等待咱们的IOC/DI去建立而且注入程序自己须要的资源
IOC的类型 基于特定的接口 基于SET方法 基于构造器
SpringAOP
SpringAOP面向切面编程,那么他的出现就是更好的帮助Java的OOP思想(面向对象编程)更好的补充和完善
那么AOP出现为何说是对OOP思想的完善和补充呢,OOP引入了封装,多态,继承等概念性的东西对象层次结构的东西,OOP容许你定义上下关系 而对于左右没可以很好的完善例如日志功能。日志代码每每水平地散布在全部对象层次中,而与它所散布到的对象的核心功能毫无关系。那么可能致使重复的代码增长不利于代码的重用性。也加深了各个模块之间的依赖,那么SpringAOP就利用了这一横切的技术解决了这一问题去剖开咱们对象的内部,而且把那些那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减小系统的重复代码,下降模块间的耦合度,并有利于将来的可操做性和可维护性。
Spring中Bean的做用域有哪些?
答:在Spring的早期版本中,仅有两个做用域:singleton和prototype,前者表示Bean以单例的方式存在;后者表示每次从容器中调用Bean时,都会返回一个新的实例,prototype一般翻译为原型。
你是如何理解”横切关注”这个概念的?
答:”横切关注”是会影响到整个应用程序的关注功能,它跟正常的业务逻辑是正交的,没有必然的联系,可是几乎全部的业务逻辑都会涉及到这些关注功能。一般,事务、日志、安全性等关注就是应用中的横切关注功能。
Spring支持的事务管理类型有哪些?你在项目中使用哪一种方式?
答:Spring支持编程式事务管理和声明式事务管理。许多Spring框架的用户选择声明式事务管理,由于这种方式和应用程序的关联较少,所以更加符合轻量级容器的概念。声明式事务管理要优于编程式事务管理,尽管在灵活性方面它弱于编程式事务管理,由于编程式事务容许你经过代码控制业务。
事务分为全局事务和局部事务。全局事务由应用服务器管理,须要底层服务器JTA支持(如WebLogic、WildFly等)。局部事务和底层采用的持久化方案有关,例如使用JDBC进行持久化时,须要使用Connetion对象来操做事务;而采用Hibernate进行持久化时,须要使用Session对象来操做事务。
大型网站在架构上应当考虑哪些问题?
答:
- 分层:分层是处理任何复杂系统最多见的手段之一,将系统横向切分红若干个层面,每一个层面只承担单一的职责,而后经过下层为上层提供的基础设施和服务以及上层对下层的调用来造成一个完整的复杂的系统。计算机网络的开放系统互联参考模型(OSI/RM)和Internet的TCP/IP模型都是分层结构,大型网站的软件系统也可使用分层的理念将其分为持久层(提供数据存储和访问服务)、业务层(处理业务逻辑,系统中最核心的部分)和表示层(系统交互、视图展现)。须要指出的是:(1)分层是逻辑上的划分,在物理上能够位于同一设备上也能够在不一样的设备上部署不一样的功能模块,这样可使用更多的计算资源来应对用户的并发访问;(2)层与层之间应当有清晰的边界,这样分层才有意义,才更利于软件的开发和维护。
- 分割:分割是对软件的纵向切分。咱们能够将大型网站的不一样功能和服务分割开,造成高内聚低耦合的功能模块(单元)。在设计初期能够作一个粗粒度的分割,将网站分割为若干个功能模块,后期还能够进一步对每一个模块进行细粒度的分割,这样一方面有助于软件的开发和维护,另外一方面有助于分布式的部署,提供网站的并发处理能力和功能的扩展。
- 分布式:除了上面提到的内容,网站的静态资源(JavaScript、CSS、图片等)也能够采用独立分布式部署并采用独立的域名,这样能够减轻应用服务器的负载压力,也使得浏览器对资源的加载更快。数据的存取也应该是分布式的,传统的商业级关系型数据库产品基本上都支持分布式部署,而新生的NoSQL产品几乎都是分布式的。固然,网站后台的业务处理也要使用分布式技术,例如查询索引的构建、数据分析等,这些业务计算规模庞大,可使用Hadoop以及MapReduce分布式计算框架来处理。
- 集群:集群使得有更多的服务器提供相同的服务,能够更好的提供对并发的支持。
- 缓存:所谓缓存就是用空间换取时间的技术,将数据尽量放在距离计算最近的位置。使用缓存是网站优化的第必定律。咱们一般说的CDN、反向代理、热点数据都是对缓存技术的使用。
- 异步:异步是实现软件实体之间解耦合的又一重要手段。异步架构是典型的生产者消费者模式,两者之间没有直接的调用关系,只要保持数据结构不变,彼此功能实现能够随意变化而不互相影响,这对网站的扩展很是有利。使用异步处理还能够提升系统可用性,加快网站的响应速度(用Ajax加载数据就是一种异步技术),同时还能够起到削峰做用(应对瞬时高并发)。";能推迟处理的都要推迟处理”是网站优化的第二定律,而异步是践行网站优化第二定律的重要手段。
- 冗余:各类服务器都要提供相应的冗余服务器以便在某台或某些服务器宕机时还能保证网站能够正常工做,同时也提供了灾难恢复的可能性。冗余是网站高可用性的重要保证。
你使用过的应用服务器优化技术有哪些?
答:
① 分布式缓存:缓存的本质就是内存中的哈希表,若是设计一个优质的哈希函数,那么理论上哈希表读写的渐近时间复杂度为O(1)。缓存主要用来存放那些读写比很高、变化不多的数据,这样应用程序读取数据时先到缓存中读取,若是没有或者数据已经失效再去访问数据库或文件系统,并根据拟定的规则将数据写入缓存。对网站数据的访问也符合二八定律(Pareto分布,幂律分布),即80%的访问都集中在20%的数据上,若是可以将这20%的数据缓存起来,那么系统的性能将获得显著的改善。固然,使用缓存须要解决如下几个问题:
- 频繁修改的数据;
- 数据不一致与脏读;
- 缓存雪崩(能够采用分布式缓存服务器集群加以解决,Redis是普遍采用的解决方案);
- 缓存预热;
- 缓存穿透(恶意持续请求不存在的数据)。
② 异步操做:可使用消息队列将调用异步化,经过异步处理将短期高并发产生的事件消息存储在消息队列中,从而起到削峰做用。电商网站在进行促销活动时,能够将用户的订单请求存入消息队列,这样能够抵御大量的并发订单请求对系统和数据库的冲击。目前,绝大多数的电商网站即使不进行促销活动,订单系统都采用了消息队列来处理。
③ 使用集群。
④ 代码优化:
- 多线程:基于Java的Web开发基本上都经过多线程的方式响应用户的并发请求,使用多线程技术在编程上要解决线程安全问题,主要能够考虑如下几个方面:A. 将对象设计为无状态对象(这和面向对象的编程观点是矛盾的,在面向对象的世界中被视为不良设计),这样就不会存在并发访问时对象状态不一致的问题。B. 在方法内部建立对象,这样对象由进入方法的线程建立,不会出现多个线程访问同一对象的问题。使用ThreadLocal将对象与线程绑定也是很好的作法,这一点在前面已经探讨过了。C. 对资源进行并发访问时应当使用合理的锁机制。
- 非阻塞I/O: 使用单线程和非阻塞I/O是目前公认的比多线程的方式更能充分发挥服务器性能的应用模式,基于Node.js构建的服务器就采用了这样的方式。Java在JDK 1.4中就引入了NIO(Non-blocking I/O),在Servlet 3规范中又引入了异步Servlet的概念,这些都为在服务器端采用非阻塞I/O提供了必要的基础。
- 资源复用:资源复用主要有两种方式,一是单例,二是对象池,咱们使用的数据库链接池、线程池都是对象池化技术,这是典型的用空间换取时间的策略,另外一方面也实现对资源的复用,从而避免了没必要要的建立和释放资源所带来的开销。
16八、什么是XSS攻击?什么是SQL注入攻击?什么是CSRF攻击?答:- XSS(Cross Site Script,跨站脚本攻击)是向网页中注入恶意脚本在用户浏览网页时在用户浏览器中执行恶意脚本的攻击方式。跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意脚本的连接以达到攻击的目标,目前有不少攻击者利用论坛、微博发布含有恶意脚本的URL就属于这种方式)和持久型攻击(将恶意脚本提交到被攻击网站的数据库中,用户浏览网页时,恶意脚本从数据库中被加载到页面执行,QQ邮箱的早期版本就曾经被利用做为持久型跨站脚本攻击的平台)。XSS虽然不是什么新鲜玩意,可是攻击的手法却不断翻新,防范XSS主要有两方面:消毒(对危险字符进行转义)和HttpOnly(防范XSS攻击者窃取Cookie数据)。- SQL注入攻击是注入攻击最多见的形式(此外还有OS注入攻击(Struts 2的高危漏洞就是经过OGNL实施OS注入攻击致使的)),当服务器使用请求参数构造SQL语句时,恶意的SQL被嵌入到SQL中交给数据库执行。SQL注入攻击须要攻击者对数据库结构有所了解才能进行,攻击者想要得到表结构有多种方式:(1)若是使用开源系统搭建网站,数据库结构也是公开的(目前有不少现成的系统能够直接搭建论坛,电商网站,虽然方便快捷可是风险是必需要认真评估的);(2)错误回显(若是将服务器的错误信息直接显示在页面上,攻击者能够经过非法参数引起页面错误从而经过错误信息了解数据库结构,Web应用应当设置友好的错误页,一方面符合最小惊讶原则,一方面屏蔽掉可能给系统带来危险的错误回显信息);(3)盲注。防范SQL注入攻击也能够采用消毒的方式,经过正则表达式对请求参数进行验证,此外,参数绑定也是很好的手段,这样恶意的SQL会被当作SQL的参数而不是命令被执行,JDBC中的PreparedStatement就是支持参数绑定的语句对象,从性能和安全性上都明显优于Statement。- CSRF攻击(Cross Site Request Forgery,跨站请求伪造)是攻击者经过跨站请求,以合法的用户身份进行非法操做(如转帐或发帖等)。CSRF的原理是利用浏览器的Cookie或服务器的Session,盗取用户身份,其原理以下图所示。防范CSRF的主要手段是识别请求者的身份,主要有如下几种方式:(1)在表单中添加令牌(token);(2)验证码;(3)检查请求头中的Referer(前面提到防图片盗连接也是用的这种方式)。令牌和验证都具备一次消费性的特征,所以在原理上一致的,可是验证码是一种糟糕的用户体验,不是必要的状况下不要轻易使用验证码,目前不少网站的作法是若是在短期内屡次提交一个表单未得到成功后才要求提供验证码,这样会得到较好的用户体验。