四种读取XML文件读取的办法

1.DOM生成和解析XML文档

为XML文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构。

优点:整个文档树在内存中,便于操作;支持删除,修改,重新排列等。

缺点: 把整个文档调入内存,存在很多无用的节点,浪费了时间和空间。

2.SAX为解决DOM

1、边读边解析,应用于大型XML文档

2、只支持读

3、访问效率低

4、顺序访问

3.DOM4J生成和解析XML文档(解析工具) 性能最好 SUM的JAXM也大量采用DOM4J

HIBERNATE采用DOM4J

虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,它通过DOM4J API和标准DOM接口具有并行访问功能。从2000下半年开始,它就一直处于开发之中。

为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。在添加灵活性、XPath集成和对大文档处理的目标时,DOM4J的目标与JDOM是一样的:针对Java开发者的易用性和直观操作。它还致力于成为比JDOM更完整的解决方案,实现在本质上处理所有Java/XML问题的目标。在完成该目标时,它比JDOM更少强调防止不正确的应用程序行为。DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.

4.JDOM

JDOM

优点:①是基于树的处理XML的Java API,把树加载在内存中

    ②没有向下兼容的限制,因此比DOM简单③速度快,缺陷少④具有SAX的JAVA规则

缺点:

 ①不能处理大于内存的文档②JDOM表示XML文档逻辑模型。不能保证每个字节真正变换。③针对实例文档不提供DTD与模式的任何实际模型。④不支持与DOM中相应遍历包。

最适合于:JDOM具有树的便利,也有SAX的JAVA规则。在需要平衡时使用

如何防止Sql注入

有两种办法

1.第一种消毒,通过正则匹配过滤请求数据中可能注入的SQL。

2.使用预编译手段preparedStatemengt。

DB第一范式,第二范式,第三范式

第一范式:没一列属性不可再分,没有多值属性

第二范式:在符合第一范式的基础上,存在主键

第三范式:在符合第二范式的基础上,非关键字独立于其他的非关键字,并且依赖关键字。不能存在传递依赖。

**public、protected、private、**默认权限

private:用于修饰类和方法,只允许该类访问。

默认:只允许在同一个类和同一个包中进行访问。

protected:用于修饰类和方法,允许该类和子类访问以及同一个包中访问。

public:用于修饰类和方法,允许该包下面和其他包的访问,即在全局范围都可以访问。

数据库事务

事务的特性:

原子性:事务是不可再分的;

一致性:事务的实行前后,数据库的状态保持一致;

隔离性:事务的并发访问,事务之间的执行互不干扰;

持久性:事务结束后数据永久保存在数据库中。

什么是脏读?

脏读就是一个事务读取了该数据并且对该数据做出了修改,另一个事务也读取了该修改后的数据但是前一个事务并没有提交,这是脏数据。

读取到保存在数据库内存中的数据。

什么是不可重复读?

一个事务:在同一个事务中读取同一数据,得到的内容不同。一个事务读取另外一个事务更新的数据,导致二次的查询的数据不一致。

什么是幻读?

幻读是当事务不独立发生的。比如一个事务删除了所有数据,另一个事务又插入了一条,那么第一个事务的用户会发现表中还没有修改的数据行。一个事务读取到另外一个事务提交的数据,导致查询的结果不一致的问题。

数据库的隔离级别:

Read uncommitted:未提交读:三中都有可能发生

Read committed :已提交读 避免脏读

Repeated read:重复读:避免脏读 不可重复读

Serializable:串行化读 都可以避免

WebService到底是什么

     一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术。

所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。

     所谓远程调用,就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,银联提供给商场的pos刷卡系统,商场的POS机转账调用的转账方法的代码其实是跑在银行服务器上。再比如,amazon,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以webservice服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,这样扩展了自己系统的市场占有率,往大的概念上吹,就是所谓的SOA应用。其实可以从多个角度来理解WebService,从表面上看,WebService就是一个应用程序向外界暴露出一个能通过Web进行调用的API,也就是说能用编程的方法通过Web来调用这个应用程序。我们把调用这个WebService的应用程序叫做客户端,而把提供这个WebService的应用程序叫做服务端。从深层次看,WebService是建立可互操作的分布式应用程序的新平台,是一个平台,是一套标准。它定义了应用程序如何在Web上实现互操作性,你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。

