中信银行面试问题总结

 

1   sring loc aop  理解

IoC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IoC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。

Loc 好处:第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。

在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加。AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

2.BeanFactory与ApplicationContext

ApplicationContext是BeanFactory的子接口,也被称为应用上下文。BeanFactory提供了Spring的配置框架和基本功能,ApplicationContext则添加了更多企业级功能(如国际化的支持),他另一重要优势在于当ApplicationContext容器初始化完成后,容器中所有的 singleton Bean 也都被实例化了,也就是说当你需要使用singleton Bean 是,在应用中无需等待就可以用,而其他BeanFactory接口的实现类,则会延迟到调用 getBean()方法时构造,ApplicationContext的初始化时间会稍长些,调用getBean()是由于Bean已经构造完毕,速度会更快。因此大部分系统都使用ApplicationContext,而只在资源较少的情况下,才考虑使用BeanFactory。

3. mybatis  一级缓存和二级缓存

 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

  一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

  二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

  二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存

4, jvm  内存模型 如何防止内存泄露??
 

名称

特征

作用

配置参数

异常

程序计数器

占用内存小,线程私有,

生命周期与线程相同

大致为字节码行号指示器

虚拟机栈

线程私有,生命周期与线程相同,使用连续的内存空间

Java 方法执行的内存模型,存储局部变量表、操作栈、动态链接、方法出口等信息

-Xss

StackOverflowError

OutOfMemoryError

java堆

线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址

保存对象实例,所有对象实例(包括数组)都要在堆上分配

-Xms

-Xmx

-Xmn

OutOfMemoryError

方法区

线程共享,生命周期与虚拟机相同,可以不使用连续的内存地址

存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

-XX:PermSize:

16M

-XX:MaxPermSize

64M

OutOfMemoryError

运行时常量池

方法区的一部分,具有动态性

存放字面量及符号引用

5.多线程  实现方式  线程同步
1、继承Thread类实现多线程

2、实现Runnable接口方式实现多线程

3、使用ExecutorService、Callable、Future实现有返回结果的多线程

一、同步方法

即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

二、同步代码块

即有synchronized关键字修饰的语句块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步

三、wait与notify

wait():使一个线程处于等待状态,并且释放所持有的对象的lock。

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
notifyAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

详细见:wait、notify、notifyAll的使用方法

四、使用特殊域变量(volatile)实现线程同步

五、使用重入锁实现线程同步

    在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。 

ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。

六、使用局部变量实现线程同步

    如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。

七、使用阻塞队列实现线程同步

前面5种同步方式都是在底层实现的线程同步,但是我们在实际开发当中,应当尽量远离底层结构。 使用javaSE5.0版本中新增的java.util.concurrent包将有助于简化开发。 本小节主要是使用LinkedBlockingQueue<E>来实现线程的同步 LinkedBlockingQueue<E>是一个基于已连接节点的,范围任意的blocking queue。 队列是先进先出的顺序(FIFO),关于队列以后会详细讲解~LinkedBlockingQueue 类常用方法 LinkedBlockingQueue() : 创建一个容量为Integer.MAX_VALUE的LinkedBlockingQueue put(E e) : 在队尾添加一个元素,如果队列满则阻塞 size() : 返回队列中的元素个数 take() : 移除并返回队头元素,如果队列空则阻塞代码实例: 实现商家生产商品和买卖商品的同步

 6.云架构的了解,Spring cloud,应用服务器用了几个?并发多少,性能?

Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全居琐,leader选举,分布式session,集群状态)中快速构建的工具,使用Spring Cloud的开发者可以快速的启动服务或构建应用、同时能够快速和云平台资源进行对接。

应用服务器 tomcat  jboss   weblogic jetty  根据你平时实际用到说不熟悉不要说出来

Qps每秒请求数

50QPS以下——小网站

没什么好说的,简单的小网站而已,就如同本站这样,你可以用最简单的方法快速搭建,短期没有太多的技术瓶颈,只要服务器不要太烂就好。

