2019java后端面试集合篇最值得收藏的(一)
2019java后端面试集合篇最值得收藏的(二)
2019java后端面试集合篇最值得收藏的(三)
2019java后端面试集合篇最值得收藏的(四)
我认为spring 就是一个框架的集成器,通常使用spring 来管理action 层和DAO 层。Spring本身有很多的组件,比如:MVC、IOC、AOP、DaoSupport等等。IOC 本身也就是一个容器,它管理了所有的bean 和bean 之间的依赖关系。
IOC 也叫作控制反转,核心是BeanFactory。也就意味着IOC 是基于工厂模式设计的,同时这个工厂生产的bean 默认是单例的。如果想修改单例变成多实例,则需要修改bean 的scope属性,值是prototype。在没有使用IOC 以前,程序员需要自己在对应的类中new 相关依赖的对象。
比如UserAction依赖于UserService完成业务操作,而UserService又依赖于UserDAO完成数据库操作。所以需要在action 中new servcie,在service 中new DAO。这样的方式,是由程序员来管理了对象的生命周期和他们之间的依赖关系,耦合度很高,不利于程序的拓展。所以通过IOC 来管理bean 和依赖关系,可以解耦合。
我们将所有的action、service 和dao等类定义成IOC 的一个bean 组件,此时类的实例化就交给了IOC 的beanFactory,由工厂来负责实例化bean 的对象。IOC 有三种注入方式,属性注入、构造器注入和接口注入。接口注入只是spring 提出的设计,并没有具体的实现,所以常用的注入方式是属性注入。
属性注入就是在bean 的标签中,配置property 标签设定注入其他的bean。要求注入的bean在被注入的bean 中要存在一个全局的私有变量,并提供set 方法。这样就可以实现了依赖关系的注入。如果需要很多的bean,则直接注入就可以。如此操作会导致bean 标签的配置比较冗余复杂,所以spring 提供了autowried的自动装配方式,可以byName也可以byType。后续的版本中,spring 还提供了annotation 的方式,不需要再去定义多余的bean 标签,而是直接在对应的类上面声明注解就可以了。
常用的注解有:@controller、@Service、@Repository、@Component、@AutoWried、@Resource 等。除了IOC 以外,项目中通常通过AOP 来实现事务控制。AOP 就是面向切面编程,一般事务我们会控制在service 层,因为一个service 有可能会调用到多个DAO 层的方法,所以只有
当一个service 方法执行成功后,再提交或者回滚事务。具体的配置方式是:在applicationContext.xml 中,配置aop:config标签,指定事务控制在service 层。除此还需要配置事务的管理类transactionManager,将这个transactionManager指定给事务管理的bean,并且配置事务的传播特性、隔离级别、回滚策略以及只读事务read-only等等。
Spring 默认的传播特性是如果当前上下文中存在事务则支持当前事务,如果没有事务,则开启一个新的事务。还有另外一个传播特性是在项目中经常用的,REQUIRES_NEW 这个配置,这个属性指的是总是开启一个新的事务,如果当前上下文中存在一个事务,则将当前的事务挂起后开启新的事务。
比如说:在一个本来是只读事务的操作中,想加入写操作的时候,就使用
REQUIRES_NEW。关于事务的隔离级别,一般使用默认的配置提交读。也就是说,事务提交以后,才能访问这条数据。
除了事务控制以外,我们通常还可以使用AOP 去完成一些特殊操作,比如日志控制、安全校验等等。这么做的目的就是将功能操作的代码从实际的业务逻辑操作出分离出来。实现的方式是通过代理模式,真正完成操作的不是实际的业务对象而是代理对象。
代理模式有静态代理和动态代理,实现的方案也有两种,一种是基于JDK 的Proxy 代理类,另外一种则通过CGLIB 来实现。实现AOP 的方式,主要是在applicationContext中定义一个AOP 处理类,这就是一个普通的bean,在类中定义要执行的方法。然后去配置一个aop:config标签,在标签中定义aop:aspect切面,在切面中关联刚才定义好的处理类bean。然后在切面标签中配置aop:pointcut切入点,切入点就指的是在哪个类的哪个方法上加入代理事务,然后配置通知模型。
AOP 的通知模型中包含:前置通知、后置通知、最终通知、异常通知、环绕通知。这几个通知模型表示在方法执行以前、执行以后、最终执行、当遇到异常时执行以及前后都执行。在执行的AOP 切面方法中,可以通过JoinPoint连接点来获得当前被代理的对象以及被代理对象要执行的方法和方法的参数。
除了IOC 和AOP,我们经常还会使用到spring 的DaoSupport。主要是spring 提供了对hibernate 和myBatis等持久型框架的接口。比如HibernateDaoSupport,和sqlSessionDaoSupport。如果DAO 继承了HibernateDaoSupport,则需要在对应的bean 中注入sessionFactory。而sessionFactory是通过IOC 加载的。
在数据库中,所谓事务是指一组逻辑操作单元即一组sql语句。当这个单元中的一部分操作失败,整个事务回滚,只有全部正确才完成提交。
事务的ACID属性
1. 原子性(Atomicity)
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,
要么都不发生。
2. 一致性(Consistency)
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。(数据不被破坏)
3. 隔离性(Isolation)
事务的隔离性是指一个事务的执行不能被其他事务干扰.
4. 持久性(Durability)
持久性是指一个事务一旦被提交,
它对数据库中数据的改变就是永久性的.
在JDBC中,
事务默认是自动提交的,
每次执行一个 SQL 语句时,如果执行成功,
就会向数据库自动提交,而不能回滚
为了让多个 SQL 语句作为一个事务执行:
(1)执行语句前调用 Connection 对象的setAutoCommit(false);
以取消自动提交事务
(2)在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
(3)在出现异常时,调用 rollback(); 方法回滚事务。
spring中事务的传播特性好像有5个左右,
我做项目的时候使用最多的就是propagation_required,
它所代表的意思支持当前事务,如果当前没有事务,就新建一个事务。
spring中事务的隔离级别有5个,默认使用的是isolation_default,
它代表使用数据库默认的事务隔离级别,也是我们项目中最常使用的。
除此之外还有
读未提交:
它充许另外一个事务可以看到这个事务未提交的数据,
这种隔离级别会产生脏读,不可重复读和幻像读。
读提交:
保证一个事务修改的数据提交后才能被另外一个事务读取,
也是大多数数据库的默认值。可以避免脏读,但会产生不可重复读和幻像读。
重复读:
在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
串行化:
顺序执行事务。除了防止脏读,不可重复读外,还避免了幻像读。
并发性也最低,但最安全。
不可重复读的重点是修改:同样的条件,你读取过的数据,再次读取出来发现值不一样了 。
幻读的重点在于新增或者删除:同样的条件,第1次和第2次读出来的记录数不一样。
参考:
我们首先说并发中可能发生的3中不讨人喜欢的事情
1: Dirty reads--读脏数据。也就是说,比如事务A的未提交(还依然缓存)的数据被事务B读走,如果事务A失败回滚,会导致事务B所读取的的数据是错误的。
2: non-repeatable reads--数据不可重复读。比如事务A中两处读取数据-total-的值。在第一读的时候,total是100,然后事务B就把total的数据改成 200,事务A再读一次,结果就发现,total竟然就变成200了,造成事务A数据混乱。
3: phantom reads--幻象读数据,这个和non-repeatable reads相似,也是同一个事务中多次读不一致的问题。但是non-repeatable reads的不一致是因为他所要取的数据集被改变了(比如total的数据),但是phantom reads所要读的数据的不一致却不是他所要读的数据集改变,而是他的条件数据集改变。比如Select account.id where account.name="ppgogo*",第一次读去了6个符合条件的id,第二次读取的时候,由于事务b把一个帐号的名字由"dd"改成"ppgogo1",结果取出来了7个数据。
1.一个类只能进行单继承,但可以实现多个接口。
2.有抽象方法的类一定是抽象类,但是抽象类里面不一定有抽象方法;
接口里面所有的方法的默认修饰符为public abstract,接口里的成员变 量默认的修饰符为 pulbic static final。
关系:
接口和接口 继承
接口和抽象类 抽象类实现接口
类和抽象类 类继承抽象类
类和类 继承
我们通常使用Spring MVC 来充当我们项目中的控制层,我们控制层的作用就是接受前台传递的参数,调用业务逻辑层进行业务处理以及将返回的结果集返回前台进行展示,首先我们要在web.xml 中配置Spring MVC 的前端总控制器DispatcherServlet并加载Spring MVC 的配置文件,我们在Controller 层上加上@Controller 注解,使其充当控制层,并且要在Spring mvc的配置文件中通过component-scan 对Controller 层进行扫描从而使类中的@Controller 注解生效,Spring mvc用方法来接收参数,所以我们说Spring mvc是基于方法的设计,我们也可以通过@PathVariable冲路径中获取信息,我们通常通过@Resource 这个注解来进行Bean 注入,他是java 中的注解,而不是Spring 中的,默认是按照属性名进行注入,我们也可以通过设置name属性的值,让其只能按照属性名进行注入,我们也可以用@Autowired注解来进行Bean 的注入,他默认是按照类型进行注入,如果要按属性名进行注入我们需要结合@Qualifier 注解使其按照名字进行注入,我们可以将返回值的类型改为ModelAndView并在配置文件中配置视图解析器的前缀和后缀,以此来给我们前台页面传递数据,也可以在方法中通过ModelMap进行返回数据。也可以通过@ResponseBody将返回的实体类或者实体类的集合转换为指定的格式进行前台页面交互。并且要在配置文件中进行相关的配置。@RequestMapping是将Url映射到具体的方法上。文件上传时我们通过@RequestParam来接收前台上传的文件。以上就是我对SpringMVC的理解和运用。
1.重载发生在同一个类中,重写发生在父子类继承关系中
2.重写要求重写父类非私有非静态的方法,而重载没有要求
3.重载与返回值无关,重写要求返回值必须相同
4.重载要求参数类型顺序个数至少有一个不同,重写要求参数必须相同
5.重写要求子类的访问权限不得小于父类,但重载没有要求
6.重写要求子类不得抛出比父类更多的异常单可以是父类异常的子异常,重载也没有要求
1、重载:
(1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。
重载Overloading是一个类中多态性的一种表现。
(2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
(3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
2、重写:
(1) 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。
方法重写又称方法覆盖。
(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
(3)子类函数的访问修饰权限不能少于父类的;
概念:即调用对象方法的机制。
全局变量直接定义在类中。
局部变量定义在方法中,参数上,语句中。
- 全局变量存放在堆内存,局部变量存放在栈内存。
- 全局变量随着对象的创建而存在,随着对象的消失而消失。局部变量随着方法的创建而存在,随着方法的结束而结束。
- 全局变量有默认初始值,局部变量没有默认初始值,要想使用,必须赋初始值。
1、全局变量:
1.1 非静态全局变量:
非静态全局变量的定义:非静态全局变量都是定在类中,是类的成员变量或者说是成员属性属于类的一部分(或者说是对象的一部分);
生存时间:非静态全局变量加载在堆内存中,随着声明初始化而创建,随着对象消亡而消亡;
是否需要初始化:全局变量都是不需要被强制初始化的,系统都会默认根据其数据类型进行默认赋值;但是建议、在声明时都进行初始化操作;
创建位置:创建在堆内存中,因为非静态的全局变量数对象的成员变量是对象的一部分;
1.2静态全局变量:
静态全局变量的定义:静态的类成员变量;
生存时间:静态全局变量随着类的字节码文件加载而加载产生,随着字节码文件的消失而消失,生存时间比类的对象还要长;
是否初始化:凡是全局变量都是可以不要初始化的,静态变量也是一样,系统会自动根据其数据类型进行赋默认值,但是建议变量在声明时都进行初始化;
创建位置:静态变量时存在于对内存中的,所以静态全局变量也是存在于堆内存中的;
2、局部变量:
局部变量的定义:定义在方法中的变量都是局部变量(main方法也是方法,所以定义在main方法中的变量也是局部变量)。
生存时间:局部变量的生存时间和方法的生存时间一致,调用该方法声明该局部变量并初始化的时,该局部变量被创建并分配内存空间;直到该方法调用结束局部变量也就结束了;
是否需要初始化:局部变量在使用前必须进行初始化,系统默认不会对局部变量进行初始化数据操作,如果局部变量在使用前没有进行初始化则会在编译器报错;如果局部变量进行了声明没有进行初始化,但是也一直没有被使用的话编译也是不会报错的;(局部变量使用前必须初始化话)
创建位置:局部变量是创建在栈内存中的;
记录项目运行时产生的动作。比如异常信息,或者关键动作的记录。都可以配置记录到一个文件当中方便查看。
基本上每个项目都可以使用。这个是个日志系统。系统上线后可以配置一个log.html文件路径,将所有捕获的异常都想log日志中输出一下。这样系统在运行中出现异常情况就可以直接从这里检查原因,而不用特费劲到服务器上调用控制台输出日志了。
优先级从高到低分别是 ERROR、WARN、INFO、DEBUG。
一:试验环境
OS:win7
JDK:jdk7
Log4j:1.2.17(好尴尬,原本是想试验下log4j2的,结果阴差阳错用了这个版本,不过幸好,试验也不白试验,试验的作用是一样的)
二:先看两个简单的例子然后在谈为什么吧!
(1)当我们想打印一些信息时,估计这是最容易想到的一种方式,将我们想打印的信息,打印到控制台中
(2)这个是使用log4j日志框架,我觉得最简单的一种实现方式,好像比(1)麻烦不少,我们好像没有必要非使用log4j日志框架的,那么再看看下面的例子吧!
(3)这段日志信息,我们的需求稍微复杂了一点点,我们想区分开来打印的信息的级别,比如:哪些可能是错误的情况?哪些可能是警告的情况?以及顺便看一下不使用日志框架时程序运行的效率如何?
(4)这段日志信息和(3)的需求一模一样,使用日志框架好像更能满足一些我们的特殊需要啦,是的,这也是为什么我们选择使用日志框架的原因的。
5)这段代码平淡无奇,是用来辅助我们测试的,不过实际的开发中使用这类代码的地方可以说是到处都是。
三:看完栗子后的感想
(1)很明显我们在编写代码的时候有各种需要打印日志的需求,比如:我们调试代码的时候;我们的应用出现了问题,我们分析、定位、解决问题的时候;我们想将某些日志信息作为离线的业务数据分析的时候等等
(2)最简单的打印日志的方式就是使用系统本身的输出语句,不过对于大多数需求这种方式都是不能满足的
(3)于是我们的目光可能会向编写一个专门打印日志信息的工具类转移,不过有人更近了一步,写出了一个日志框架供我们使用
(4)使用日志框架的好处显而易见,方便、自在、功能强大能够满足各种需求,不好的地方也是有的,比如:如果你也进行了试验你会发现,程序变慢了,需要一定的时间和精力作为学习的成本
(5)日志框架都是能控制什么哪?那我们需要打印的日志都能满足什么样的需求哪?通常我们希望一个日志框架能够灵活的做到以下三点:
5-1:能够控制日志信息想往哪里打就往哪里打,比如:控制台、文件、邮箱、数据库等等
5-2:能够控制日志信息想怎么打就怎么打,比如:我想要打印时间、程序的名称、程序的方法名、程序的行号、线程的名称等等
5-3:能够控制日志信息想打什么打什么,不想打的就不打,日志信息是分级别的,有时候我只想看错误的信息或者警告的信息,有时候我想看到所有的信息我想调试程序等等
(6)如果有这么个框架,不是太难使用我也是非常乐意玩玩的,尤其是当程序出现问题的时候,项目负责人让你赶紧解决问题,这时候有一份日志文件可供分析就好了!
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
有时候我们说某个语言具有很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic binding)、动态链接(dynamic linking)、动态加载(dynamic loading)等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚至像对象导向当初被导入编程领域一样,一人一把号,各吹各的调。
一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。
尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
Java如何能够做出上述的动态特性呢?这是一个深远话题,本文对此只简单介绍一些概念。整个篇幅最主要还是介绍Reflection APIs,也就是让读者知道如何探索class的结构、如何对某个“运行时才获知名称的class”生成一份实体、为其fields设值、调用其methods。本文将谈到java.lang.Class,以及java.lang.reflect中的Method、Field、Constructor等等classes。
1、mongo使用场合
mongodb的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。mongo适用于以下场景:
a.网站数据:mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
b.缓存:由于性能很高,mongo也适合作为信息基础设施的缓存层。在系统重启之后,由mongo搭建的持久化缓存可以避免下层的数据源过载。
c.大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储。
d.高伸缩性的场景:mongo非常适合由数十或者数百台服务器组成的数据库。
e.用于对象及JSON数据的存储:mongo的BSON数据格式非常适合文档格式化的存储及查询。
2、不适合的场景:
a.高度事物性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
b.传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
c.需要SQL的问题。
不能的。因为默认的都是“public static”的静态方法,所以是没法new对象的。
抽象类之所以存在就是要子类去实现他的所有的抽象方法,既然是抽象的,创建它的对象后调用它的方法,什么都不会产生,所以毫无意义。
1.抽象类与抽象方法的关系是:抽象方法必须在抽象类中,如果抽象方法不在抽象类中,则会编译报错,这个是规定的。
2.抽象类中的方法不一定要必须是抽象方法,可以有抽象方法,和非抽象方法.其中非抽象方法,往往都是抽象类的所有子类所具有的,而抽象方法则由具体的不同子类实现不同的方法。抽象类无法实例化,无法创建对象。现实生活中也有抽象类的类子,比如说人类是一个抽象类,无法创建一个叫人类的对象,人继承人类来创建对象。况且抽象类中的抽象方法只有声明,没有主体,如果实例化了,又如何去实现调用呢?
String(字符串),hash(哈希),list(集合),set(无序集合)及zset(sorted set有序集合)
1、String (Key-Value)String是最常用的一种数据类型,普通的key/value存储都可以归为此类。
2、Hash(Key-Value)hash是一个string 类型的field和value的映射表。
3、list是一个链表结构,主要功能是push, pop, 获取一个范围的所有的值等。操作中key理解为链表名字。
4、Set它是string类型的无序集合。set是通过hash table实现的,可以进行添加、删除和查找。对集合我们可以取并集,交集,差集.
5、zset,Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。
Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,就使得数据能够被轻松地存储和传输。(即Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。)
1、序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态,并且可以把保存的对象状态再读出来。虽然你可以 用自己的各种方法来保存Object states,
但是Java给你提供一种应该比你自己好的保存对象状态的机制、那就是序列化。
2、什么情况下需要序列化?
a)当你想把的内存中的对象保存到一个文件或者数据库中时候。
b)当你想用套接字在网络上传送对象的时候
c)当你想通过RMI传输对象的时候(RMI->Remote Method Invocation 远程方法调用)
3、当对一个对象实现序列化时,究竟发生了什么?
在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实体变量(instance ariable)例如:Foo myFoo=new Foo(); myFoo.setWidth(20); myFoo.setHeight(40);对象反序列化方法和装置
其中,对象反序列化方法包括:获取目标字符串;创建与所述目标字符串对应的Json对象,所述Json对象为具有Json属性的设置操作的类;将所述目标字符串转化为所述Json对象;以及由所述Json对象生成所述目标字符串的对象。通过本发明,避免了Json字符串内容与目标对象不匹配,而导致的反序列化失败的问题,达到了成功反序列化的效果。
oop(Object-Oriented Programming)
aop(Aspect-Oriented Programming)
Sop(Service-Oriented Programming)
我们做权限的时候用了5张表,一张用户表、角色表、用户角色中间表,首先完成用户赋角色,就是将用户和角色id一起存入用户角色中间表。一张权限表和一张角色权限中间表,将角色id和权限id插入角色权限中间表。当用户登陆的时候,通过用户id查询当前用户拥有的所有角色,通过角色id再查权限,将权限用ztree的形式完成展示,完成权限
权限涉及到 5 张表:
用户表,角色表,权限表(菜单表),用户角色关联表,角色权限关联表
60
当用户登录时,根据用户名和密码到用户表验证信息是否合法,如果合法则获取用户信息,
之后根据用户id再到用户角色关联表中得到相关连的角色id集合,之后根据角色id再到角色权
限关联表中获取该角色所拥有的权限 id 集合,然后再根据权限 id 集合到权限表(菜单表)中
获取具体的菜单,展现给当前登录用户,从而达到不同用用户看到不同的菜单权限。
我们通过ZTree 来给角色赋权并且通过 ZTree 来展示菜单,以及通过 ZTree 来管理菜单即
增加和编辑菜单。
我们做的权限控制到url 级别,为了防止用户不登录直接输入 url 访问的这个弊端,通过拦
截器进行拦截验证。
resultMap与resultType、parameterMap与 parameterType的区别?
Map:映射;Type:Java类型。
1、客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet.
2、DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。
3-4、DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。
5、Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。
6、Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。
7、Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。
- 你们公司的maven私服怎么搭建的
- 在官网上面下载maven的压缩包。
- 配置验证maven(mvn-version命令查看是否安装成功)。
- 把maven和eclipse整合到一起。
- 小鸡吃大米,怎么实现。
1、创建一个小鸡对象,给它添加属性,胃能容纳多少粒米。2、写一个小鸡吃米方法,有一个for写吃米的过程,for(int i = 0; i < 变量+1; i++),也就是吃饱了就不吃了。如果是多只小鸡,就在外面加个for循环(默认是小鸡排队吃饱为止)。如果小鸡不排队的话,就用多线程的抢占机制来吃米(多线程的抢占调度机制)。
- 一对多
- 多对一
- 多对多。
- 一对一
- 新技术是什么东西。
- 为什么要使用这项技术。
- 如何使用这项技术。
- 在使用这个技术中遇到什么问题,怎么解决的。
- 这个技术的应用场景。
- 啥叫感恩?
- 解释 常见的几个java技术网站。
CSDN、博客园、GitHub、stackoverflow、知乎、开源中国
- 什么叫 b2b b2c 020 p2p B/S C/S
B2B:(Business To Business)商家对商家进行交易, 是指企业与企业之间通过专用网络或Internet,进行数据信息的交换、传递,开展交易活动的商业模式。它将企业内部网,通过 B2B 网站与客户紧密结合起来,通过网络的快速反应,为客户提供更好的服务,从而促进企业的业务发展。
B2C:(Business To Consumer)商家对个人进行交易。而其中文简称为“商对客”。“商对客”是电子商务的一种模式,也就是通常说的直接面向消费者销售产品和服务商业零售模式。
O2O即Online To Offline(在线离线/线上到线下),是指将线下的商务机会与互联网结合,让互联网成为线下交易的前台,这个概念最早来源于美国。O2O的概念非常广泛,只要产业链中既可涉及到线上,又可涉及到线下,就可通称为O2O。
P2P借贷是一种将非常小额度的资金聚集起来借贷给有资金需求人群的一种民间小额借贷模式。P2P是“Peer-to-Peer”的简写,个人对个人的意思,P2P借贷指个人通过第三方平台(P2P公司)在收取一定服务费用的前提下向其他个人提供小额借贷的金融模式。
C/S结构,即Client/Server(客户机/服务器)结构,是大家熟知的软件系统体系结构,通过将任务合理分配到Client端和Server端,降低了系统的通讯开销,可以充分利用两端硬件环境的优势。早期的软件系统多以此作为首选设计标准。
B/S结构,即Browser/Server(浏览器/服务器)结构,是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现,形成所谓3-tier结构。B/S结构,主要是利用了不断成熟的WWW浏览器技术,结合浏览器的多种Script语言(VBScript、JavaScript…)和ActiveX技术,用通用浏览器就实现了原来需要复杂专用软件才能实现的强大功能,并节约了开发成本,是一种全新的软件系统构造技术。随着Windows 98/Windows 2000将浏览器技术植入操作系统内部,这种结构更成为当今应用软件的首选体系结构。
- 不使用子查询,即使用表自联查。
- 避免函数索引,MySQL不像Oracle那样支持函数索引,即使d字段有索引,也会直接全表扫描。
- 用IN来替换OR,or的查询低效查询,in高效查询。
- .LIKE双百分号无法使用到索引
- 读取适当的记录LIMIT M,N
- 避免数据类型不一致
- 分组统计可以禁止排序
- 避免随机取记录
- 禁止不必要的ORDER BY排序
- 批量INSERT插入
两者都是表示查询结果集与java对象之间的一种关系,处理查询结果集,映射到java对象。
resultMap表示将查询结果集中的列一一映射到bean对象的各个属性。映射的查询结果集中的列标签可以根据需要灵活变化,并且,在映射关系中,还可以通过typeHandler设置实现查询结果值的类型转换,比如布尔型与0/1的类型转换。
例如:
SELECTID,COMMAND,DESCRIPTION,CONTENT FROM message WHERE 1=1
andCOMMAND=#{command}
andDESCRIPTION like '%' #{description} '%'
resultType 表示的是bean中的对象类,此时可以省略掉resultMap标签的映射,但是必须保证查询结果集中的属性和 bean对象类中的属性是一一对应的,此时大小写不敏感,但是有限制。
以下是resultType的写法,将其值设置成对应的java类上即可。不需要上述resultMap的映射关系。
SELECTID,COMMAND,DESCRIPTION,CONTENT FROM message WHERE 1=1
andCOMMAND=#{command}
andDESCRIPTION like '%' #{description} '%'
ParameterMap和resultMap类似,表示将查询结果集中列值的类型一一映射到java对象属性的类型上,在开发过程中不推荐这种方式。
一般使用parameterType直接将查询结果列值类型自动对应到java对象属性类型上,不再配置映射关系一一对应,例如上述代码中下划线部分表示将查询结果类型自动对应到hdu.terence.bean.Message的Bean对象属性类型。
resultMap和ParameterMap书写拼写要使用#{},resultType和parameterType类型使用${},使用例子如下:
Select ID,COMMAND from Message where COMMAND=#{command}
Select ID,COMMAND from Message where COMMAND=‘${command}’
前者解析为:
Select ID,COMMAND from Message where COMMAND=?具有预编译效果
后者解析为:
Select ID,COMMAND from Message where COMMAND=段子 不具有预编译效果
但是,例如当页面向后台传递一个列名(属性名)的时候,是不希望被预编译出一个?的,此时要用到$格式;
如:加上 order by${param} ,此时param是一个列名。