WebService平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,WebService平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。Web service平台必须提供一种标准来描述Web service,让客户可以得到足够的信息来调用这个Web service。最后,我们还必须有一种方法来对这个Web service进行远程调用,这种方法实际是一种远程过程调用协议(RPC)。为了达到互操作性,这种RPC协议还必须与平台和编程语言无关。

java中锁的优化

1.减少锁持有的时间,可以减少其它线程的等待时间,不能让一个线程一直控制着某个锁不释放,导致竞争加剧。

2.减少锁的粒度,合适的锁的代码块,可以减少竞争,控制锁的范围。

3.锁分离,将锁安功能划分,比如读写锁,读读不互斥,读写互斥,写写互斥,保证了线程的安全,提高了性能。比如阻塞队列中的take和put

4.锁粗化,如果对同一个锁不停的进行请求,同步和释放,这个消耗是非常的大的,所以适当的时候可以粗化。

5.锁消除,编译器可以帮助我们优化比如一些代码根本不需要锁。

虚拟机内的锁优化

1.偏向锁:偏向当前已经占有锁的线程,在无竞争的时候,之前获得锁的线程再次获得锁时,会判断是否偏向锁指向我,那么该线程将不用再次获得锁,直接进入同步块。

2.轻量级锁:偏向锁失败后,利用cas补救补救失败就会升级为重量级锁。

3.自旋锁:会做空操作,并且不停地尝试拿到这个锁。

java中一亿个数找前10000个最大的

先利用Hash法去重复,去除大量的之后 然后等量的分成100份 用小顶堆 来获得10000个,再把所有的1万个都合在一起就OK

java中线程的状态

java中的线程的状态有5种(新建、就绪、运行、阻塞、结束)

1.新建:创建后尚未启动的线程处于这种状态,新建出一个线程对象。

2.就绪状态:当针对该对象掉用了start()方法,该线程等待获取CPU的使用权

3.运行状态:在就绪状态下,获得了CPU处于运行状态。

4.阻塞:

等待阻塞:运行的线程执行wait方法,JVM会把该线程放入等待池

同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被其他的线程锁占用,则jvm会把该线程放入锁池中。

其他阻塞:运行的线程在执行sleep()方法或者join()方法时,或者发出IO请求,JVM会把线程置为阻塞状态。

5.结束:

也就是我们的死亡,表明线程结束。

Maven的生命周期

maven有三套相互独立的生命周期

1.clean生命周期

pre-clean,clean,post-clean

2.default生命周期 构建项目

1.validate:验证工程是否正确,所有需要的资源是否可用

2.compile:编译项目源代码

3.test:使用合适的单元框架来测试已编译的源代码。

4.Package:把已编译的代码打包成可发布的格式,jar。

4)Package:把已编译的代码打包成可发布的格式,比如jar。

5)integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。

6)verify:运行所有检查,验证包是否有效且达到质量标准。

7)install:把包安装到maven本地仓库,可以被其他工程作为依赖来使用。

8)Deploy:在集成或者发布环境下执行,将最终版本的包拷贝到远程的repository,使得其他的开发者或者工程可以共享。

site生命周期:建立和发布项目站点,phase如下

1)pre-site:生成项目站点之前需要完成的工作

2)site:生成项目站点文档

3)post-site:生成项目站点之后需要完成的工作

4)site-deploy:将项目站点发布到服务器

数据库索引

什么是索引?

(1)索引是对记录集多个字段进行排序的方法。

(2)也是一个数据结构,在一张表中为一个字段创建索引,将创建另外一个数据结构,包含字段的数值以及指向相关记录的指针,就可以对该数据结构进行二分法排序,当需要查询时就可以降低时间复杂度。

优势:快速存取数据;保证数据记录的唯一性;实现表和表之间的参照完整性;在使用order by group by子句进行数据的检索时,利用索引可以减少排序和分组的时间。

弊端:建立索引表也是会需要额外的空间。

索引的工作原理:

在对表中记录进行搜索时并不是对表中的数据进行全部的扫描遍历,而是查看在索引中定义的有序列,一旦在索引中找到了要查询的记录,就会得到一个指针,它会指向相应的表中数据所保存的位置。

索引的类型:

(1)聚集索引:数据页在物理上的有序的存储,数据页的物理顺序是按照聚集索引的顺序进行排列。在聚集索引中数据页聚集索引的叶子节点,数据页之间通过双向的链表形式相连接,实际的数据存储在叶节点中。

(2)非聚集索引:叶子节点不存放具体的数据页信息,只存放索引的键值。非聚集索引的叶子节点包含着指向具体数据的指针,数据页之间没有连接,是相对独立的。

(3)唯一索引:在整个表中仅仅会出现一次(主键约束/UNIQUE)

(4)非唯一索引:在提取数据时允许出现重复的值。

(5)单一索引和组合索引

[哪些情况下索引会失效?]

1.条件中有or但是前后没有同时使用索引

2.多列索引,不是使用前面部分

3.like查询是以%开头

4.字符类型应该加单引号 防止转换为int类型

数据库查询优化(Sql)

1、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

2、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

3、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

4、尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20

5、下面的查询也将导致全表扫描:(不能前置百分号)
select id from t where name like ‘�c%’
若要提高效率,可以考虑全文检索。

6、in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

7、如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num

8、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2

9、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)=’abc’–name以abc开头的id
select id from t where datediff(day,createdate,’2005-11-30′)=0–’2005-11-30′生成的id
应改为:
select id from t where name like ‘abc%’
select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′

10、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

11、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使 用,并且应尽可能的让字段顺序与索引顺序相一致。

12、不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(…)

13、很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)

14、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

15、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。

16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

17、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会 逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

18、尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

19、任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

20、尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

21、避免频繁创建和删除临时表,以减少系统表资源的消耗。

22、临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使 用导出表。

23、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

24、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

25、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

26、使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

27、与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

28、在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

29、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

30、尽量避免大事务操作,提高系统并发能力。查询sql语句中哪些比较慢

1.慢查询日志,一般设置查询超过两秒就记录

2.processlist:显示哪些线程正在运行.

3.explain关键字可以让我们更好的优化

数据库设计优化:

1.反范式设计,尽量是单表,可以高效利用索引

2.可以使用查询缓存,Mysql也会自带查询缓存

3.尽量查询通过搜索引擎查不通过我们

4.key,value数据库

锁的优化策略

1.读写分离,锁分离

2.减少锁持有时间,可以减少其他的锁的持有时间

3.以正确的顺序获得和释放锁

4.适当的锁的范围扩大或者缩小,控制锁的粒度

Spring Bean中作用域

singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例。

prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。

request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效。

session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效。

Global****session:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。

java中启定时任务

1.利用sleep特性//休眠

2.time和timerTask//定时器

3.ScheduledExecutorService service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);

//任务调度服务

操作系统如何进行分页调度

用户程序的地址空间被划分成若干固定大小的区域,称为“页”,相应地,内存空间分成若干个物理块,页和块的大小相等。可将用户程序的任一页放在内存的任一块中,实现了离散分配。

linux内核的三种主要调度策略:

1,SCHED_OTHER 分时调度策略,

2,SCHED_FIFO实时调度策略,先到先服务

3,SCHED_RR实时调度策略,时间片轮转

TCP和UDP相关

TCP通过什么方式提供可靠性:

1.超时重发,发出报文段要是没有收到及时的确认,会重发。

2.数据包的校验,也就是校验首部数据和。

3.对失序的数据重新排序

4.进行流量控制,防止缓冲区溢出

5.快重传和快恢复

6.TCP会将数据截断为合理的长度

TCP和UDP的区别:

1.UDP是无连接的,TCP必须三次握手建立连接

2.UDP是面向报文,没有拥塞控制,所以速度快,适合多媒体通信要求,比如及时聊天,支持一对一,一队多。多对一,多对多。

3.TCP只能是一对一的可靠性传输

TCP的RPC,在协议栈的下层,能够灵活的对字段进行定制,减少网络传输字节数,降低网络开销,提高性能,实现更大的吞吐量和并发数。但是实现代价高,底层复杂,难以得到开源社区的支持,难以实现跨平台

集群调优

1.load

load是被定义为特定时间间隔内运行队列中的平均线程数,uptime查看,一般load不大于3,我们认为负载是正常的,如果每个CPU的线程数大于5,表示负载就非常高了。

2.CPU利用率

查看cpu的消耗的情况命令:top | grep Cpu