50~100QPS——DB极限型

大部分的关系型数据库的每次请求大多都能控制在0.01秒左右,即便你的网站每页面只有一次DB请求,那么页面请求无法保证在1秒钟内完成100个请求,这个阶段要考虑做Cache或者多DB负载。无论那种方案,网站重构是不可避免的。

300~800QPS——带宽极限型

目前服务器大多用了IDC提供的“百兆带宽”,这意味着网站出口的实际带宽是8M Byte左右。假定每个页面只有10K Byte,在这个并发条件下,百兆带宽已经吃完。首要考虑是CDN加速/异地缓存,多机负载等技术。

500~1000QPS——内网带宽极限+Memcache极限型

由于Key/value的特性,每个页面对memcache的请求远大于直接对DB的请求,Memcache的悲观并发数在2w左右,看似很高,但事实上大多数情况下,首先是有可能在次之前内网的带宽就已经吃光,接着是在8K QPS左右的情况下,Memcache已经表现出了不稳定,如果代码上没有足够的优化,可能直接将压力转嫁到了DB层上,这就最终导致整个系统在达到某个阀值之上,性能迅速下滑。

1000~2000QPS——FORK/SELECT,锁模式极限型

好吧,一句话:线程模型决定吞吐量。不管你系统中最常见的锁是什么锁,这个级别下,文件系统访问锁都成为了灾难。这就要求系统中不能存在中央节点,所有的数据都必须分布存储,数据需要分布处理。总之,关键词:分布

2000QPS以上——C10K极限

尽管现在很多应用已经实现了C25K,但短板理论告诉我们,决定网站整体并发的永远是最低效的那个环节。我承认我生涯中从未遇到过2000QPS以上,甚至1.5K以上的网站,希望有此经验的哥们可以一起交流下

高并发性能问题

1、HTML静态化

2、图片服务器分离

3、数据库集群、库表散列

4、缓存

5、负载均衡

6、镜像  容器 docker 技术

7.Spring 7层

 

8. 人行渠道采用什么方式,格式什么?其他渠道要熟悉?

人行查询回的数据:人基本信息,贷款信息,借记卡,信用卡信息,webservice

加密方式:https 端口加密or数字签名CA

9 sql 优化

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

2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:

select idfrom twhere numis null

最好不要给数据库留NULL,尽可能的使用 NOT NULL填充数据库.

备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。

不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的,如果是varchar这样的变长字段, null 不占用空间。

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:

select idfrom twhere num= 0

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

4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:

select idfrom twhere num=10 or Name= 'admin'

可以这样查询:

select idfrom twhere num= 10union allselect idfrom twhere Name= 'admin'

5.in 和 not in 也要慎用,否则会导致全表扫描,如:

select idfrom twhere numin(1,2,3)

对于连续的数值,能用 between 就不要用 in 了:

select idfrom twhere numbetween 1 and 3

很多时候用 exists 代替 in 是一个好的选择:

select numfrom awhere numin(select numfrom b)

用下面的语句替换:

select numfrom awhere exists(select 1 from bwhere num=a.num)

6.下面的查询也将导致全表扫描:

select idfrom twhere namelike ‘%abc%’

若要提高效率,可以考虑全文检索。

7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:

select idfrom twhere num= @num

可以改为强制查询使用索引:

select idfrom twith(index(索引名))where num= @num

应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select idfrom twhere num/2100

应改为:

select idfrom twhere num= 100*2

9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select idfrom twhere substring(name,1,3)= ’abc’       -–name以abc开头的idselect idfrom twhere datediff(day,createdate,’2005-11-30′)= 0    -–‘2005-11-30’    --生成的id

应改为:

select idfrom twhere namelike 'abc%'select idfrom twhere createdate>= '2005-11-30' and createdate< '2005-12-1'

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

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

12.不要写一些没有意义的查询,如需要生成一个空表结构:

select col1,col2into #tfrom twhere 1=0

这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:

create table #t(…)

13.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。

