(两到三年)Java 面试精髓

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/liugw_768/article/details/69942627

1.Struts2框架的执行流程 ?

从客户端发送请求过来,先经过前端控制器(核心过滤器)过滤器中,执行一组拦截器(一组拦截器 就会完成部分功能代码)执行目标Action,

在Action中返回一个结果视图,根据Result的配置进行页面的跳转.

Struts2和Struts1没有任何联系.Struts2内核是webwork的内核.

2.hibernate框架的理解?

定义:

Hibernate是一个开放源代码的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,

使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.可以通过对象保存到关系型数据库中,仅提供sava/get方法即可

Hibernate是一个持久层的ORM框架.

3.Spring框架的理解?

Spring是一个开源框架,核心是控制反转(IOC编程思想)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EEfull-stack(一站式) 轻量级开源框架

Spring的AOP的理解:通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率.可以在不修改源代码的前提下,对程序进行增强.

例如:在以前配置事务的时候,进行事务的回滚,提交等操作,配置AOP 以后可以将事务的权限交给Spring框架去管理,自动管理

4.SpringMVC的理解?

springMvc:是一个表现层框架,就是从请求中接收传入的参数,

将处理后的结果数据返回给页面展示

基本类型:string,double,float,integer,long.boolean

5.Mybatis的理解?

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

#{}可以有效防止sql注入

6.Servlet的理解?

* GET和POST区别?

* GET:请求参数会显示到地址栏.GET方式有大小的限制.GET方式没有请求体

* POST:请求参数不会显示到地址栏.在请求体中.POST没有大小限制.POST方式有请求体.

* 只有表单设置为method=”post”才是post请求.其他的都是get请求

生命周期:客户端第一次访问该Servlet的时候才会创建一个Servlet的对象,那么Servlet中的init方法就会执行.任何一次从客户端发送的请求,那么服务器创建一个新的线程执行Servlet中service方法为这次请求服务.

service方法的内部根据请求的方式的不同调用不同doXXX的方法.当Servlet从服务器中移除或者关闭服务器的时候Servlet对象就会被销毁.destroy的方法就会执行.

7.Struts2与SpringMVC的区别?

1)springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

8.Jsp的核心及核心标签?

a) Servlet

b) Core XML Database Funcations

9.Redis什么情况下使用,redis持久化方案?

a) 处理大数据量的时候

b) Redis的所有数据都是保存在内存中,

Rdb:快照形式,定期把内存中当前时刻的数据保存到磁盘,redis默认支持的持久化方案

aof形式:append only file。把所有对redis数据库操作的命令,增删改操作命令,保存到文件中,数据库恢复是把所有命令执行一遍即可。

10.Hibernate和Mybatis的区别和优劣?

a) Sql优化方面:hibernate的查询会将表中所有的字段查询出来,这一点会有性能的消耗

Mybatis的sql是手动编写的,所以可以按需求指定查询的字段,sql会更灵活,可控性更好

b) Hibernate是在JDBC上进行了一次封装

Mybatis是基于原生的JDBC,运行速度有优势

c) Mybatis mapper xml支持动态sql;Hibernate不支持

d) Hibernate与具体数据库的关联只需在xml文件中配置即可,所有hql语句与具体的数据库无关,移植性好

Mybatis项目所有的sql语句都是依赖所用的数据库的,所以不同数据库类型的支持不好

11.StringBuffer、StringBuilder的区别?

StringBuffer、StringBuilder是容器,是可变的字符串序列,存放于堆内存。

StringBuffer是JDK1.0版本的,线程是安全的,效率比较低。StringBuilder是JDK1.5出现的,线程不安全,效率高。

12.说一下SOLR?

solr就是一个中文搜索引擎,做完分词之后会做热度排名,核心是中文分词器,全文搜索支持,索引值指向对应的文档,相当于是一个字典,默认为collection的一个域对象,查询快,效率高.

可以在Redis里做分词之后的缓存,每次搜索一次就次数加一,里面还有一个投票容错机制,主机挂掉还有备份机,一般配置都为奇数态配置.

13.Solr与Lucene的区别?

Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索引擎,Lucene提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索引擎。

Solr的目标是打造一款企业级的搜索引擎系统,它是一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

14.什么是Redis?

1) Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。

Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。

1.1RDB持久化

RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。

每次进行访问进行存储,如果服务器一旦崩溃,会导致数据丢失

RDB是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

save 900 1 , save 300 10, save 60 10000

save 开头的一行就是持久化配置,可以配置多个条件(每行配置一个条件),每个条件之间是“或”的关系,“save 900 1”表示15分钟(900秒钟)内