查看磁盘的剩余空间命令:df -h

查看系统的内存的使用情况:free -m

心跳检测方法

1.使用ping命令

对于full gc导致不响应,网络攻击这种 ping展示不明确

2.使用curl

访问我们的自测地址

3.对不同的功能使用curl检测,在response中加入状态头,表示正常

可以计算qps通过28原则

innodb存储引擎通过预写事务日志的方式保障事务的原子性,也就是在写入数据之前,先将数据操作写入日志,这种成为预写日志

轻量级锁认为在程序运行过程中,绝大部分的锁,在整个同步周期内都是不存在竞争的,利用cas操作避免互斥开销。

偏向锁是jdk1.6中引入的一项优化,甚至可以省掉CAS操作,偏向锁偏向第一个获得他锁的线程,如果在接下来执行过程中,这个锁没有被其他线程获取,则持有偏向锁的线程永远不需要同步。

GC调优

查看GC日志,根据GC日志来优化

我们可以通过jps找到我们虚拟机正在运行的进程。参数 通过jps -help了解。

Jstat -gc 或者 -gcutil 查看堆使用情况-class 配合Jps得到进程

BTrace原理利用hotspot虚拟中的热替换,把代码动态的替换到java程序内,可在不需要重启的时候就可以排除问题

JConsole

我们也可以使用JConsole来分析这是一个图形化的,比较容易让我们操作

使用VisualVM 进行远程连接 使用JMX方式,也有修改tomcat的catalina就行了

内部类去访问外部变量,为什么需要加final?

题目有点问题,并不是所有的外部变量才加final,我们的内部类访问我们的成员变量就不需要加final,但是访问局部变量就必须要加final,因为方法(main方法)结束我们栈帧也就销毁了,但是我们内部类在堆中并没有被销毁,如果引用了成员变量,这时候被销毁了肯定是不行的,所以我们就需要成员变量设置为final,让其在方法(main方法)结束时不会被销毁。

泛型

泛型的作用:在我们没有泛型的时候,我们通过对Object的引用来对参数的任意化,任意化有个缺点就是要做显示的强制类型转换,强制转换有一个不好的地方是运行的时候才会报错,泛型的好处实在编译的时候检查类型安全,所以泛型的特点就是简单安全,泛型的原理是类型擦除,java的泛型是伪泛型,在编译期间,所有的泛型信息都会被擦除掉。在生成的java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器编译的时候去掉。比如List信息在编译后都是List。

nginx和apache的对比

1.nginx相对于apache来说

(1)轻量级占用的内存少;

(2)抗并发,nginx是异步非阻塞,apache是阻塞的,在高并发的情况下,nginx的性能优;

(3)高度模块化的设计,编写模块相对简单;

(4)社区活跃,各种高性能模块有。

适合场景:apache适合于动态的请求,而负载均衡和静态请求适合nginx,nginx采用的是epoll,并且有自己的一套sendfile系统,减少在内存中的赋值次数。

2.apache 相对于nginx 的优点:

(1)rewrite ,比nginx 的rewrite 强大 ;

(2)模块超多,基本想到的都可以找到 ;

(3)少bug ,nginx 的bug 相对较多 ;

(4)超稳定 。

** 线程****、进程的****共享和独立**

共享的部分:

1.进程代码段

2.进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯)

3.进程打开的文件描述符、

4.信号的处理器、

5.进程的当前目录

6.进程用户ID与进程组ID

线程独有的内容包括:

1.线程ID

2.寄存器组的值

3.线程的堆栈

4.错误返回码

5.线程的信号屏蔽码

最大的优势就是线程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,线程的性能优势就越明显。

第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在线程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

简单的说一下nginx的优点

1.作为高性能的web服务器:相比Apache,Nginx使用更少的资源,支持更多的并发连接,体现更高的效率,这点让Nginx受到虚拟主机提供商的欢迎。一个Nginx实例能够轻松支持高达5万并发。

2.作为负载均衡服务器:Nginx即可以在内部直接支持PHP,也可以支持作为HTTP代理服务器对外进行服务,独有的send files系统,减少文件复制次数

3.作为**邮件代理服务器:**也比Apache好很多。

4.Nginx安装简单,配置文件非常简洁。启动容易,7*24小时几乎不间断,可以进行热更新。