14.对于多张大数据量(这里几百条就算大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差。

15.select count(*) from table;这样不带任何条件的count会引起全表扫描,并且没有任何业务意义,是一定要杜绝的。

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

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

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

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

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

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.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

10  tomcat 启动参数设置 windows 和linux

.Linux:

在/usr/tomcat6/bin目录下的catalina.sh文件中,首先设置JAVA_HOME,linux下设置JAVA_HOME需要使用export指令,如:export JAVA_HOME=/usr/appserver/jdk1.6

然后添加jvm的JAVA_OPTS:JAVA_OPTS='-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGCDetails -server'

linux下catalina.sh中完整代码如下:


1

2

3

4

5

export CATALINA_BASE=/usr/appserver/tomcat6  

export CATALINA_HOME=/usr/appserver/tomcat6 

export CATALINA_TMPDIR=/usr/appserver/tomcat6/temp     

export JAVA_HOME=/usr/appserver/jdk1.6      

export JAVA_OPTS='-Xms1024m -Xmx1024m  -XX:PermSize=256m -XX:MaxPermSize=256m  -XX:+PrintGCDetails -server'

Windows

在catalina.bat最前面加入

set JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGCDetails -server

如果用startup.bat启动tomcat,OK设置生效.够成功的分配1024M内存.

11 常用Linux命令?

1. Ls

2. Pwd

3. Mkdir

4.  Rm rmdir

5. Mv

6. Cp

7. Cat

8. More

9. Find 10 chmod  11 tar 12 grep  13 kill  14 tenelt 15 service  16 ssh

12   tomcat集群

1 tomcat 配置多台tomcat 端口号

下面配置文件中的几个关键点:

(1)进程数与每个进程的最大连接数

#工作进程个数,一般跟服务器cpu核数相等,或者核数的两倍

worker_processes 2;

#单个进程最大连接数

events{

    worker_connections 1024;

}

· 1

· 2

· 3

· 4

· 5

· 6

· 7

· 8

① nginx进程数,建议设置为和服务器cup核数相等,或者是核数的两倍

② 单个进程最大连接数,该服务器的最大连接数=连接数*进程数; 
服务器支持最大并发数=(连接数*进程数) /2 ,因为反向代理是双向的。

(2)Nginx的基本配置

#nginx基本配置server{

    listen 8088;    #端口号

    server_name 192.168.22.227;#服务名

}

· 1

· 2

· 3

· 4

· 5

① 监听端口一般都为http端口:80;可以修改为其他,这里修改为8088。

② server_name :默认为localhost ,这里修改为服务器ip地址。

(3)负载均衡列表基本配置

    #服务器集群

    upstream mycluster{

        #这里添加的是上面启动好的两台Tomcat服务器

         server 192.168.22.229:8080 weight=1;

         server 192.168.22.230:8080 weight=1;

    }

location /{

        #将访问请求转向至服务器集群,mycluster和上面upstream mycluster 对应

        proxy_pass http://mycluster;

        # 真实的客户端IP

        proxy_set_header   X-Real-IP        $remote_addr;

        # 请求头中Host信息

        proxy_set_header   Host             $host;

        # 代理路由信息,此处取IP有安全隐患

        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

·    

① location / {}:负载均衡访问的请求,可以添加筛选,假如我们要对所有的jsp后缀的文件进行负载均衡时,可以这样写:location ~ .*.jsp$ {}

② proxy_pass:请求转向自定义的服务器列表,这里我们将请求都转向标识为http://mycluster的负载均衡服务器列表;

③ 在负载均衡服务器列表的配置中,Server指令:指定服务器的ip地址,weight是权重,可以根据机器配置定义权重(如果某台服务器的硬件配置十分好,可以处理更多的请求,那么可以为其设置一个比较高的weight;而有一台的服务器的硬件配置比较差,那么可以将前一台的weight配置为weight=2,后一台差的配置为weight=1)。weigth参数表示权值,权值越高被访问到的几率越大;

13  数据库索引 创建


普通索引   添加INDEX

ALTER TABLE `table_name` ADD INDEX index_name ( `column` )

下面演示下给user表的name字段添加一个索引

主键索引   添加PRIMARY KEY

ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )

唯一索引    添加UNIQUE

ALTER TABLE `table_name` ADD UNIQUE ( `column` )


全文索引    添加FULLTEXT

ALTER TABLE `table_name` ADD FULLTEXT ( `column`)

如何添加多列索引

ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )

14   微服务 spring boot

单体应用的不足

1. 逻辑复杂、模块耦合、代码臃肿,修改难度大,版本迭代效率低下

2. 系统启动慢,一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长

3. 系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机

4. 可伸缩性差;系统的扩容只能只对这个应用进行扩容,不能做到对某个功能点进行扩容

5. 线上问题修复周期长;任何一个线上问题修复需要对整个应用系统进行全面升级

微服务架构的优点

1. 分而治之;单个服务功能内聚,复杂性低;方便团队的拆分和管理

2. 可伸缩;能够单独的对指定的服务进行伸缩

3. 迭代周期短;支持快速的迭代开发

4. 独立部署,独立开发

微服务架构的不足

1. 可维护性差;应用流程常常垮多个微服务,不易进行问题的定位

2. 效率相对低,团队依赖强,一个服务的版本延迟会拖慢整个应用的开发周期

3. 开发难度大;垮服务的调用通常是不同的机器,甚至是不同的机房,开发人员需要处理超时、网络异常等问题

4. 应用级别的需求变动常常波及多个服务;

5. 分布式事务的支持

SpringBoot是伴随着Spring4.0诞生的;

1) Spring Boot使编码变简单

     2) Spring Boot使配置变简单

     3) Spring Boot使部署变简单

     4) Spring Boot使监控变简单

Spring由于其繁琐的配置,一度被人认为“配置地狱”,各种XML、Annotation配置,让人眼花缭乱,而且如果出错了也很难找出原因。

Spring Boot更多的是采用Java Config的方式,对Spring进行配置。

15   谈下 ssm 架构

认真理解  ssm 和三层架构关系  每层用到什么技术 不能含糊

为什么要有架构? 

这是为了满足“低耦合,高内聚”,实现代码的健壮性和可扩展性。比如为了更好的降低各层间的耦合度,在三层架构程序设计中,采用面向抽象编程。即上层对下层的调用,是通过接口实现的。而下层对上层的真正服务提供者,是下层接口的实现类。服务标准(接口)是相同的,服务提供者(实现类)可以更换。

SSM主要由Spring,SpringMVC 和 Mybatis三个构成。它们在三层架构中所处的位置是不同的,即它们在三层架构中的功能各不相同,各司其职

1. SpringMVC:作为View层的实现者,完成用户的请求接收功能。SpringMVC的Controller作为整个应用的控制器,完成用户请求的转发及对用户的响应

2. MyBatis:作为 Dao层的实现者,完成对数据库的增、删、改、查功能

3. Spring:以整个应用大管家的身份出现。整个应用中所有的Bean的生命周期行为,均由Spring来管理。即整个应用中所有对象的创建、初始化、销毁,及对象间关联关系的维护,均由Spring进行管理

16  设计模式

一、设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

17  负载均衡 技术

在互联网高速发展的时代,大数据量、高并发等是互联网网站提及最多的。如何处理高并发带来的系统性能问题,最终大家都会使用负载均衡机制。它是根据某种负载策略把请求分发到集群中的每一台服务器上,让整个服务器群来处理网站的请求。
公司比较有钱的,可以购买专门负责负载均衡的硬件(如:F5),效果肯定会很好。对于大部分公司,会选择廉价有效的方法扩展整个系统的架构,来增加服务器的吞吐量和处理能力,以及承载能力。

高可用(HA)

 在集群服务器架构中,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。ps:这里我感觉它跟故障转移(failover)是一个意思,看到的网友给个解释,谢谢?