至少

1个键被更改则进行快照,“save 300 10”表示5分钟(300秒)内至少10个键被更改则进行快照。

在redis.conf中:

配置dir指定

rdb快照文件的位置;配置dbfilenam指定rdb快照文件的名称

Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。

通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。

问题总结:

通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。

1.2AOF持久化

默认情况下Redis没有开启AOF(append only file)方式的持久化,访问一段存储一段,效率高.

可以通过appendonly参数开启:appendonly yes开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件

AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof

2)主从复制(了解)

2.1什么是主从复制

持久化保证了即使redis服务重启也会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:

说明:

n主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。

n主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。

n只有一个主redis,可以有多个从redis。

n主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求

n一个redis可以即是主又是从,如下图:

2.2主从配置

2.2.1主redis配置

无需特殊配置。

2.2.2redis配置

修改从redis服务器上的redis.conf文件,添加slaveof redisipredis端口

上边的配置说明当前该从redis服务器所对应的主redis是192.168.101.3,端口是6379

2.3主从复制过程

2.3.1完整复制

在redis2.8版本之前主从复制过程如下图:

复制过程说明:

1、slave 服务启动,slave 会建立和master 的连接,发送sync 命令。

2、master启动一个后台进程将数据库快照保存到RDB文件中

注意:此时如果生成RDB文件过程中存在写数据操作会导致RDB文件和当前主redis数据不一致,所以此时master 主进程会开始收集写命令并缓存起来。

3、master 就发送RDB文件给slave

4、slave 将文件保存到磁盘上,然后加载到内存恢复

5、master把缓存的命令转发给slave

注意:后续master 收到的写命令都会通过开始建立的连接发送给slave。

当master 和slave 的连接断开时slave 可以自动重新建立连接。如果master 同时收到多个slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有slave。

完整复制的问题:

在redis2.8之前从redis每次同步都会从主redis中复制全部的数据,如果从redis是新创建的从主redis中复制全部的数据这是没有问题的,但是,如果当从redis停止运行,再启动时可能只有少部分数据和主redis不同步,此时启动redis仍然会从主redis复制全部数据,这样的性能肯定没有只复制那一小部分不同步的数据高。

2.3.2部分复制

部分复制说明:

从机连接主机后,会主动发起 PSYNC 命令,从机会提供 master的runid(机器标识,随机生成的一个串) 和 offset(数据偏移量,如果offset主从不一致则说明数据不同步),主机验证 runid 和 offset 是否有效, runid 相当于主机身份验证码,用来验证从机上一次连接的主机,如果runid验证未通过则,则进行全同步,如果验证通过则说明曾经同步过,根据offset同步部分数据。

2)redis是一个nosql(not only sql不仅仅只有sql)数据库.翻译成中文叫做非关系型型数据库.

关系型数据库:以二维表形式存储数据

非关系型数据库: 以键值对形式存储数据(key, value形式)

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库。它通过提供多种键值数据类型来适应不同场景下的存储需求,

目前为止Redis支持的键值数据类型如下:

字符串类型

散列类型

列表类型

集合类型

有序集合类型。

3)redis的应用场景

缓存(数据查询、短连接、新闻内容、商品内容等等)。(最多使用)

分布式集群架构中的session分离。

聊天室的在线好友列表。

任务队列。(秒杀、抢购、12306等等)

应用排行榜。

网站访问统计。

数据过期处理(可以精确到毫秒)

redis是将数据存放到内存中,由于内容存取速度快所以redis被广泛应用在互联网项目中,

redis有点:存取速度快,官方称读取速度会达到30万次每秒,写速度在10万次每秒最有,具体限制于硬件.

缺点:对持久化支持不够良好,

所以redis一般不作为数据的主数据库存储,一般配合传统的关系型数据库使用.

4) redis应用领域

分布式缓存

分布式session

保存博客或者论坛的留言回复等.

总之是用在数据量大,并发量高的情况下

15.谈下DUBBO?

Dubbo就是资源调度和治理中心的管理工具。

调用关系说明:

0. 服务容器负责启动,加载,运行服务提供者。

1. 服务提供者在启动时,向注册中心注册自己提供的服务。

2. 服务消费者在启动时,向注册中心订阅自己所需的服务。

3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。

4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。

5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

16.解决跨域问题?

JSONP-->Script Tags

17.秒杀方案:

1、把商品的数量放到redis中。

2、秒杀时使用decr命令对商品数量减一。如果不是负数说明抢到。

3、一旦返回数值变为0说明商品已售完。

