Java面试3

一、线程池

1、newCachedThreadPool

概念:创建一个可缓存的线程池。如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程;

说明:线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用第一个任务的线程,而不用每次新建线程

public class ThreadPoolExecutorTest{
    public static void main (String[] args){
        ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
        for(int i=0;i<10;i++){
            final int index=i;
            try{
                Thread.sleep(index*1000);
            }catch(InterrruptedException e){
                e.printStackTrace();
            }
            cachedTYhreadPool.execut(new Runnable(){
                public void run(){
                    System.out.println(index);
                }
            })
        }
    }
}

2、newFixedThreadPool

概念:创建一个定长的线程池,可控制线程最大并发量,超出的线程会在队列中等待;

说明:因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个字;

定长线程池的大小最好根据系统资源进行设置;

public class ThreadPoolExecutorTest{
    public static void main(String[] args){
        //创建线程池并且确定线程池的大小
        ExecutorService ficdThreadPool=Executors.newFixedTHreadPool(3);
        for(int i =0;i<10;i++){
            final int index=i;
            fixedThreadPool.execute(new Runnable(){
                public void run(){
                    try{
                        System.out.pringtln(index);
                        Tread.sleep(2000);
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            })
        }
    }
}

3、newScheduledThreadPool

概念:创建一个定长的线程池,支持定时 及周期性任务执行。

说明:表示延迟3秒执行

public class ThreadPoolExecutorTest{
    public static void main(Stirng[] args){
        ScheduledExectorService sheduledThreadPool=Executor.newScheduledThreadPool(5);
        sheduledThreadPool.schedule(new Runnale(){
            public void run(){
                System.out.println("delay 3 seconds");
            }
        },3,TimeUtil.SECONDS)
    }
}

说明:定期执行,延迟1秒后每3秒执行一次

public class ThreadPoolExecutorTest{
    public static void main(Stirng[] args){
        ScheduledExectorService sheduledThreadPool=Executor.newScheduledThreadPool(5);
        sheduledThreadPool.schedule(new Runnale(){
            public void run(){
                System.out.println("delay 1 seconds,and excute every 3 seconds");
            }
        },1,3,TimeUtil.SECONDS)
    }
}

4、newSingleThreadPool

概念:创建一个单线程化线程池,只会用单一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行

说明:结果依次输出,相当于顺序执行

public class ThreadPoolExecutorTest{
    public static void mian (String[] args){
        ExectorService singleThreadPool=Executor.newSingleThreadPool();
         for(int i =0;i<10;i++){
            final int index=i;
            singleThreadPool.execute(new Runnable(){
                public void run(){
                    try{
                        System.out.pringtln(index);
                        Tread.sleep(2000);
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                }
            })
        }
    }
}

二、修饰符的作用范围

 privatedefueltprotectedpublic
同一个类中
同一个包的 
不同包的子类中  
不同包的类中   

三、==与equals的区别

==:(1)非引用型变量:值是否相等;

(2)引用型变量:地址是否相同,即栈中的内容是否相同

equals:(1)变量是否对同一对象的引用,堆中的内容是否相同

四、java动态代理

(1)代理模式是常用的java设计模式,特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息,过滤消息,把消息转发给委托类,以及事后处理消息。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象相关联,代理类的本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定服务。

(2)动态代理类由java的反射机制动态生成,,不仅简化工作,而且提高了软件系统的可扩展性;

(3)JDK动态代理主要由接口实现,若有些类没有接口,则可使用cglib动态代理;

五、Cglib动态代理

cglib是针对类来实现代理的

原理:对指定的目标类生成一个子类,并且覆盖其中方法实现增强,,由于采用的是继承,所以不能对final修饰的类进行代理

六、对象被当做参数传递到一个方法,方法可改变对象属性,这是值传递还是引用传递

(1)值传递

(2)参数的值是对该对象的引用,对象的内容可以在被调用的方法中进行改变,对象的引用是永远不会被改变的

七、abstract class和interface有什么区别

类型abstract classInterface
定义声明方法存在而不实现抽象类的变体
继承抽象类可以继承一个类和实现多个接口;子类只可以继承一个抽象类接口只可以继承接口(一个或多个);子类可以实现多个接口
访问修饰符抽象方法可以有publicprotecteddefault这些修饰符接口方法默认修饰符是public。你不可以使用其它修饰符
方法实现可定义构造方法,可以有抽象方法和具体方法接口完全是抽象的,没构造方法,且方法都是抽象的,不存在方法的实现
实现方式子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
作用了把相同的东西提取出来,即重用为了把程序模块进行固化的契约,是为了降低偶合

八、字符串操作:如何实现字符串的反转及替换?

 

九、网络七层协议

 

十、http与https的区别

1.传输:(1)http是超文本传输协议,信息是明文传输
       (2)https是ssl加密传输协议
2.连接端口:
       (1)http是80
       (2)https是443
3.协议:(1)http连接是无状态的
       (2)https是SSL+http协议进行加密传输,身份认证

十一、web.xml的作用

概念:用于初始化配置信息:如welcome页面、servlet、servlet-mapping、filter、listener、启动加载级别
web.xml中常用的标签及功能:
1.命名与制定url:以servlet和jsp文件命名并制定url;
2.制定初始化参数:可制定servlet、jsp、context的初始化参数,再从中获取这些参数值
3.指定错误页面处理:通过"异常类型"和"错误码"
4.设置过滤器:设置编码过滤器,过滤所有资源
5.设置监听器;
6.设置会话过期时间:时间以分钟为单位;

十二、javaEE的设计模式

1.工厂模式

例如:spring中BeanFactory就是简单工厂模式,传入一个唯一的标识来获得Bean对象,但是传参的先后创建视情况而定
概念:定义一个用于创建对象的接口,让子类决定实例化哪一个类,FactoryBean使一个类的实例化延迟到子类;

 

2.单例模式

保证一个类仅有一个实例。并且提供一个访问它的全局访问点;

主要有,懒汉式、饿汉式,双重锁式

3.代理模式

概念:为其他对象提供一种代理以控制对这个对象的访问;所以profxy是控制,更像是对一种功能的限制;

十三、什么是MVC

概念:MVC是model、view、controller的缩写,MVC是Application开发的设计模式;
model:是应用程序的主体部分;
view:是应用程序中负责生成用户界面的部分;
controller:是根据用户的输入,控制用户界面数据的显示及更新model对象状态的部分,即商业逻辑、界面显示、数据分离;

十四、MVC的优缺点

优点:
1.模型、视图、控制分离,代码重用性高;
2.开发效率高
3.便于后期维护、降低维护成本;
4.分工明确
缺点:
1.框架清晰以代码的复杂性为代价;
2.运行效率低;
3.控制层和表现层优势会过于紧密,导致没有真正的分离和重用;

十五、springMVC运行原理

注意,整个过程是从一个http请求开始:
1.tomcat启动加载时解析web.xml,进而找到springMVC的前端总控制器DispacherServlet,并且通过DispacherServlet来加载相关的配置文件;
2.DispacherServlet接受到客户端请求,找到对应的handlerMapping,根据映射规则,找到对应的处理器(handler);
3.调用相应的处理器的处理方法,处理请求后,返回一个model and view;
4.DispacherServlet得到ModelAndView中的视图对象,找到合适的viewRsolver(视图解析器),根据视图解析器的配置,DispacherServlet将显示的数据传给相应的视图,最终显示给用户;

十六、IOC

IOC:
控制倒转(Inversion of control):spring的核心,由spring来负责控制对象的生命周期和对象的关系,所有的类的创建和销毁都由spring控制;

十七、spring事务传播属性和隔离级别

1.事务的传播属性(propagation)

其中spring七个事物传播属性:
 PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
 PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
 PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
 PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
 PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
 PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
 PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,

2.事务的隔离级别(Isolation Level)

2-1 事务并发引起的三种情况:
(1)脏读
一个事务正对这组数据进行更新操作,但是还未提交,另一个事务也对这组数据进行更新操作,并且读取到了还未提交的数据,而前一个事务如果操作失败进行回滚,后一个事务读取的就是一组错误的数据,就造成脏读;
(2)不可重复读
一个事务多次读取同一数据,在该事务还未结束时,另一个事务也对该数据进行操作,而且第一个事务两次读取之间,第二个事务对数据进行了更新,那么第一个事务读取的两次数据是不同的,造成了不可重复读;
(3)幻读
第一个事务正在查询符合某一条数据,这时,另一事务又插入了符合条件的数据,第一个事务在查询符合条件的事务的时候,发现多了一条前一次查询没有的数据,造成了幻读;

2-2 spring支持的5种事务隔离级别的设置
(1)defult(默认)
使用数据库默认的事务隔离级别
(2)read_uncommitted(读未提交)
事务最低隔离级别,准许另一个事务可以看到此事务还未提交的数据;这种隔离级别会产生脏读、不可重复读、幻读;
(3)read_committed(读已提交)
保证一个事务修改的数据提交后才能被另一个事务提取,另外一个事务不能读取该事物未提交的数据,这种事务隔离级别可以避免脏读,可能会出现不可重复读和幻读;
(4)repeatable_read(可重复读)
保证一个事务不能读取另一个事务未提交的数据外,这种事务隔离级别可防止脏读,不可重复读。可能出现幻读;
(5)serializable(串行化)
最高代价最可靠的事务隔离级别,事务被处理为顺序执行,可避免脏读,不可重复读,幻读;

十八、MyBatis

主要特点:小巧、方便、高效、简单、直接、半自动
优点:
1.数据库自动连接绑定
2.更为细致的sql优化,减少查询字段
缺点:
1.框架简陋,底层数据库查询要自己写,工作量大
2.二级缓存机制不佳

十九、Hibernate

主要特点:强大、方便、高效、复杂、绕弯子,全自动
优点:
1.数据库无关性好,O/R映射能力强,若对Hibernate进行适当封装,那么持久层代码会相当简单,开发速度会快
2.二级缓存机制好,可以使用第三方缓存
缺点:
1.学习门槛高,对性能和对象模型之间如何权衡取得平衡难度大;

二十、Query接口的list方法和Iterate方法的区别

相同点:
(1)实现获取查询的对象
不同点:
(1)list()方法返回的对象都是完整的,Iterator()方法返回的对象仅包含主键值(标识符);

二十一、springBoot

特点:开发速度快,启动速度快
根据Maven构建里面的starter依赖,如web项目的的qidong器是web-starter,就道要构建的项目类型,并且会把相关的依赖搭建好
以web项目为例:
web项目会把spring、springMVC以及json转换还有tomcat这些依赖jar包准备好,启动项目时,用SpringBoot:run启动,此时会找到唯一的一个main方法运行,在main方法里面使用SpringApplication启动应用;
涉及到的注解:
@componentScan:扫描包
@EnableAutoconfig:启动自动配置
@RestController:是@controller和ResponseBody的结合,会将返回的数据转成json@RequestMappping,依然是进行路由的EnableScheduling启用调度器进行注解扫描;
springBoot项目可以脱离xml配置,框架会根据你的pom依赖帮你准备好所有的东西,并且是用了很多默认配置,若想改掉默认配置,可以在resource-->application.properties属性文件;根据要求修改

二十二、数据库

1.JDBC连接数据库步骤(mysql)

1.加载JDBC驱动程序
2.提供JDBC连接URL、创建数据库的连接
3.创建一个Statement
4.执行sql语句
5.关闭JDBC对象

2.Prepared Statement和Statement的区别

1.Prepared Stetament是预编译的,Stetament不是,执行sql语句增删改查时,若数据量大于1,则每次执行sql语句时,Statement都要预编译,则Prepared Stetament不用;
2.从代码的可读性和可维护性来说,Prepared Stetament比Statement要好;
3.从安全性来讲,PreparedStetament是用“?”传参,防止sql注入,安全性高;statement是用“+”连接,安全性低

3.数据库连接池

DBCP:比较稳定
C3P0:性能比较高
1.不使用连接池时
每次访问数据库的时候都要创建连接,使用完之后要释放关闭连接;这样耗费资源高;
2.使用连接池时
tomcat启动的时候就自动创建连接,当程序使用时直接从连接池中取;当不需要时,不需要关闭,直接返回到连接池中供其他应用程序使用;

4.数据库的三范式

第一范式:数据库的所有字段值都是不可分解的原子性;
第二范式:确保数据库的每一列要和主键相关,而不是和某一部分相关;
第三范式:确保数据库的每一列要和主键相关,而不是间接相关;

5.MySql的最大连接数

mysql的默认连接数是100.最大可连接16384
怎么配置最大连接数:
修改Mysql配置文件my.ini或my.cnf的参数max_connections,将其max_connections=10000,然后重启mysql即可

二十三、事务

概念:事务指的是逻辑上的一组操作,要么全部成功,要么全部失败;
特性:
1.原子性:不可分割的工作单位,要么全部成功,要么全部失败,不能单独运行;
2.一致性:事务执行的前后,数据的完整性要保证;
3.隔离性:多个用户并发访问数据库,一个事务不能被其他事务所干扰,多个并发的事务之间的数据要互相隔离;
4.持久性:一个事务一旦提交,对数据库的改变是永久性的;

二十四、缓存

1.缓存穿透

概念:一般的缓存系统,都是按照key去缓存查询;
1、若不存在对应的value值,就会去后端系统去查询;
2、key对应的value值是一定不存在的,并且对该key并发请求量很大,就会对后端系统造成很大的压力,这就叫缓存穿透;

2.缓存穿透如何避免

1、对查询结果为空的时候也进行缓存,缓存时间设置短一些;或者该key对应数据insert了之后清理缓存;
2、对于一定不存在的key进行过滤,把所有可能存在的key放到bitmap中,查询的时候通过bitmap过滤去获得;

3.缓存雪崩

当缓存服务器重启或者大量缓存集中在某一时段失效,在失效的时候,给后端压力很大,这就叫缓存雪崩;

4.缓存雪崩如何避免

1.缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量;
2.不同的key,设置不同的过期时间,让缓存失效的时间尽量均匀;
3.多个缓存副本之间的一致性,为了保证系统的高可用,缓存系统背后往往会接两套存储系统(如redis,memcache)

5.分布式缓存系统面临的问题

1、缓存一致性问题
(1)缓存系统与底层数据一致性,可读可写;
(2)有继承关系的缓存之间的一致性;为了提高缓存的命中率,缓存也是分层,全局缓存,二级缓存;全局缓存可以由二级缓存来组成;
(3)多个缓存存在副本之间的一致性;为了保证系统的高可用,缓存系统背后往往会接着两套存储系统(如memcache/redis)

2、缓存数据淘汰
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,再判断这个请求是否过期,过期的话就去底层系统得到新的数据并且更新缓存;
两者对比:
第一种方式:缺点是维护大量缓存的key;
第二种方式:缺点是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂;
解决:
(1)预估失效时间;
(2)版本号(必须单调递增);
(3)提供手动清理缓存接口;

二十五、Redis

1.redis简介

1、redis是一种内存型、非关系型数据库;
2、redis数据会储存到硬盘上;
3、redis(持久化)保存数据采用rdb(快照形式,快照是采用的一种机制保存,这种机制保存可以在里面配置配置,隔多久保存多少数据,数据保存到硬盘上去,当redis启动的时候,硬盘上的数据会写到数据库中,这种方法大量提高了数据的存储和读取的效率,性能会受到一定的影响,因为会占用cpu去保存快照操作)
4、Redis保存数据的另外一种方式是AOF集群方式,使每个服务器都有对方服务器的数据,避免rdb类似的快照保存机制,从而减少内存占用,还有是达到了高可用;

2、Redis应用

1.数据经常被读写的地方,如电商的价格和数量;
2.大大减轻数据库压力的地方;

3、Redis数据类型

1.字符串类型
这是基本数据类型,以二进制的形式存在,可以容纳任何格式的数据,同时字符串类型的value值容纳的数据长度为512M;

2.Hash(散列)
将redis中的hash看成一个String key和String value的map容器,每一个hash可以储存4294967295个键值对;

3.list类型
list底层是双向链表,可以在头部和尾部添加新的元素,插入时,若键并不存在,将创建一个新的链表,反之,则若链表中的所有元素均被移除,该键也会从数据库中删除;所以。如果是插入和删除是在表的两头是非常高效的,若是在中间,则是非常低效的;

4.set类型
set的底层是无序的字符集合,不容许出现重复的元素;

4、Redis持久化

Redis对持久化的支持主要是通过RDB和AOF文件来进行持久化的;
(1)RDB持久化是在指定的时间间隔内生成数据集的时间点快照;
(2)AOF持久化记录的是服务器执行的所有写操作的命令;在服务器启动时,重新执行命令还原数据集;

5、Redis备份数据

(1)Redis对于数据备份是非常好的,服务器运行时对RDB文件进行复制,RDB文件一旦被复制创建,就不会对其进行更改
(2)当服务器创建一个新的RDB文件时,它先将文件的内容保存在一个临时文件夹里,临时文件写入完毕时,程序就开始使用,此时用临时文件夹代替原来的文件夹,所以说复制RDB是绝对安全的

6、Redis事务

redis事务的特征:
(1)事务中的所有命令会被序列化的顺序执行,事务执行期间,redis不会再为客户端的其他请求提供任何服务,保证所有命令都会原子的顺序执行;
(2)redis中的事务如果有某一条命令执行失败,其后的命令仍然会被执行;
(3)可以通过multi命令开启一个事务,执行之后的命令被视为事务之内的操作,最后通过执行exec/discard命令来提交和回滚的操作;
(4)事务开启之前。若客户端和服务器之间出现通讯障碍并且导致网络断开,所有待执行的语句不会被执行,然而,如果网络的中断事件是发生在客户端执行exec命令之后,那么该事务中所有的命令都会被服务器执行;

7、Redis集群

Redis cluster在设计时,就考虑了去中心化,去中间件;集群中的每个节点都是平等的,并且每个集群都保留了各自的数据以及整个集群的概念,每个节点之间都有联系,找到其中的任意节点就能找到其他节点;
Redis 集群是采用哈希槽来分配数据的(hash slot),默认分配了16384个soft,当set一个key时,用CRC16算法来取模得到所属的slot,然后将key分配到哈希槽区的节点上;
Redis集群会把数据存到一个master节点上,然后这个master节点会和salve进行数据同步,当数据同步时,此时根据哈希算法的一致性得到相对应的master节点获取数据,当其中的一个master挂掉之后会启动一个slave来充当master

注意:
(1)必须是3个或者3个以上的节点,否则创建集群会失败;
(2)当存活的主节点小于总结点数的的一般时,集群无法提供服;

二十六、Solr

1.简介
采用Java开发,基于Lucene的全文搜索服务器,有扩展的地方有面向抽象编程的地方(如分词器,查询);提供了更为丰富的查询(如过滤器);可和hadoop整合,提供了一个完善的功能管理界面,是一款非常优秀的全文检索引擎;
服务器占用一个接口来提供服务,作用是提供缓存
Solr是一个企业级搜索应用服务器,他对外提供了类似于web Service的API接口,用户可以通过http请求,向搜索引擎服务提供一定格式的xml文件,生成索引,也可以通过Http G solr J操作查找请求(也可以通过json格式提交),并且得到xml文件的返回结果;
2.Solr 和lucene的关系
solr是基于Lucene做的,可以通过各种api使应用使用搜索服务,不需要将搜索服务耦合在应用中,solr可以根据配置来定义解析不同数据的方法,更加像一种搜索框架,支持主从(集群中的方式),热换库(索引的数据与数据库之间的同步),高亮,facet(搜索组件)
使用solrj 使用solrjava版本的solrj来跟Tomcat进行交互,
schema.xml中:
filed name="id"(分词器名称)
type="string"(类型)
indexed="true"(是否建立索引)
stored="true"(是否储存)
required="是否必须存在"
multiValue="false"(是否允许有多个值)
schema.xml是用来定义索引域的,其中包括域名称,域类型,域是否索引,是否分词,是否储存,
schema.xml包含了大部分参数是配置solr本身的;
3.solr的性能优化
(1)将只用于搜索而不作为结果的filed的stored设置为false;
(2)将不需要被用于搜索而只作为返回结果的filed的indexed设置为false;
(3)删除所有不必要的copyfile的声明;
(4)为了索引字段的最小化和搜索效率,将所有的text fileds的index都设置成files,然后使用copyfiled将他们复制到一个总的text filed上,然后对他们进行搜索;
(5)为了最大化搜索效率,使用Java编写的客户端与solr交互(使用流通信);
(6)在服务器端运行jvm(省去网络通信),使用可能高的log输出等级,减少日志量;

二十七、话术

1、Ajax请求Session超时问题

做项目时会遇到session超时问题,如果session超时,平常请求没什么问题,通过拦截器可以正确跳转到登录页面,如用ajax请求会出现问题,因为ajax时异步的,局部刷新,故而登录页面不会在全页面中显示,只会显示在局部页面,这是因为在所用的框架是和Struts2集成的,故而应该在拦截器中进行设置;
第一:判断session是否为空,这就判断session是否超时,如果超时就取出请求得head头信request.getHeader ,如果不为空就和xmlHttpRequest(Ajax标识)进行比较,如果相等就说明时ajax请求;
第二:如果是ajax请求就可以用response.setHeader(键,值)设置一个标识,来告诉用户这是ajax请求,并且是session超时发出的,这样就可以知道在回调函数中取出的时自己设置的那个标识,若取出的值是和自己在后台中设置的值是一样的,这就证明session超时,这样就可以设置Windows.location.replace("登录界面"),跳转到登录界面;
总结:
这样虽然解决了问题,但是解决这些问题也不是完美的,在回调函数中写这些代码,代码会显得特别零散,所以定义一个全局设置就能找到juery的ajaxSetUp方法,通过ajaxSetUp(相当于ajax的拦截器)对juery的ajax进行全局判断,通过设置ajaxSetUp里面的complate,他就相当于回调函数,可以弥补不足;
自我总结:
我做项目时还用到了$(document).ajaxStart(),这是ajax请求时的事件,$(document).ajaxSuccess(),这是ajax请求成功之后的事件,一般用的是遮罩层和隐藏遮罩层,为的是不让用户重复提交,提高用户体验度,让用户知道已经提交了;

2、Servlet

1、servlet是一个web容器,servlet是httpservlet,httpservlet继承genericservlet,genericservlet
   实现servlet接口;
2、servlet生命周期:
(1)实例化
(2)初始化
(3)提高服务避免使用局部比阿娘
(4)销毁
(5)不可用
这5个生命周期:初始化是调用init方法,提高服务是调用service方法,在这个方法中,因为继承了httpservlet,其实就是对应了doGet(),doPost(),据我了解,servlet是单例的,非线程安全,有以下几种方案解决:
第一种:继承SingleThreadmodel但这样都会创建一个一个新的servlet实例,这样消耗服务器内存,降低性能,接口已经过时,不推荐使用;
第二种:尽量不使用全局变量,就我个人而言比较喜欢这种方法;
第三种:我们可以通过使用ThreadLocal,内部结构是一个map结构,用前线程作为key,会创建多个副本,get、set方法;
第四种:通过加锁,解决线程问题;
总结:
这种常见的MVC框架,Struts1,spring这些MVC框架,都是基于servlet发展而来的,就比如Struts1的核心总控制器是ActionServlet,而SpringMVC的前端总控制器的是dispachServlet,在项目我们曾经servlet来生成图片验证码,防止用户进行暴力破解,
3、servlet的配置文件web.xml
在web.xml文件当中我们首先servlet标签,servlet标签有两个子标签,一个叫servlet-name,另外一个叫servlet-class,这个servlet-class就是我后台提高服务的servlet,除此之外还有一个servlet-mapping,在里面有一个servlet-name,是保证和上面的servlet-name保持一致,还有一个是url-pattern,这是一个虚拟路径,用来发送请求的url地址;

3、介绍所做过项目中遇到的特别难解决的问题

1、发现问题:
在项目测试阶段,功能测试-->性能测试-->仿真测试;
在功能测试和性能测试过程中,项目运行良好;在仿真测试之中,系统最初开始运行一段时间里没有出现问题,但是在7-8天后,系统开始出现运行缓慢的现象,在过一段时间后,系统崩溃了。根据这个现象判断是出现系统内存泄漏的问题,所以使用了Java内存检测工具jprofiler对系统进行检测,定位源码,发现有大量的javabean占用资源,没有释放,随着系统运行的事件的增长,没有释放的资源越来越多,这样就导致内存泄漏;
2、问题原因
通过相应信息定位到代码块,发现我们在Spring中定位了多个定时器,来执行不同的操作,比如系统数据备份,数据转换,发送邮件;通过百度搜索quartz,知道quartz有这样一个bug就是会导致整个web应用的类加载器不能进行垃圾回收,在web关闭后,会看到这个应用的所有静态资源,也就是系统退出之后没有释放资源;
3、解决问题
Spring提供一个监听器,主要负责处理由于JavabeanIntrospector的监听器,web.xml中注册这个listener,可以保证在web应用关闭的时候释放这些资源(web应用相关的class loader和他管理的类);所以解决上述问题的办法是,在web.xml中加入
<listener>
<listener-class>org.Springfamework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
4、总结:
Servlet标准不允许在web容器内进行做线程管理;quartz问题确实存在。对于web容器而言,最忌讳的是应用程序私自启动线程,自行进行线程调度;像quartz这种在web容器内部默认就自己启动了线程进行一步job调度的框架本身就是一件很危险的事情,很容易造成servlet线程回收不掉;

4、是否解决过项目上线的bug

1、问题原因
项目测试中专业人士有自己的一套模式,而项目上线之后,普通用户可能因为不正当的操作而导致项目出现bug,当用户把bug反馈给我们的时候,进行排查,比如系统数据丢失,在解决bug过程当中对用户的操作进行验证,提示用户可以进行正常验证,或者在页面进行引导性的验证,再者使用oracle,利用oracle闪存来修复误操作的数据;
2、问题解决
应用Flashback Query查询过去的数据,Flashback Query常被用于修复误操作的数据,注意,这并不是说可以恢复数据,Flashback Query并不能恢复任何操作和修改,也不能告诉我们做过什么操作和修改,它是基于SELECT的扩展,能够让用户查询到某一时间指定的记录;
基于时间查询,执行查询语句,可查询距离现在5分钟左右的数据,SELECT*FROM 表名 AS OF TIMESTAM SYSDATE-5/1440,sysdate是系统当前时间,以天为单位,1440=24*60计算每一天的分钟数,sysdate-5/1440就可以计算出距离当前5分钟的记录,然后再将数据用insert语句新增到数据库当中;

5、谈谈你对敏捷开发的认识

敏捷开发有以下特性:
1、工作在小团队中
2、团队是跨功能的-测试人员、开发人员、文档开发人员等
3、短迭代-利用短迭代来交付软件
4、相较于文档,敏捷开发是面对面的交流
5、敏捷不是一个过程,而是一个软件开发的形式或者方法

6、高并发解决方案

基本解决集中在这样几个环节:
使用高性能服务器,高性能数据库,高性能编程语言,高性能web容器

7、HTML静态化

效率最高,消耗最小的就是html静态化页面,所以我们页面上尽可能采用静态化页面实现,对于大量内容并且频繁更新的网站,无法手动挨个去实现,但是可以用信息发布系统CMS,cms可以实现最简单的信息录入自动生成页面,还能具备频道管理,权限管理,自动抓取等功能;对于大型网站来说是必不可少的;
HTML静态化也用于缓存,对于数据库的频繁查询却内容更新量很小的情况下,可以使用HTML静态化来实现;

8、图片服务器分离

对于web服务器来说,不管是Apache,IIS还是其他容器,图片是最消耗资源的,有必要将图片与页面分离,大型网站都会有很多台独立的图片服务器;这样减轻页面访问请求服务器的系统压力,并且保证不会因为图片的问题而产生崩溃;
在应用服务器和图片服务器上,可以进行不同配置的优化,比如Apache在配置ContentType的时候可以尽量减少支持,尽量减少LoadModule,保证更高的系统消耗和执行效率;

9、缓存

缓存在网站架构和网站开发是非常重要的,高级和分布式的缓存也是最基本的;
1、架构方面的缓存
对于Apache熟悉的人来说,Apache提供了自己的缓存模块,也可以外加squid模块进行缓存,都可以提高Apache的访问速度。
2、网站开发的缓存
Linux上提供了MemoryCache常用的缓存接口,可以在web上使用,在Java开发的时候就可以调用MemoryCache对数据进行缓存和通讯共享;

10、镜像

镜像是大型网站提高性能和数据安全的方式,镜像技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建教育镜像站点,数据进行定时或者实时更新;

11、负载均衡

1、负载均衡是解决高负荷和大量并发请求的最佳选择
2、个人接触了以下解决方法,其中两个框架可以参考:
(1)硬件四层交换
第四层交换使用将第四层和第三层信息包的报头信息,根据区间识别业务流,将整个区间的业务流分配到合适的服务器进行处理;
第四层交换就像是虚拟IP,指向物理服务器,传输出来的业务服从多种协议,有http,ftp,nfs,telnet或者其他协议,这些业务在物理服务器的基础上需要复杂的负载平衡算法;在IP的世界里,业务类型由终端TCP或者UDP端口地址来决定,在第四层交换中的应用区间由源端和终端IP地址、TCP、UDP端口共同决定的;
(2)软件四层交换
基于OSI模型来实现软件四层交换,性能比硬件四层交换相对较差;软件四层交换是使用Linux上常用的LVS来解决,lvs就是Linux virtual server,提供了基于心跳线heartbeat的实时灾难应对解决方案,提高系统强壮性,提供了虚拟VIP配置和管理功能;
一个典型的负载均衡就是在硬件四层或者是软件四层交换的基础上搭建squid集群,优点是:架构成本低,高性能还有很强的扩展性,可随时向架构里面增加或者减少节点;

12、FreeMarker

概念:Java编写的模板引擎,基于模板生成输出通用的工具,具体可以生成HTML、xml、jsp或者其他;
优点:提高开发效率,使得在开发中的员工分工更加明确;
我的项目经验:
我在做一个门户网站的时候,利用FreeMarker将二级以及三级页面静态化,在我做的项目里面,会在web.xml或者Spring里面配置一个监听器,用监听器将生成静态化的方法监听起来;然后在项目启动的时候利用监听器,将二级和三级的页面生成静态化页面,也就是HTML页面,缺点是在更新数据的时候,静态化的页面还是旧数据,后期可以使用S定时间来解决这个问题,每天可以定时几点钟更新一次静态页面;
注意:在使用FreeMarker的时注意模板的数据不能为空,否则就会抛异常;

13、Maven和ant的区别

1、Maven编译的以及所有的脚本都会有一个基础,就是POM(project object model),各种脚本在这个模型上工作,而ant完全是自己定义的,可以看出Maven更好;
2、Maven对所依赖的包有明确的定义,而ant则是简单的包括了所有的jar;
3、Maven是把所有的资源装进一个中央仓库里面,但编译是,Maven会自动匹配仓库,找到相应包;若没有本地仓库,则从设定好的远程仓库中下载到本地,ant则需要自己定义;
4、Maven有大量的重用脚本可以利用,如生成网站,生成Javadoc,sourcecode,reference;而ant需要自己去写;
5、Maven目前不足的地方是没有像ant那样的GUI界面;

14、图片及Excel的导入是怎样实现的

1、导入
首先导出Excel模板,让客户按照模板进行相关数据信息的录入,之后提供的导入功能将Excel传到服务器端,服务器端对他进行解析
2、解析
首先后台创建一个workbook对象,每个workbook都有与其对应的多个sheet对象,再依次解析每一个sheet对象,每一个sheet对象对应多个row对象,再依次解析每一个row,每一个row对应多个cell,再依次解析每一个cell里面要获取的相应的数据,即可完成Excel的导入功能;
3、导出
从后台数据库中获取到要导出的全部数据,之后根据相应的导出功能将数据导到相应的Excel表格中;
4、流程
先获取数据,在创建一个workbook,循环建出需要的sheet,再根据查询出来的的记录条数创建row,之后再根据查询出来的每一条记录的属性个数创建出cell,并且给cell赋值,所有循环完成后将文件输出,就完成了Excel导出功能;
5、大量数据操作的问题
如果xls文件的数量比较大时,将读入到的数据封装到对象中,再全部放到list之中,list对其中的对象都是强引用(strong reference),大量的数据会引发内存溢出异常,为了解决这个问题,在工具类中每得到若干个对象后调用service层的方法保存这些数据,再重新给list赋值,再继续读取出数据;

二十八、Dubbo

dubbo有两个概念,一个提供服务方,一个消费方,同时也叫提供服务者和消费者,zookeeper就是dubbo的服务中心;第一,服务方编写真正的实现,把接口和vo对象打包成jar包,为消费者提供依赖,编写完真正实现后我们的需要注册到zookeeper的服务中心;第二,消费者连接zookeeper注册相应的地址引用相关的interface,这就使用zookeeper和dubbo的简易流程;
使用zookeeper和dubbo的优点:
如APP服务端,pc端,后台和红包系统都要进行用户查询,而且每一个查询都会连接数据库有重复代码的工作,此时要进行优化,若不同模块的单独开发,实现的方式实现的逻辑不同导致结果不一致,这样就可以使用dubbo服务,各个模块之间都可以使用,直接操作的是service接口而不是api接口。

二十九、定时任务+web service同步数据

项目中需要将一些数据同步到其他业务系统,此时就采用了定时调度+web service的方式;
定时调度有4种做法:
(1)jdk自带timer,当时它实际上就是新开一个线程去实现,当执行任务有异常的时候,定时任务都会有问题;
(2)jdk并发包中的任务调度线程池ScheduleExcutorService,它可以捕捉到系统时间变化;
(3)采用quartz框架,可以配置线程池,以及分布式。
(4)是使用Spring自带的task框架,它会自己处理异常,当执行定时任务出现异常,不会影响整个定时任务;
同步数据使用的是web service的方式,采用的是cxf框架来实现,另一个系统作为作为服务端,发布一个web service服务,使用发布的wsdl文件来生成客户端Java类,调用接口,将数据同步过去,需要注意的是安全性问题;

三十、可能问到的问题

1、数据量比较大的问题
(1)数据量不大的时候,可以采用分页的方式,发送多次请求;
(2)数据量特别大的时候,可以采用流的方式,也可以通过web service发送文件,或者,直接采用ftp的方式,将需要发送的数据打包成文件,通过ftp上传到服务端,服务端解析文件之后,进行处理;
2、请求端发送重复的数据,服务端怎么解决
每条数据的逐渐采用的是自增长,临时表的数据不删除,增加一个状态字段,表示,待同步,同步失败,已经同步,服务端接收请求的时候,先判断,同步的数据是否已经同步过,这个判断,通过查询服务端的数据库得知,结果已经存放,服务端返回的状态码或者记录ID,告知客户端,已经发送过;
3、数据的推与拉?什么叫推数据?什么叫拉数据?
数据的产生方A 数据的接收方B
A-->B 推数据 特点:快速、及时
B-->A 拉数据 特点:需要轮询,有延时,而且很多时候发的请求得不到新数据;

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值