session复制/共享

 在访问系统的会话过程中,用户登录系统后,不管访问系统的任何资源地址都不需要重复登录,这里面servlet容易保存了该用户的会话(session)。如果两个tomcat(A、B)提供集群服务时候,用户在A-tomcat上登录,接下来的请求web服务器根据策略分发到B-tomcat,因为B-tomcat没有保存用户的会话(session)信息,不知道其登录,会跳转到登录界面。
这时候我们需要让B-tomcat也保存有A-tomcat的会话,我们可以使用tomcat的session复制实现或者通过其他手段让session共享。

18 http 协议 get post put  几个区别

简单的说

就是整套CRUD(增删改查)操作,C对应POST,R对应GET,U对应PUT,D对应DELETE。

在实际的做的时候,很多人却没有按照HTTP规范去做,导致这个问题的原因有很多,比如说:

1.很多人贪方便,更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点。

2.对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。

3.另外一个是,早期的但是Web MVC框架设计者们并没有有意识地将URL当作抽象的资源来看待和设计 。还有一个较为严重的问题是传统的Web MVC框架基本上都只支持GET和POST两种HTTP方法,而不支持PUT和DELETE方法。

 

进一步解说

GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定的服务端逻辑造成的。

PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。

POST操作既不是安全的,也不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。

安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。

19  maven

3.eclipse配置 maven:

        (1). 点击 Add 按钮,选到你本机安装 Maven 的路径值

           

          (2)在Preferences-->Maven-->User Settings中,点击Update Settings,加载刚才我们 对settings.xml的更改

          
   

    4.修改 maven 本地仓库存放位置:

       找到 apache-maven-3.0.4下的 conf 下的 settings.xml 配置文件,我的是在 D:\Development\apache-maven-3.0.4\conf\settings.xml

       

        apache-maven-3.0.4的仓库默认是放在本地用户的临时文件夹下面的 .m2 文件夹下的 repository 下,我的是在 C:\Users\Administrator\.m2\repository 目录下, 
        现在我们来修改将它指定到我们自己的路径下,我现在要将仓库指定到 D:/Development/m2/repository 目录下,只需要将上面注销的本地仓库打开,

         然后把相应的路径值写到里面去就行了:
         

 本地仓库

设置本地仓库到指定目录,而不使用Maven默认的配置(默认放在C:/user/m2.目录下)

打开Maven的解压目录E:\soft\apache-maven-3.1.0\conf,修改settings.xml

配置localRepository即可完成本地仓库的设置:

Xml代码  

1. <localRepository>E:/repository/maven/repos</localRepository>  

==================================================================

中心仓库

即,告诉Maven从外网的哪个地方下载jar包

Maven的安装目录中,在lib目录下,maven-model-builder-3.1.0.jar中,有一个默认的pom.xml文件

其中就配置了Maven默认连接的中心仓库

修改中心仓库:

直接在POM.xml中加入repository的配置,指定一个新的url即可

注意:这里仍然使用<id>central</id>,目的在于覆盖Maven中的配置的id为central的repository!

Xml代码  

1. <repositories>  

2.     <repository>  

3.         <id>central</id>  

4.         <name>My Central Repository</name>  

5.         <url>http://repo.maven.apache.org/maven2</url>  

6.         <layout>default</layout>  

7.         <snapshots>  

8.             <enabled>false</enabled>  

9.         </snapshots>  

10.     </repository>  

11. </repositories>  

==================================================================

 私服

配置在局域网环境中,为局域网中所有开发人员提供jar包的统一管理

本地仓库(本机)--->私服(局域网)--->中心仓库(外部网络)

私服的安装

1.下载NEXUS,http://www.sonatype.org

2.解压

3.配置环境变量:

新建环境变量:NEXUS_HOME = E:\soft\nexus-2.5.1-01

加入到path中:%NEXUS_HOME%\bin;

4.打开CMD命令行

C:\Users\Administrator>nexus install      安装服务

C:\Users\Administrator>nexus start         启动服务

