Java的面试题

1.结合项目谈谈你对MVC的理解
MVC是model-view-control的简称.也就是模型-视图-控制器.mvc是一种设计模式,它强制性的吧应用程序的输入,处理,输出分开.MVC中模型.视图,控制器分别承担正不同的任务.
视图:视图是用户看到并与之交互的界面.视图向用户显示相关的数据,并接受用户的输出.视图不进行任何业务逻辑处理
模型:表示业务数据和业务处理,相当JavaBean.一个模型能为多个视图提供数据,这提供了应用程序的重用性.
控制器:当用户单机web页面中的提交按钮是,控制器接收请求并调用相应的模型去处理请求.然后根据处理结构调用相应的视图来显示处理的过程的结构
MVC的处理过程:首先控制器接收用户的请求,调用相应的模型来进行业务处理,并返回数据给控制器.控制器调用相应的视图来显示处理的结构.并通过视图呈现给用户.如果在项目中对应MVC的haul;View对用项目中的JSP.controler对应action.model对应service+dao层的业务逻辑和持久层的操作

2.项目中为什么使用ssh(三大框架的有点)
- springmvc是因为struts基于mvc模式的,很好的将应用程序进行了分层,使开发者更关注业务逻辑的实现
- Hivernate:是因为Hibernate为java应用提供了一个易用的、搞效率的对象关系映射框架。hibernate是个轻量级的持久层框架,功能丰富
- Spring基于IOC(控制反转)和AOP框架多层J2ee系统的框架

3.为何使用spring
spring是一个轻量级的控制反转(IOC),面向切面(AOP),面向接口,事物管理,包容促进其他框架;是系统中用到的其他框假的耦合程度大大降地,扩展性强,简单易用好管理..

4.Spring在项目中如何充当粘合剂
在项目中利用spring的ioc(控制反转或依赖注入),明确的定义组件接口(UserDao),开发者可以独立开发各个组件,然后根据组件间的依赖关系组装(UserControl依赖UserService,UserService依赖UserDao)运行,很好的吧SpringMVC和hibernate结合起来;
spring的事物管理吧hibernate对数据库的操作进行了事物配置

5.描述在系统中如何使用了spring的事物控制
spring事物包括编程和声明式事务.在系统中使用了声明式的事务管理是用spring的AOP来实现的;配置了只读事物和回滚事物,当出现错误后进行事物回滚操作.在项目中通过aop切入事物daoservice层,这样能是以业务逻辑操作包括几个数据操作都控制在一个事务中.

6.Hibernate工作原理以及什么要用?
原理:

  • 读取并解析配置文件
  • 读取并解析映射信息,创建SessionFactory
  • 打开Session
  • 创建事物Transaction
  • 持久化操作
  • 提交事物
  • 关闭Session
  • 关闭SessionFactory
    为什么要用
    1.对JDBC访问数据库代码做了封装,大大简化了数据访问层繁琐的重复性代码.
    2.hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现.他很大程度上简化DAO层的编码工作.
    3.Hibernate使用Java反射机制,而不是字节码增强程序来实现透明性
    4.Hibernate的性能非常好,因为他是一个轻量级框架.映射的灵活性很出色.他支持各种关系型数据库,从一到多对对的各种复杂的关系

Hibernate在系统中使用的优化策略
Hibernate对数据的缓存包括两个级:一级缓存,在session的级别上进行,主要是对象的缓存,一起id为键保存对象,在Session的生命期间存在;二级缓存,在SessionFactory的的级别上进行,有对象缓存和查询缓存,查询缓存一查询条件为键保存查询结果,在SessionFactory的生命期间存在,默认地,Hibernate只启用一级缓存

Hibernate与mybatis的比较
Hibernate与mybatis相比较,mybatis更为轻便、灵活,容易掌握。mybatis可以把sql语句从java代码中分离了出来,放在了配置文件中书写,大大降低里java代码与SQL语句的耦合度,更容易对sql语句操作,重要的是mybatis还可以书写动态的sql语句,但mybatis也存在一些缺陷,比如mybatis本身的缓存机制没有hibernate那么完善,hibernate除了本身有良好的缓存机制,还可以使用第三方缓存。Hibernate较完整的封装了JDBC,但学起来要比mybatis更困难一些。Hibernate的DAO层开发比MyBatis简单,对对象的维护和缓存要比MyBatis好。

谈一下拦截器和过滤器的区别
- 拦截器是基于JAVA反射机制的,而过滤器是基于函数回调的
- 过滤器只能对Action请求起作用(action中的方法),而过滤器可以对几乎所有的请求起作用(css JSP JS)
- 过滤器依赖servlet容器,二拦截器不依赖Servlet容器