18.ZOOKeeper?

Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化。

通过监控这些数据状态的变化,从而可以达到基于数据的集群管理

注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力小。使用dubbo-2.3.3以上版本,建议使用zookeeper注册中心。

Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,可用于生产环境,并推荐使用

19.ActiveMQ的消息形式

一种是点对点的,即一个生产者和一个消费者一一对应;可进行缓存,只允许单人登录查看

另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。无法进行缓存,支持多人访问.

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

StreamMessage -- Java原始值的数据流

MapMessage--一套名称-值对

TextMessage--一个字符串对象

ObjectMessage--一个序列化的 Java对象

BytesMessage--一个字节的数据流

1.订单系统

1.1.功能分析

1、在购物车页面点击“去结算”按钮跳转到订单确认页面。

a)展示商品列表

b)配送地址列表

c)选择支付方式

2、展示订单确认页面之前,应该确认用户身份。

a)使用拦截器实现。

b)Cookie中取token

c)取不到token跳转到登录页面

d)取到token,根据token查询用户信息。

e)如果没有用户信息,登录过期跳转到登录页面

f)取到用户信息,放行。

3、提交订单

a)生成订单

b)展示订单提交成功页面。

订单系统系统:订单确认页面、订单提交成功页面。

订单服务系统

1.1.展示订单确认页面

1.1.1.功能分析

1、在购物车页面点击“去结算”按钮跳转到订单确认页面。

2、请求的url:

/order/order-cart

3、参数:没有参数。

4、购物车商品数据从cookie中取出来的。可以在订单系统中取到cookie中的购物车数据。

5、配送地址列表,需要用户登录。需要根据用户id查询收货地址列表。静态数据。

6、支付方式。静态数据。

7、返回值:逻辑视图String,展示订单确认页面。

1.1.2.Dao层、Service层(没有)

需要根据用户id查询收货地址列表。没有此功能。

1.1.3.表现层

请求的url:/order/order-cart

参数:无

业务逻辑:

从cookie中取商品列表展示到页面。

返回值:逻辑视图。

1.1.用户身份认证

在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。

1.1.1.功能分析

1、使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。

2、业务逻辑

a)从cookie中取token。

b)没有token,需要跳转到登录页面。

c)有token。调用sso系统的服务,根据token查询用户信息。

d)如果查不到用户信息。用户登录已经过期。需要跳转到登录页面。

e)查询到用户信息。放行。

3、在springmvc.xml中配置拦截器。

1.1.2.拦截器实现

1.1.1.功能分析

1、在订单确认页面点击“提交订单”按钮生成订单。

2、请求的url:/order/create

3、参数:提交的是表单的数据。保存的数据:订单、订单明细、配送地址。

a)向tb_order中插入记录。

i.订单号需要手动生成。

要求订单号不能重复。

订单号可读性号。

可以使用redis的incr命令生成订单号。订单号需要一个初始值。

ii.Payment:表单数据

iii.payment_type:表单数据

iv.user_id:用户信息

v.buyer_nick:用户名

vi.其他字段null

b)向tb_order_item订单明细表插入数据。

i.Id:使用incr生成

ii.order_id:生成的订单号

iii.其他的都是表单中的数据。

c)tb_order_shipping,订单配送信息

i.order_id:生成的订单号

ii.其他字段都是表单中的数据。

d)使用pojo接收表单的数据。

可以扩展TbOrder,在子类中添加两个属性一个是商品明细列表,一个是配送信息。

把pojo放到taotao-order-interface工程中。

业务逻辑:

1、接收表单的数据

2、生成订单id

3、向订单表插入数据。

4、向订单明细表插入数据

5、向订单物流表插入数据。

6、返回TaotaoResult。

返回值:TaotaoResult

1.1.1.Dao

可以使用逆向工程。

1.1.2.Service

参数:OrderInfo

19.单点登录

单点登录就是我们是做了分布式,tomcat集群之后会有session复制的问题,影响利群数量。所以把注册登录拿出来单独做了一个单点登录系统。做的时候是用的redis,key是用uuid生成的一个token,类似于session id,是用户的唯一标识,value是用户的信息。设置了有效期是7天。然后把redis放到了cookie中,实现了cookie的二级跨域。当我们进行操作时,首先要从cookie里面取出token如果取不到,就跳到单点登录系统进行登录操作如果取到了,再看看token有没有过期,如果过期了,也是跳到单点登录系统登录一下,没过期就继续用户的操作。密码进行了加密,用Md5

展开阅读全文
博主设置当前文章不允许评论。

没有更多推荐了,返回首页