C:\Users\Administrator>nexus uninstall  卸载服务

5.访问私服

使用默认账户:admin 密码:admin123

NEXUS内部使用Jetty作为服务器

 http://localhost:8081/nexus   【界面用extjs开发的】

仓库的分类

查看Repository

host仓库--->内部项目的发布仓库

Snapshots   发布内部snapshots版本的仓库

Releases     发布内部release版本的仓库

3rd party      发布第3方jar包的仓库,如oracle数据库驱动,open-189.jar

proxy仓库--->从远程中心仓库查找jar包的仓库

Apache Snapshots    查找Apache项目的快照版本的仓库

Central   中心仓库http://repo1.maven.org/maven2/

Codehaus Snapshots    查找Codehaus 的快照版本的仓库

group仓库--->把仓库按组划分,以组为单位进行管理

virtual仓库  

私服的配置 / Repository的配置

在parent模块的pom.xml中加入私服的配置,让Maven从私服下载jar包,而不直接去远程仓库下载。

默认情况下,Maven下载jar包将直接连接到外网http://repo1.maven.org/maven2/去下载;

安装私服之后,让Maven下载jar包先从私服查找,如果没有,再从外网下载并保存在私服上

在POM在加入下面的配置,其中url为NEXUS私服的Public Repository对外的地址

以后,Maven下载构建(jar包或插件)都将从这里开始下载

Xml代码  

1. <project>  

2.     

3.   ...  

4.     

5.   <!-- 配置私服地址 -->  

6.   <repositories>  

7.     <repository>  

8.       <id>nexus</id>  

9.       <url>http://localhost:8081/nexus/content/groups/public/</url>  

10.       <snapshots><enabled>true</enabled></snapshots>  

11.       <releases><enabled>true</enabled></releases>  

12.     </repository>  

13.   </repositories>  

14.   <pluginRepositories>  

15.     <pluginRepository>  

16.       <id>nexus</id>  

17.       <url>http://localhost:8081/nexus/content/groups/public/</url>  

18.       <snapshots><enabled>true</enabled></snapshots>  

19.       <releases><enabled>true</enabled></releases>  

20.     </pluginRepository>  

21.   </pluginRepositories>  

22.   

23.   ...  

24.   

25. <project>  

通过settings.xml来配置私服

由于所有的Maven项目都会用settings.xml中的配置进行解析,如果将Repository配置到这个文件中,那么对所有的Maven项目都将生效。

此时,Maven项目中的POM文件就不需要再配置私服地址了!

注意:修改settings.xml文件时,看IDE中关联的是哪个settings文件。

如C:\user\.m2目录下可能存在,Maven的解压目录下也存在,具体修改哪个根据实际情况而定。如,Eclipse下,查看Maven的User Settings选项即能看到关联。

我的IDE关联的是Maven\conf目录下的settings.xml:

E:\soft\apache-maven-3.1.0\conf\settings.xml

首先,通过<profile/>添加Repository和pluginRepository

Xml代码  

1. <settings>  

2.   

3.   ...  

4.   

5.   <profiles>  

6.      <profile>  

7.       <id>profile-nexus</id>  

8.   

9.       <repositories>  

10.         <repository>  

11.           <id>nexus</id>  

12.           <url>http://localhost:8081/nexus/content/groups/public/</url>  

13.           <snapshots><enabled>true</enabled></snapshots>  

14.           <releases><enabled>true</enabled></releases>  

15.         </repository>  

16.       </repositories>  

17.       <pluginRepositories>  

18.         <pluginRepository>  

19.           <id>nexus</id>  

20.           <url>http://localhost:8081/nexus/content/groups/public/</url>  

21.           <snapshots><enabled>true</enabled></snapshots>  

22.           <releases><enabled>true</enabled></releases>  

23.         </pluginRepository>  

24.       </pluginRepositories>  

25.     </profile>  

26.   </profiles>  

27.   

28.   ...  

29.   

30. </settings>  