SessionFactory是线程安全吗?Session是线程安全吗?两个线程能共享一个Session吗?
SessionFactory对应Hibernate的一个数据存储的概念,它的线程是安全的,可以被多个线程并发并访问.SessionFactory一般只会在启动时候创建.对于对应的程序,最好是将SessionFactory通过单例的模式进行封装以便访问

Session是一个轻量级非线程安全的对象 (线程之间不能共享session),它表示与数据库进行交互的一个工作单元.Session是由SessionFactory创建的,在任务完成之后被关闭.Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用TreadLocal来获取当前的session,无论你调用多少次getCurrentSession()方法,返回的都是同一个session。

Session的load和get方法的区别
如果没有找到符合条件的记录,get方法返回null值,而load方法会抛出异常
get方法直接返回实体类对象,load方法返回实体类对象的代理
对于load()方法,hibernate认为该数据在数据库中一定存在,可以放心的使用代理来实现延迟加载,如果没有数据,就会抛出异常,而通过get()方法去取数据,是可以不存在的。

Session加载实体对象的过程
Session在调用数据查询工鞥呢之前,首先会缓冲中进行查询,在一级缓存中,通过实体类型和主键进行查询.如果一级缓存查询中且数据状态合法,则直接返回
如果一级缓存没有命中,接下来Session会在当前NonExists记录(相当于一个查询黑名单,如果出现重复的无效查询可以迅速判断,从而提升性能)中进行查询,如果NonExists中存在同样的查询条件,则返回null;
对于load方法,如果一级缓存查询失败,则查询二级缓存,如果二级缓存命中则直接返回
如果之前的查询都未命中,则发出sql语句,如果查询未发现对应的记录,则此次查询添加到Session的NonExists中加以记录,并返回null;
根据映射配置和SQL语句,的带ResultSet,并创建对应的实体对象
将对象纳入Session(一级缓存)管理
执行拦截器的onload方法(如果有对应的拦截器);
将数据对象纳入二级缓存;
返回数据对象。

Query接口的list方法和iterate方法有什么区别?
①list()方法返回的每个对象都是完整的(对象中的每个属性都被表中的字段填充上了),list方法无法利用缓存,它对一级缓存只写不读;

②iterate方法可以充分利用一级缓存,它所返回的对象中仅包含了主键值(标识符),只有当你对iterator中的对象进行操作时,Hibernate才会向数据库再次发送SQL语句来获取该对象的属性值;

②list方法不会引起N+1查询问题,而iterate方法会引起N+1查询问题。

Hibernate如何实现分页查询
通过Hibernate实现分页查询,开发人眼只需要提供HOL语句,查询起始行数(setFirstResult()方法)和最大查询行数(setMaxResult()),并调用Query接口的list()方法,Hibernate会自动生成分页查询的SQL语句

servlet的执行流程
客户端发出http的请求,web服务器请求转发到servlet容器,servlet容器解析url并根据werb.xml找到相应的servlet,并将request和response对象传递给找到servlet,servlet根据request就可以知道是谁发出的请求,请求信息及其他信息,当servlet处理完业务逻辑后会将信息放入到response并响应到客户端。

springMVC执行流程
springMVC流程是由dispatchservlet为核心的分层控制框架.首先客户端发出一个请求web服务器解析请求url并去匹配dispatchservlet的映射url,,如果匹配上就将这个请求放入到dispatchservlet,dispatchservlet根据mapping映射配置去寻找相对应的handel,然后把处理权交给找到的handel,handel封装了处理业务逻辑的代码,当handel处理完后会返回一个逻辑视图modelandview给dispatchservlet,此时的modelandview是一个逻辑视图不是一个正式视图,所以dispatchservlet会通过viewresource视图资源去解析modelandview,然后将解析后的参数放到view中返回到客户端并展现。

多线程
a)一个进程是一个独立的运行环境,可以看做是一个程序,而线程可以看做是进程的一个任务,比如QQ是一个进程,而一个QQ窗口是一个线程。

b)在多线程程序中,多线程并发可以提高程序的效率,cpu不会因为某个线程等待资源而进入空闲状态,它会把资源让给其他的线程。

c)用户线程就是我们开发程序是创建的线程,而守护线程为系统线程,如JVM虚拟中的GC

d)线程的优先级别:每一个线程都有优先级别,有限级别高的可以先获取CPU资源使该线程从就绪状态转为运行状态。也可以自定义线程的有限级别

e)死锁:至少两个以上线程争取两个以上cpu资源,避免死锁就避免使用嵌套锁,只需要在他们需要同步的地方加锁和避免无限等待

Spring的IOC和AOP
a) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度。而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的,容器控制对象,控制了对外部资源的获取。而反转即为,在传统的编程中都是由我们创建对象获取依赖对象,而在IOC中是容器帮我们创建对象并注入依赖对象,正是容器帮我们查找和注入对象,对象是被获取,所以叫反转。

