***XML 常用的解析方式
XML 的解析方式通常有 JOM,DOM4J,SAX,这几中方式也各有优缺点。
JOM:解析器读入整个文档,以树的结构加载到内存中,然后代码就可以使用DOM 接口来操作这个树结构。
优点:
1、允许应用程序对数据和结构做出更改。
2、访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。
缺点:
将整个文档调入内存(包括无用的节点),浪费时间和空间,如果文件足够大时,超过 10M 加载速度会很慢,甚至会抛出异常。
DOM4J:在文件加载上是和 JOM 一样,也是属于一致性加载到内存中,所以也会继承 JOM 的优缺点,除此外 DOM4J 还有自己独特的地方。
优点:
1、使用了很多 JavaApi 的集合类,便于对象的操作。
2、支持 Xpath,性能很好,Hibernate 对 XML 的解析默认的方式就是dom4j,毕竟在我们自己的开发中,一般很少出现超过 10M的单个 xml 文件。
缺点:
有时候优点过了就是缺点,API 过多也使用开发的复杂性增加。
SAX:SAX 是一个用于处理 XML 事件驱动的“推”模型,它对大文件的处理性能很高,支持对节点分块加载。
优点:是一种解析速度快并且占用内存少的 xml 解析器,它需要哪些数据再加载和解析哪些内容。
缺点:是它不会记录标签的关系,而要让你的应用程序自己处理,这样就增加了你程序的负担。
***Apache、Tomcat、JBoss、WebLogic 的区别
Apache:Apache HTTP Server(简称 Apache)是 Apache 软件基金会的一个开放源码的网页服务器,通常称为静态服务器,可以在大多数计算机操作系统中运行,由于其多平台和安全性被广泛使用,是最流行的 Web 服务器端软件之一全球应用最广泛的 http 服务器,免费,也是全球使用最多的服务器。
Tomcat:是 Apache 软件基金会(Apache Software Foundation)的 Jakarta 项目中的一个核心项目,应用也算非常广泛的 web 服务器,支持部分 j2ee 最新标准,免费,默认支持 150 并发,一般普通系统部署情况下可以达到 300 的并发左右。
JBoss:开源的应用服务器,发展最为迅速的服务器,商业性能较好,对 J2EE支持良好,免费(文档收费)。
Weblogic:应该说算是业界第一的 app server,Java 编写的,全部支持 j2ee 最新标准,对于开发者,有免费使用一年的许可证,用起来比较舒服,出资 BEA 公司,现在应该是归宿 Oracle 公司,并且收费规则也有所改变,但对于 Java 开发者来说是一款非常优秀的服务器,有非常友好强大的控制台管理界面。
***动态代理的原理及实现
Java 开发中,动态代理模式通常有两种实现方式,一种是 JDK 提供的实现(称 JDK 动态代理),另外一种是引入第三方 Jar 字节码技术的方式实现的称为 CGLIB 动态代理。
JDK 动态代理:必须基于接口实现,它是通过对目标类的实现接口来生成代理类(解决静态代理每个接口都生成代理类所带来的维护成本高,代码量大等问题),jdk 的 java.lang.reflect 包中的提供了两个主要类:Proxy 和 InvocationHandler。 InvocationHandler 是一个接口,通过实现该接口来实现需要代理的逻辑,并通过反射机制调用目标类的代码,动态将代理逻辑和业务逻辑整合。Proxy 利用 InvocationHandler 动态创建一个符合某一接口的实例,生成目标类的代理对象。
CGLIB 动态代理:对于没有基于接口开发的类提供的一种代理方式,CGLIB 是在 asm 包上进行的封装,可以动态的对没有接口的业务生成子类,覆盖被代理类(目标类)中所有的业务方法,所以 CGLIB 实现的目标类不能有 final 关键字修饰。实现过程, 声明 Enhancer 类, 通过回调来生成代理的子类对象; 实现MethodInterceptor 接口,重写 intercept 方法完成代理逻辑与业务逻辑的整合。另外 Spring 默认使用的是 JDK 动态代理,如果在 Spring 中使用 cglib 需要打开配置,<aop:aspectj-autoproxy proxy-target-class="true"/>。
***Struts 与 Spring 的区别
Struts 是一个典型 MVC 模式的 Web 框架,能够独立完成 Web 项目的开发。Struts 本身集成了核心控制器 ActionServlet 和 View 层(JSP),但对于 Model 层通常依赖第三方框架,或者直接编码实现的(比如自己写 dao 层 jdbc)。
Spring 是一个轻量级的容器,它的初衷就是致力于减化 J2EE 复杂的开发流程, 使用各种框架更好更容易的集成。它的核心是 IOC,可以很好来完成 struts 中Model 层的业务需求。[在此基础之上,Spring 提供了 AOP(Aspect-Oriented Programming 面向层面的编程)的实现,很方便的对声明事务的操作管理(可以把上面 12.2 中 spring 的结构简单介绍几个) ]。而且 Spring 本身还实现了一个 Web 框架 SpringMVC,它拥有 Struts 结构上的所有优点。
***hiberante与mybatis的对比
Hibernate 是比较流行的全自动 O/R mapping 框架,它出身于 sf.net
Mybatis 是一种优秀的半自动 O/R mapping 框架,属于 apache 的一个子项目。两者是非常优秀的 ORM 框架,通过 session 开启事务(类似的 sesson 生命周期),都支持 JDBC 和 JTA 事务,也都有第三方的缓存支持等;它们的区别可以通过下面几点比较一下。
开发相关对比
Hibernate 因为封装程度更深,对程序员的要求也越高,尤其是关联关系、抓取策略、延迟加载、性能优化等方便,都要求程序员有很高的技术积累;换句话说培训成本高。但 Hibernate 因为都是基于配置映射,真正的把程序员从 SQL 中解脱出来,可移植性强,不同方言的支持更变数据库容易,开发效率高,开发周期短。
Mybatis 属于半自动化 ORM 框架,入门快,培训成本低,容易上手,比较容易组建团队。但开发人员还是要自己写 SQL 语句(这点其实无所谓的,中国的码农有不会写 SQL 语句的吗),而且灵活性不如 Hibernate,开发周期较长。
缓存策略对比
Hibernat 采用的是两级缓存策略,一级缓存 Session 级别,一般是与线程绑定;二级缓存是 SessionFactory , 通常是引用第三方缓存插件,Encache 缓存是Hibernate 默认的 CacheProvider,二级缓存是与进程绑定的。
Mybatis 缓存比 Hibernate 更细致,也很容易配置实现,默认情况下 Mybatis 是没有开启缓存的,除了局部的 session 缓存,要开启二级缓存,你需要在你的 SQL映射文件中添加一行: <cache/>。
项目维护调优对比
Hiberante 虽然开发周期快,但后期调优(配置的关联关系,不易优化)、异常定位(高度的封装,不易看到 SQL 语句)、功能扩展(容易破坏封装的结构,而且关系是在配置中维持的,不易维护)上都会比 Mybatis 上弱些。
Mybatis 上扩展,调优虽然优秀,但是因为维护太多的 SQL 配置,一旦表结构的变动,就会增加一堆工作量。
***对 NoSQL 数据库有什么理解
NoSQL=Not only SQL 是运用非关系型的数据存储,对之前一直推崇的关系型数据库来说,是一个挑战也是一个新的思维注入。
NoSQL 数据库的特点是:
非关系型存储(包括四大类:Key-Value 健值存储数据库、列存储数据库、文档型数库、图形数据库),从关系型数据库中解脱出来,这让面向对象的开发人员用起来更得心应手。
服务器硬性要求不高,只要是一个 PC 机都可以(当然 NoSQL 产品都是先基于内存再序列号到硬盘的存储,所以内存越大越好),小公司使用起来没压力。 开源易扩展,NoSQL 的产品很多,彼此之间没什么关联关系;而且是基于内存操作,又是以对象存储,对于面向对象的开发人员来说,扩展应该是很容易的。
大数据量高性能,这貌似是是大家最关心的,它的出现也是互联网对性能极尽要求,不再去维护复杂的关联关系,而且是基于内存存储,性能很高。
NoSQL 数据库虽然优点很多,但并不能取代关系型数据库,笔者在实际工作中在对 Redis、MongoDB 使用时,就出现过数据丢失,由于不维护关联关系,查起来很费劲,所以现在最完美的设计是 NoSQL+关联型数据库配合使用,真正的达到读写分离、性能提升。
***Memcached 的工作原理
Memcached 一般被称为查询缓存,它现在也是 NoSQL 代表产品之一。
Memcached 是可以独立发布的应用缓存服务器,做多台服务集群时,各个缓存服务器之间是没有什么影响的,主导方在于调用端的配置。
Memcached 实现就是一个巨大的、存储了很多<key,value>对的哈希表。通过key,可以存储或查询任意的数据,客户端可以把数据存储在多台 memcached 上。当查询数据时,首先参考节点列表计算出 key 的哈希值,选中一个节点,客户端将请求发送给选中的节点,然后 memcached 节点通过一个内部的哈希算法,查找真正的 Item。
Memcached 对于容错机制和数据冗余机制几乎不处理,数据冗余或者出错一般都会直接再查一次数据库,因为没有过多额外的处理机制,这使用 Memcaced 性能很高。
***Encache,Memcached 的区别
Encache 缓存是纯 java 开发的一种插件式缓存,一般与我们的应用集成发布, 对于分布式的实现是通过 RMI 调用来实现的。支持容灾机制、支持硬盘序列化(前提对象必须继承了序列化接口)。优点:效率高,功能强大;缺点:客户端单一。
Memcached 缓存是由 C 语言开发的,一般独立部署在服务器,支持 c,java,php等多种客户端,比 Encache 有更多的用户端。memcached 服务器端是使用不相互
通信的协议,分布式实现是由客户端配置来实现的。支持硬盘序列和容灾机制, 因为要经过网络通信,性能不如 Encache。优点:支持客户端多,部署灵活;缺点:功能不够完善(序列化到硬盘需要第三方应用实现)。
***IO与NIO的区别
IO 是早期的输入输出流,而 NIO 全名是 New IO 在 IO 的基础上新增了许多新的特性。提供的新特性包括:非阻塞 I/O,字符转换,缓冲以及通道。
1、IO 是面向流的,NIO 是面向缓冲区的。 Java IO 面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO 的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。
2、Java IO 的各种流是阻塞的。这意味着,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO 的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。线程通常将非阻塞 IO 的空闲时间用于在其它通道上执行 IO 操作, 所以一个单独的线程现在可以管理多个输入和输出通道(channel)。虽然是非阻塞的,但也会遇到一个问题就是服务器对最大连接的支持,但在线用户连接数大于系统支持数时,NIO 的默认实现是并不管是否还有足够的可用连接数,而是直接打开连接。在 netty 框架中经常会看到一个 open too many files 异常就是由此引起的,所以要灵活使用,合适配置。
3、Java NIO 的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
扩展:Netty 是 NIO 实现的一个经典框架,好多职位中都要求熟悉 netty,大家有时间可以研究一下
***数据库连接池的机制
数据库连接池的能够有效的避免开发人员在应用中手动的重复创建和关闭带来的资源浪费。
数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从缓冲池中取出一个了,使用完毕后再放回去。我们可以通过设定连接池最大数来防止系统无尽的与数据库连接。也可以设置最大空闲时间,释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。更为重要的是我们可以通过连接池的管理机制监视数据库连接使用数量,使用情况,为系统开发,测试以及性能调整提供依据。
***Maven 的工作原理
Maven 作为 Apache 的一个开源项目,它最早的意图只是为了给apache 组织的几个项目提供统一的开发、测试、打包和部署,能让开发者在多个项目中方便的切换。现在已经成为了很多公司的主要的项目管理框架。
Maven 的基本原理,采用远程仓库和本地仓库以及一个类似 build.xml 的pom.xml,将 pom.xml 中定义的 jar 文件从远程仓库下载到本地仓库,各个应用使用同一个本地仓库的 jar,同一个版本的 jar 只需下载一次,而且避免每个应用都去拷贝 jar。同时它采用了现在流行的插件体系架构,只保留最小的核心,其余功能都通过插件的形式提供,所以 maven 下载很小(1.1M),在执行 maven任务时,才会自动下载需要的插件。对于局域网络也可以建立公司内部的私服系统来代替不可能随时上网访问的中央仓库。
***对web.xml的理解
对于 Java 程序员来说,程序的一般入口是 Main 方法(对于 App 应用),Applet,然后就是 Servlet。对于开发人员来说,拿到一个 web 项目,在没有任何参考文档的前提下,应该从 web.xml 入手来读程序代码。
对于 web.xml 来说,一般包含 context-param:上下文参数,常用来配置包含的其它 xml 文件,比如 Spring 的配置等。listener:监听器。filter:过滤器,拦截器。servlet:web 应用入口中,还有一些常用欢迎页,异常跳转等等。系统启动后,会首先加载 web.xml 配置,然后初始化 listener>filter>servlet(一般顺序)。如果context-pararm 中引入了 job.xml 相关的配置,也要注意 job.xml 也是程序入口, 通常用来声明一个定时器。
***能谈一下 linux 常用的命令吗
文件&文件目录操作->
cd /file #进入 file 目录;cd.. #退出一级目录;cd/ #退到根目录。
pwd #查看当前的位置路径;
ls #查看文件目录中的文件;ls -ll #显示详细信息;ls -a#显示隐藏信息。
rm -f file#删除当前目录下的 file 文件;rm -fr dir #删除 dir 目录(包含子文件)。
mkdir file #新建一个文件夹;mkdir file1 file2 #创建两个文件目录。mv source target #将文件 source 重命名 target。
cp sou tar #将文件sou 复制tar;cp /root/sou . #将root 下的sou 复制到当前目录。cat file #显示文件内容;tac file 反向查看一个文件内容;
head -i file #查看一个文件的前 i 行;
tail -i file #查看一个文件的后 i 行。
tail -f file #查看文件的动态日志;tail -f nohup.out #weblogic 下 out 的动态日志。
vi file #编辑文件。
find /-name file #从根开始搜索文件和目录。
find / -user username #从根开始搜索属于 username 的文件和目录进程查看操作->
ps #显示当前系统进程;ps -ef #显示系统所有进程。
ps -ef|grep java#显示系统 java 进程;ps -ef|grep app #显示 app 应用进程名。
kill -9 i #杀死编号为 i 的进程;killall -9 i #对包有名字为 i 的进程杀死。
top #显示系统的活跃情况,按 CPU 资源百分比来分。
free#显示系统内存及 swap 使用情况。
注意:top,free 命令在系统性能监控时,很有作用。
*** 如何设计高并发下的秒杀功能
不过多么强大的服务器,在秒级内达到数十万数百万的并发估计都可能挂掉。秒杀对于淘宝的用户来说,同一时间数万并发应该是常见的,但这个压力并不一定会到应用服务器上;比如前面的负载均衡服务器肯定先进行大的分流,分流到应用服务器时的在线人员可能依旧很大,这时可以通过登录队列来控制排队数,比如只有 30 个物品参与秒杀,那我就从队列中取出三十人进行秒杀的业务逻辑,大部分用户阻塞在队列外就 OK 了。
***谈一下高并发框架的设计
对于高并发框架的设计通常要分三部分来考虑:应用程序、数据库环境、部署环境。
应用程序:首先在设计应用设计上就要考虑到应用的分布式部署(部署多少台应用服务器),开发选择的框架一定要支持分布式的部署才行;对于访问量大的页面可以采用静态页(结合一些前端脚本技术使用);尽可能使用查询缓存,做到业务部分的读写分离;对于长业务逻辑处理的部分要尽可能分离出来等等。
数据库环境:对于大并发量的框架设计,数据库一定要采用集群的方式(我们公司之前的环境就是使用单独数据库服务,虽然使用了大量的缓存服务,还是会因为连接数问题导致服务挂掉)。
部署环境:最好将应用部署多台服务器上(每台服务器也可以装多个应用服务器),必须部署负责均衡的服务器,必须有数据库集群的服务器,最好有独立的缓存服务器。