然后,使用<activeProfiles>对上面的配置进行激活(通过配置的id标识进行激活)

Xml代码  

1. <activeProfiles>  

2.   <activeProfile>profile-nexus</activeProfile>  

3. </activeProfiles>  

现在,本地机器上创建Maven项目,都会使用settings中有关仓库的配置了

本地仓库:

<localRepository>E:/repository/maven/repos</localRepository>

本地Maven下载的依赖包和插件都将放到E:/repository/maven/repos目录中

私服:

本地所有Maven项目,下载构建都统一从http://localhost:8081/nexus/content/groups/public/ 下载!

【私服上不存在某个构建时,再从远程下载】

远程仓库:

如果远程仓库连接不上,则通过nexus修改central的地址即可!

当前使用Maven的默认配置:http://repo1.maven.org/maven2/

 Maven 私服 建议大家手动搭建

20. linux 查看日志文件

Linux日志文件在/var/log目录下,可以通过命令查看日志文件。
    1,cat messages可以查看某个日志文件。
    2,要达到实时更新,可以通过tail命令查看更新的数据,例如tail -f messages。
    3,tail命令参数:
    -f 循环读取
    -q 不显示处理信息
    -v 显示详细的处理信息
    -c<数目> 显示的字节数
    -n<行数> 显示行数
    --pid=PID 与-f合用,表示在进程ID,PID死掉之后结束.
    -q, --quiet, --silent 从不输出给出文件名的首部 
    -s, --sleep-interval=S 与-f合用,表示在每次反复的间隔休眠S秒。

日志类型

下面是常见的日志类型,但并不是所有的Linux发行版都包含这些类型:

类型

说明

auth

用户认证时产生的日志,如login命令、su命令。

authpriv

与 auth 类似,但是只能被特定用户查看。

console

针对系统控制台的消息。

cron

系统定期执行计划任务时产生的日志。

daemon

某些守护进程产生的日志。

ftp

FTP服务。

kern

系统内核消息。

local0.local7

由自定义程序使用。

lpr

与打印机活动有关。

mail

邮件日志。

mark

产生时间戳。系统每隔一段时间向日志文件中输出当前时间,每行的格式类似于 May 26 11:17:09 rs2 -- MARK --,可以由此推断系统发生故障的大概时间。

news

网络新闻传输协议(nntp)产生的消息。

ntp

网络时间协议(ntp)产生的消息。

user

用户进程。

uucp

UUCP子系统。

日志优先级

常见的日志优先级请见下标:

优先级

说明

emerg

紧急情况,系统不可用(例如系统崩溃),一般会通知所有用户。

alert

需要立即修复,例如系统数据库损坏。

crit

危险情况,例如硬盘错误,可能会阻碍程序的部分功能。

err

一般错误消息。

warning

警告。

notice

不是错误,但是可能需要处理。

info

通用性消息,一般用来提供有用信息。

debug

调试程序产生的信息。

none

没有优先级,不记录任何日志消息。

常用日志文件

系统日志是由一个名为syslog的服务管理的,如以下日志文件都是由syslog日志服务驱动的:

/var/log/boot.log:录了系统在引导过程中发生的事件,就是Linux系统开机自检过程显示的信息

/var/log/lastlog :记录最后一次用户成功登陆的时间、登陆IP等信息

/var/log/messages :记录Linux操作系统常见的系统和服务错误信息

/var/log/secure :Linux系统安全日志,记录用户和工作组变坏情况、用户登陆认证情况

/var/log/btmp :记录Linux登陆失败的用户、时间以及远程IP地址

/var/log/syslog:只记录警告信息,常常是系统出问题的信息,使用lastlog查看

/var/log/wtmp:该日志文件永久记录每个用户登录、注销及系统的启动、停机的事件,使用last命令查看

/var/run/utmp:该日志文件记录有关当前登录的每个用户的信息。如 who、w、users、finger等就需要访问这个文件