b) AOP:面向切面编程,主要是管理系统层的业务,比如日志,权限,事物等。AOP是将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为切面(aspect),切面将那些与业务逻辑无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

Hibernate的核心思想
Hibernate的核心思想是ROM对象关系映射机制.它是将表与表之间的操作映射成对象与对象之间的操作。也就是从数据库中提取的信息会自动按照你设置的映射要求封装成特定的对象。所以hibernate就是通过将数据表实体类的映射,使得对对象的修改对应数据行的修改。

mybatis
数据库优化
a) 选择合适的字段,比如邮箱字段可以设为char(6),尽量把字段设置为notnull,这样查询的时候数据库就不需要比较null值
b) 使用关联查询( left join on)查询代替子查询

c) 使用union联合查询手动创建临时表

d) 开启事物,当数据库执行多条语句出现错误时,事物会回滚,可以维护数据库的完整性

e) 使用外键,事物可以维护数据的完整性但是它却不能保证数据的关联性,使用外键可以保证数据的关联性

f) 使用索引,索引是提高数据库性能的常用方法,它可以令数据库服务器以比没有索引快的多的速度检索特定的行,特别是对于max,min,order by查询时,效果更明显

g) 优化的查询语句,绝大多数情况下,使用索引可以提高查询的速度,但如果sql语句使用不恰当的话,索引无法发挥它的特性。

Tomcat服务器优化(内存,并发连接数,缓存)
a) 内存优化:主要是对Tomcat启动参数进行优化,我们可以在Tomcat启动脚本中修改它的最大内存数等等。

b) 线程数优化:Tomcat的并发连接参数,主要在Tomcat配置文件中server.xml中配置,比如修改最小空闲连接线程数,用于提高系统处理性能等等。

c) 优化缓存:打开压缩功能,修改参数,比如压缩的输出内容大小默认为2KB,可以适当的修改。

类加载过程
遇到一个新的类时,首先会到方法区去找class文件,如果没有找到就会去硬盘中找class文件,找到后会返回,将class文件加载到方法区中,在类加载的时候,静态成员变量会被分配到方法区的静态区域,非静态成员变量分配到非静态区域,然后开始给静态成员变量初始化,赋默认值,赋完默认值后,会根据静态成员变量书写的位置赋显示值,然后执行静态代码。当所有的静态代码执行完,类加载才算完成

对象的创建
a) 遇到一个新类时,会进行类的加载,定位到class文件

b) 对所有静态成员变量初始化,静态代码块也会执行,而且只在类加载的时候执行一次

c) New 对象时,jvm会在堆中分配一个足够大的存储空间

d) 存储空间清空,为所有的变量赋默认值,所有的对象引用赋值为null

e) 根据书写的位置给字段一些初始化操作

f) 调用构造器方法(没有继承)

MyBatis编程步骤
1.创建SqlSessionFactory
2.通过SqlSessionFactory创建SqlSession
3.通过sqlsession执行数据库操作
4.调用session.commit()提交事物
5.调用session.close()关闭会话

进程间通信的方式?
(1)管道(pipe)及有名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

(2)信号(signal):信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致的。

(3)消息队列(message queue):消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。

(4)共享内存(shared memory):可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。

(5)信号量(semaphore):主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。

(6)套接字(socket):这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。

线程的基本概念、线程的基本状态及状态之间的关系?
线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。

产生 就绪 运行 消亡 阻塞

守护线程: 只要当前JVM中尚有任何一个非守护线程没有结束,守护线程就全部工作 thread.setDaemon(true)

线程的优先级(1–>10(最重要))

推荐使用implemenets Runnable
保留了继承权
适合多个相同的程序代码去处同一个资源
增加了程序的健壮性,代码可以被多个线程共享.代码和数据独立

线程与进程的区别?
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体.

线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量

多线程同步和互斥有何异同,在什么情况下分别使用他们?
所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。如果用对资源的访问来定义的话,同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。

所谓互斥,是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。如果用对资源的访问来定义的话,互斥某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

Java多线程中调用wait() 和 sleep()方法有什么不同?
Java程序中wait 和 sleep都会造成某种形式的暂停,它们可以满足不同的需要。wait()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而sleep()方法仅仅释放CPU资源或者让当前线程停止执行一段时间,但不会释放锁。

“==”和equals方法有什么区别?
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。

quals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的

.抽象类和接口的区别?
 抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
 1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

  2)抽象类不能用来创建对象;

  3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

区别?
1.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

  2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

解释Nginx如何处理HTTP请求
Nginx使用反应器模式。主事件循环等待操作系统发出准备事件的信号,这样数据就可以从套接字读取,在该实例中读取到缓冲区并进行处理。单个线程可以提供数万个并发连接。

猜你喜欢

转载自blog.csdn.net/qq_38334410/article/details/79482268