BIO

在BIO中读和写都是同步阻塞的,阻塞的时间取决于对方I/O线程的处理速度和网络的传输速度。本质上来讲,我们是无法保证生产环境的网络状况和对端的应用程序可以足够快,应用程序是不应该依赖对方的处理速度,它的可靠性就非常差。BIO就算用线程池实现,要是所有可用线程都被阻塞到故障点中,后续的所有I/O消息都将在队列中排队。

NIO

(1)提供了高速,面向块的I/O

(2)在NIO中所有数据都是用缓冲区来处理的,也就是使用我们的jvm中的direct memory(直接内存)。缓冲区是一个数组,但是缓冲区不仅仅是一个数组,缓冲区提供了对数据的结构化访问以及维护读写位置等信息。

(3)在NIO中channel****(通道也是特别重要的他是我们数据读写的通道,一般来说流比如inputStream和outputStream都是单向的,而通道是双向的,是全双工的。

(4)多路复用器Selector也是比较重要的,掌握它对于我们的NIO编程来说是比较重要的。多路复用器提供选择已经就绪的任务的能力。Selector会不断轮训注册在其上的Channel,如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,通过Selection Key可以获取就绪Channel的集合,进行后续的I/o操作。我们只需要一个线程就可以管理我们多个客户端。

垃圾收集器

1.Serial收集器

Serial收集器是JAVA虚拟机中最基本、历史最悠久的收集器,在JDK 1.3.1之前是JAVA虚拟机新生代收集的唯一选择。Serial收集器是一个单线程的收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个 CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束。Serial收集器到JDK1.7为止,它依然是JAVA虚拟机运行在Client模式下的默认新生代收集器。它也有着优于其他收集器的地方:简单而高 效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集 效率。在用户的桌面应用场景中,分配给虚拟机管理的内存一般来说不会很大,收集几十兆甚至一两百兆的新生代(仅仅是新生代使用的内存,桌面应用基本上不会 再大了),停顿时间完全可以控制在几十毫秒最多一百多毫秒以内,只要不是频繁发生,这点停顿是可以接受的。所以,Serial收集器对于运行在 Client模式下的虚拟机来说是一个很好的选择。

2. Parallel(并行)收集器

这是 JVM 的缺省收集器。就像它的名字,其最大的优点是使用多个线程来通过扫描并压缩堆。串行收集器在GC时会停止其他所有工作线程(stop-the- world),CPU利用率是最高的,所以适用于要求高吞吐量(throughput)的应用,但停顿时间(pause time)会比较长,所以对web应用来说就不适合,因为这意味着用户等待时间会加长。而并行收集器可以理解是多线程串行收集,在串行收集基础上采用多线 程方式进行GC,很好的弥补了串行收集的不足,可以大幅缩短停顿时间(如下图表示的停顿时长高度,并发比并行要短),因此对于空间不大的区域(如 young generation),采用并行收集器停顿时间很短,回收效率高,适合高频率执行。

3.CMS收集器

CMS(Concurrent Mark Sweep)收集器是基于“标记-清除”算法实现的,它使用多线程的算法去扫描堆(标记)并对发现的未使用的对象进行回收(清除)。整个过程分为6个步骤,包括:

初始标记(CMS initial mark)

并发标记(CMS concurrent mark)

并发预清理(CMS-concurrent-preclean)

重新标记(CMS remark)

并发清除(CMS concurrent sweep)

并发重置(CMS-concurrent-reset)

其中初始标记、重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一 般会比初始标记阶段稍长一些,但远比并发标记的时间短。其他动作都是并发的。需要注意的是,CMS收集器无法处理浮动垃圾(Floating Garbage),可能出现“Concurrent Mode Failure”失败而导致另一次Full GC的产生。由于CMS并发清理阶段用户线程还在运行着,伴随程序的运行自然还会有新的垃圾不断产生,这一部分垃圾出现在标记过程之后,CMS无法在本次 收集中处理掉它们,只好留待下一次GC时再将其清理掉。这一部分垃圾就称为“浮动垃圾”。也是由于在垃圾收集阶段用户线程还需要运行,即还需要预留足够的 内存空间给用户线程使用,因此CMS收集器不能像其他收集器那样等到老年代几乎完全被填满了再进行收集,需要预留一部分空间提供并发收集时的程序运作使 用。在默认设置下,CMS收集器在老年代使用了68%的空间后就会被激活,这是一个偏保守的设置,如果在应用中老年代增长不是太快,可以适当调高参数 -XX:CMSInitiatingOccupancyFraction的值来提高触发百分比,以便降低内存回收次数以获取更好的性能。要是CMS运行期 间预留的内存无法满足程序需要,就会出现一次“Concurrent Mode Failure”失败,这时候虚拟机将启动后备预案:临时启用Serial Old收集器来重新进行老年代的垃圾收集,这样停顿时间就很长了。所以说参数-XX:CMSInitiatingOccupancyFraction设置 得太高将会很容易导致大量“Concurrent Mode Failure”失败,性能反而降低。

try catch有return 在字节码中 可以看到会出现Goto跳转行数,跳转到finally中的return

Tomcat总结构

最外层的Server提供接口访问内部的Service服务。

Service服务的作用就是把Connector 在Connetor中监听端口和Container连接起来,方便我们的操纵控制。

在tomcat中生命周期是统一的由Lifecycle来管理的

在lifecycle中有两个方法比较重要start和stop,调用server的start会去调用自己下面所有service的start方法

Connector最重要的功能就是接受连接请求然后分配线程处理

在Container中 有4个级别Engine,Host,Context,warpper,这四个组件不是平行的,而是父子关系,Engine 包含 Host,Host 包含 Context,Context 包含 Wrapper。通常一个 Servlet class 对应一个 Wrapper,如果有多个 Servlet 就可以定义多个 Wrapper,如果有多个 Wrapper 就要定义一个更高的 Container 了,如 Context。在Host中有个value比较重要,类似于一个管道,和拦截器链差不多,我们在中间可以进行一些处理。

在Engine中只能添加子容器Host,不能添加父容器.Engine下可以配置多个虚拟主机Virtual Host,每个虚拟主机都有一个域名

当Engine获得一个请求时,它把该请求匹配到某个Host上,然后把该请求交给该Host来处理Engine有一个默认虚拟主机,当请求无法匹配到任何一个Host上的时候,将交给该默认Host来处理

一个Host就类似于一个虚拟主机,用来管理应用。代表一个Virtual Host,虚拟主机,每个虚拟主机和某个网络域名Domain Name相匹配

每个虚拟主机下都可以部署(deploy)一个或者多个Web App,每个Web App对应于一个Context,有一个Context path

当Host获得一个请求时,将把该请求匹配到某个Context上,然后把该请求交给该Context来处理

匹配的方法是“最长匹配”,所以一个path==""的Context将成为该Host的默认Context

所有无法和其它Context的路径名匹配的请求都将最终和该默认Context匹配。

Context 代表 Servlet 的 Context,它具备了 Servlet 运行的基本环境,理论上只要有 Context 就能运行 Servlet 了。简单的 Tomcat 可以没有 Engine 和 Host。

Context 最重要的功能就是管理它里面的 Servlet 实例,Servlet 实例在 Context 中是以 Wrapper 出现的,还有一点就是 Context 如何才能找到正确的 Servlet 来执行它呢?

一个Context对应于一个Web Application,一个Web Application由一个或者多个Servlet组成

Context在创建的时候将根据配置文件 C A T A L I N A H O M E / c o n f / w e b . x m l 和 CATALINA_HOME/conf/web.xml和 CATALINAH​OME/conf/web.xml和WEBAPP_HOME/WEB-INF/web.xml载入Servlet类

当Context获得请求时,将在自己的映射表(mapping table)中寻找相匹配的Servlet类

如果找到,则执行该类,获得请求的回应,并返回.

java后端研发经典面试题总结二相关推荐

  1. java后端研发经典面试题总结,为公司招兵买马

    垃圾回收算法 1.标记-清除算法 标记-清除算法是最基本的算法,和他的名字一样,分为两个步骤,一个步骤是标记需要回收的对象.在标记完成后统一回收被标记的对象.这个算法两个问题.一个是效率问题,标记和清 ...

  2. java后端研发经典面试题总结

    垃圾回收算法 1.标记-清除算法 标记-清除算法是最基本的算法,和他的名字一样,分为两个步骤,一个步骤是标记需要回收的对象.在标记完成后统一回收被标记的对象.这个算法两个问题.一个是效率问题,标记和清 ...

  3. Java后端工程师常见面试题

    以下是整理的Java后端工程师常见面试题,希望有助于找工作: 1,对Java集合框架的理解.ArrayList和LinkedList的区别和优缺点,以及使用场景.扩容因子了解吗?分别是多少. Java ...

  4. 前端经典面试题(二)-李游Leo-专题视频课程

    前端经典面试题(二)-80人已学习 课程介绍         在鱼龙混杂的前端行业中,面试一直是一门非常重要的课程,尤其是笔试题. 本课程精选了14道出现率颇高的经典的前端面试题,从浅入深的了解认知这 ...

  5. 字节跳动、美团java后端社招面试题:多线程+分布式+算法+数据库+JVM+微服务

    写在前面: 字节跳动是近几年发展特别迅速的互联网公司,凭借短视频平台[抖音]和自由创作平台[今日头条]等一系列以内容创造价值的应用异军突起,已经成为动摇BAT地位的一大狠角色. 同时,字节跳动公司也是 ...

  6. Web前端经典面试试题(二)

    上次由于时间有限只分享了一部分的前端面试题,所以本篇继续分享前端经典面试试题 一. 栈和队列的区别? 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的. 队列先进先出,栈先进后出. 栈 ...

  7. BAT Java面试笔试33题:JavaList、Java Map等经典面试题!答案汇总!

    JavaList面试题汇总 1.List集合:ArrayList.LinkedList.Vector等. 2.Vector是List接口下线程安全的集合. 3.List是有序的. 4.ArrayLis ...

  8. 阿里妈妈技术联盟Java后端研发五轮技术面总结

    2019年03月12日内推简历投递 2019年04月19日面完HR面 2019年04月30日收到录取意向书 部门:阿里集团-阿里妈妈事业群-阿里妈妈事业部-联盟业务 阿里一面(60min)(基础面) ...

  9. 软件测试技巧|软测经典面试题(二)

    背面试题是避免面试出现被问懵的现象出现最好的方式,昨天我们分享了第一期软测经典面试题,今天我们继续分享,还是老规矩建议收藏~~ 16.简述一下缺陷的生命周期? 提交->确认->分配-> ...

最新文章

  1. Python3学习笔记-面向对象
  2. Interview Q A 小明一家5口如何过桥
  3. Linux下服务器模型 【转载】
  4. html表格选择一行,vue + element table表格如何默认选中第一行
  5. 【问题记录】raise IndexError(‘index {} is out of range‘.format(idx)) index 0 is out of range
  6. html实现 页面禁止右键 禁止复制 禁止图片拖动 禁止复制和剪切
  7. Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法
  8. 【CodeForces - 761B】Dasha and friends (思维,模拟,构造)
  9. http协议知识msdn
  10. tomcat 后台 getshell
  11. ArcGIS水文分析实战教程(3)DEM数据准备
  12. 计算机技术中,下列的英文缩写和中文名字的对照中,正确的是,计算机技术中,下列的英文缩写和中文名字的对照中。正确的是(  )。 a.cad——计算机辅助制造b.cam——计...
  13. 第三部分数据结构[专业课考试3]
  14. DB2 客户端下载地址
  15. java hl7v3_hl7 java 解析
  16. 数据仓库介绍(一) - 数据来源
  17. Anaconda下载及安装保姆级教程(详细图文)
  18. Win10装系统及科研常用软件
  19. LTE下行物理层传输机制-PCFICH信道
  20. 如何解决在excel工作表中鼠标的右键不能使用的问题

热门文章

  1. 如何在iPhone和iPad上更改默认浏览器
  2. 单总线CPU微程序控制器设计
  3. ctfshow-萌新赛Crypto
  4. JPush+SAE+J2EE实现微信公众平台账号服务
  5. 「NFT 之王」无聊猿与品牌的跨界营销!
  6. 工程师小哥魔术揭秘“三仙归洞”,把我都看蒙了!
  7. HDU 6078 Wavel Sequence【动态规划】
  8. 一篇搞定 SpringBoot+Mybatis+Shiro 实现多角色权限管理
  9. python获取远程主机信息_python远程获取主机监控信息
  10. JavaScript数组常用方法总结及使用详解