/var/log/syslog 或 /var/log/messages 存储所有的全局系统活动数据,包括开机信息。基于 Debian 的系统如 Ubuntu 在 /var/log/syslog 中存储它们,而基于 RedHat 的系统如 RHEL 或 CentOS 则在 /var/log/messages 中存储它们。
/var/log/auth.log 或 /var/log/secure 存储来自可插拔认证模块(PAM)的日志,包括成功的登录,失败的登录尝试和认证方式。Ubuntu 和 Debian 在 /var/log/auth.log 中存储认证信息,而 RedHat 和 CentOS 则在 /var/log/secure 中存储该信息。

21 redis 优缺点??

一:redis简介:

1:键-值存储 通常被称作是一款数据结构服务器

2:支持的数据类型:字符串、哈希、列表、集合、有序集合等 。对这些数据类型,可以执行原子操作。

3:为了获得优异的性能,redis采用内存中数据集的方式。 

4:redis支持数据的持久化,可以每个一段时间将数据转存到磁盘上,或在日志尾部追加一条操作命令。

5:redis支持主从复制,并具有非常快速的非阻塞的首次同步、网络断开自动重连等功能。

6:redis的一些其他功能:简单的事务支持、发布订阅、管道、虚拟内存等。

Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

分布式:redis支持主从的模式。

原则:Master会将数据同步到slave,而slave不会将数据同步到master。Slave启动时会连接master来同步数据。 
这是一个典型的分布式读写分离模型。我们可以利用master来插入数据,slave提供检索服务。这样可以有效减少单个机器的并发访问数量。

读写分离模型

通过增加Slave DB的数量,读的性能可以线性增长。为了避免Master DB的单点故障,集群一般都会采用两台Master 
DB做双机热备,所以整个集群的读和写的可用性都非常高。 
读写分离架构的缺陷在于,不管是Master还是Slave,每个节点都必须保存完整的数据,如果在数据量很大的情况下,集群的扩展能力还是受限于单个节点的存储能力,而且对于Write-intensive类型的应用,读写分离架构并不适合。

优点: 
1. 丰富的数据结构

· String

· list

· set

· hash

· sorted set

2.高速读写,redis使用自己实现的分离器,代码量很短,没有使用lock(MySQL),没有使用CAS(memcached),因此效率非常高。

缺点: 
1. 持久化。Redis直接将数据存储到内存中,要将数据保存到磁盘上,Redis可以使用两种方式实现持久化过程。定时快照(snapshot):每隔一段时间将整个数据库写到磁盘上,每次均是写全部数据,代价非常高。第二种方式基于语句追加(aof):只追踪变化的数据,但是追加的log可能过大,同时所有的操作均重新执行一遍,回复速度慢。 
2. 耗内存,占用内存过高。 

23 mq 流程

1. 创建 连接工厂QueueConnectionFactory

2  提供 连接工厂 创建连接connection

3. 创建一个session 会话

4.  创建一个消息队列

5. 创建消息发送者

6. 发送消息

7. 提交会话

说说Spring MVC的工作原理、流程

在整个Spring MVC框架中,DispatcherServlet处于核心位置,它负责协调和组织不同组件完成请求处理并返回响应的工作。具体流程为:

1)客户端发送http请求,web应用服务器接收到这个请求,如果匹配DispatcherServlet的映射路径(在web.xml中配置),web容器将请求转交给DispatcherServlet处理;

2)DispatcherServlet根据请求的信息及HandlerMapping的配置找到处理该请求的Controller;

3)Controller完成业务逻辑处理后,返回一个ModelAndView给DispatcherServlet;

4)DispatcherServlet借由ViewResolver完成ModelAndView中逻辑视图名到真实视图对象View的解析工作;

5)DispatcherServlet根据ModelAndView中的数据模型对View对象进行视图渲染,最终客户端得到的响应消息可能是一个普通的html页面,也可能是一个xml或json串,甚至是一张图片或一个PDF文档等不同的媒体形式。

猜你喜欢

转载自blog.csdn.net/u012045045/article/details/84334715