- 面试题总结
- Spring
- SpringMVC
- Shiro
- Maven
- 前端
- MySQL
- Java编程
- Mybatis
- Redis
- spring框架优点
- 轻量:Spring 是轻量的,基本的版本大约2MB
- 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们
- 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开
- 容器:Spring 包含并管理应用中对象的生命周期和配置
- MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品
- 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)
- 异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常
- 谈谈你对spring AOP 和 IOC 的理解,他们有什么区别?
- AOP与IOC给Spring的业务层提供支持,使程序松耦合,代码简洁
- AOP原理:即面向切面编程,就是提取公共部分,集中解决一些公共问题
- IOC原理:控制反转,在传统过程中,当某一个对象依赖于另一个对象时,会由该对象去创建另外一个对象。但是有了IOC之后,将创建过程交给IOC,由spring创建Bean,从而只需给该对象注入即可。
- 依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源
- 控制反转是从容器的角度在描述,容器控制应用程序,而容器反向的向应用程序注入应用程序所需要的外部资源
- spring配置bean实例化有哪些方法
- 无参构造方法实例化
- 工厂静态方法实例化
- 工厂实例方法实例化
- 请介绍一下Spring 框架中Bean的生命周期和作用域
生命周期:-
需找所有的bean根据bean定义的信息来实例化bean
-
使用依赖注入,spring按bean定义信息配置bean的所有属性
-
若bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递bean的ID。
-
若bean实现了BeanFactoryAware接口,工厂调用setBeanFactory() 方法传入工厂自身。
-
若bean实现了ApplicationContextAware()接口,setApplicationContext()方法会被调用
-
若BeanPostProcessor和bean关联,则它们的postProcessBeforeInitialization()方法被调用
-
若bean指定了init-method="init"方法、,它将被调用。
-
若有BeanPostProcessor和bean关联,则它们的postProcessAfterInitialization()方法被调用
注意:通过已上 *** 作,此时的Bean就可以被应用的系统使用,并讲保留在BeanFactory工厂中直到不再需要为止.但我们也可以通过9或者10进行销毁 -
若bean实现了DisposableBean接口,distroy()方法被调用
-
如果指定了destroy-method="close"定制的销毁方法,就调用这个方法
-
-
作用域:
- singleton 在Spring IoC 容器中仅存在一个Bean实例,Bean以单例方式存在,默认值
- prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()
- request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
- session 同一个HTTP Session 共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境
- globalSession 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境
-
Bean注入属性有哪几种方式?
- set方法注入
- 构造器注入
- 静态工厂注入
- 实例工厂注入
-
@Autowired 和 @Resource 之间的区别
- @Resource和@Autowired都是做bean的注入时使用
- @Resource是J2EE提供的注解
- @Autowired是spring提供的注解
- @Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
- @Resource默认按照ByName自动注入
-
什么是AOP , AOP的作用是什么?
- 面向切面编程,
- 作用:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来
-
Spring里面如何配置数据库驱动的
-
介绍一下Spring的事务管理
Spring事务本质是对数据库事务的支持,如果数据库不支持事务(例如MySQL的MyISAM引擎不支持事务),则Spring事务也不会生效。
所谓事务管理,其实就是“按照给定的事务规则来执行提交或者回滚 *** 作”。
- Spring事务管理接口
- PlatformTransactionManager: (平台)事务管理器
- TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
- TransactionStatus: 事务运行状态
- Spring并不直接管理事务,而是提供了多种事务管理器 ,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。 Spring事务管理器的接口是: org.springframework.transaction.PlatformTransactionManager ,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
-
Spring AOP通知有哪些类型 ?
- 前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。
- 正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
- 异常返回通知[After throwing advice]:在连接点抛出异常后执行。
- 返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
- 环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些 *** 作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
-
Spring的两种代理JDK和CGLIB的区别()
- 有两种CGLIB 和 JDK 两种方式
- CGLIB(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
- CGLIB封装了asm,可以在运行期动态生成新的class。
- CGLIB用于AOP,JDK中的proxy必须基于接口,CGLIB却没有这个限制。
- 原理区别 :
- 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
- 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
- 如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
- 有两种CGLIB 和 JDK 两种方式
-
什么叫事务传播行为?Spring支持几种事务传播行为?都是什么?
事务传播行为: 事务传播行为用来描述由某一个事务传播行为修饰的方法被嵌套进另一个方法时事务如何传播。
- PROPAGATION_REQUIRED – 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
- PROPAGATION_SUPPORTS – 支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY – 支持当前事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW – 新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED – 以非事务方式执行 *** 作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER – 以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED – 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的 *** 作。 -
事务的隔离级别
- 未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
- 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
- 可重复读(Repeated Read):在同一个事务内的查询都是事务开始时刻一致的,Mysql的InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻读(多个事务同时修改同一条记录,事务之间不知道彼此存在,当事务提交之后,后面的事务修改的数据将会覆盖前事务,前一个事务就像发生幻觉一样)
- 可串行化(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。
- 不可重复读和幻读的区别主要是:解决不可重复读需要锁定了当前满足条件的记录,而解决幻读需要锁定当前满足条件的记录及相近的记录。比如查询某个商品的信息,可重复读事务隔离级别可以保证当前商品信息被锁定,解决不可重复读;但是如果统计商品个数,中途有记录插入,可重复读事务隔离级别就不能保证两个事务统计的个数相同。
- SpringMVC框架是什么?常见的MVC框架有哪些?他们有什么区别?
什么是spring mvc:- 首先是一个MVC框架。
在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,是为了简化开发,减少出错。还是为了组内开发人员之间的配合。总之就是一种分层工作的办法。 - springMVC,是spring的一个子框架,当然拥有spring的特性,如依赖注入。
Spring下的子项目:Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
- 首先是一个MVC框架。
- 常见的框架:Spring Mybatis Dubbo Maven RabbitMQ Ehcache Redis Shiro等。
- Mybatis MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
- Dubbo Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用协议)远程服务调用方案,以及SOA服务治理方案。简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需要用的,只有在分布式的时候,才有dubbo这样的分布式服务框架的需求,并且本质上是个服务调用的东东,说白了就是个远程服务调用的分布式框架。
- Maven Maven这是个项目管理和构建自动化工具,越来越多的开发人员使用它来管理项目中的jar包。但是对于我们程序员来说,我们最关心的是它的项目构建功能。
- RabbitMQ 消息队列一般是在项目中,将一些无需即时返回且耗时的 *** 作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。
- Ehcache框架 EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。
- Redis框架 Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的 *** 作,而且这些 *** 作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改 *** 作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis数据库完全在内存中,使用磁盘仅用于持久性。相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。Redis可以将数据复制到任意数量的从服务器。
- Shiro框架 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权。Shiro在JavaSE和JavaEE项目中都可以使用。它主要用来处理身份认证,授权,企业会话管理和加密等。
-
阐述一下SpringMVC的运行流程?
-
用户发送请求至前端控制器DispatcherServlet。
-
DispatcherServlet收到请求调用HandlerMapping处理器映射器。
-
处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
-
DispatcherServlet调用HandlerAdapter处理器适配器。
-
HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
-
Controller执行完成返回ModelAndView。
-
HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
-
DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
-
ViewReslover解析后返回具体View。
-
DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
-
DispatcherServlet响应用户。
-
-
SpringMVC的主要组件有哪些 他们的作用是什么
-
前端控制器(DispatcherServlet):主要负责捕获来自客户端的请求和调度各个组件。
-
处理器映射器(HandlerMapping):根据url查找后端控制器Handler。
-
处理器适配器(HandlerAdapter):执行后端控制器(Handler),拿到后端控制器返回的结果ModelAndView后将结果返回给前端控制器DispatcherServlet。
-
后端控制器(处理器)(Handler):主要负责处理前端请求,完成业务逻辑,生成ModelAndView对象返回给HandlerAdapter。
-
视图解析器(ViewResolver):主要负责将从DispatcherServlet中拿到的ModelAndView对象进行解析,生成View对象返回给DispatcherServlet。
-
-
SpringMVC怎样设置重定向和转发的?默认是请求转发还是重定向?
在SpringMVC中仍然可以使用传统方式实现转发和重定向:
- request.getRequestDispatcher("").forward(request, response);
- response.sendRedirect("");
在SpringMVC中也提供了快捷方法实现转发和重定向 只要在返回视图时,使用如下方式指定即可:- redirect:/xxx.action
- forward:/xxx.action
controller 方法在提供了 String 类型的返回值之后,默认就是请求转发。我们也可以写成【forward:路径】的形式。
- SpringMVC怎么和Ajax相互调用的?
- 加入Jackson.jar
- 在配置文件中配置json 的映射
- 在接受Ajax 方法里面可以直接返回Object,List 等,但方法前面要加上@ResponseBody 注解。
- SpringMVC中如何解决post中文乱码问题,get又如何解决?
- get请求乱码
- 修改tomcat配置文件
- 对参数进行重新编码
- ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
- post请求乱码
- 在web.xml中配置CharacterEncodingFilter类
- SpringMVC如何做异常处理?
- 系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。
- springmvc中自带的简单异常处理器
- 自定义全局异常处理器
- @ExceptionHandler注解实现异常处理
- SpringMVC的控制器是不是单例模式,如果是,有什么问题,怎么解决?
- 默认情况下是单例模式,
- 在多线程进行访问的时候,有线程安全问题.但是不建议使用同步,因为会影响性能.
- 解决方案是在控制器里面不能写成员变量.
- SpringMVC常用的注解有哪些?
spring常见注解有:- @Controller
- @RestController
- @RequestMapping
- @PathVariable
- @RequestParam
- @RequestBody
- SpringMVC中函数的返回值是什么?
spring函数返回值- String
- ModelAndView:(不常用)
- 实体类
- void(不常用)
- @SessionAttribute
- 说一下什么是rbac,设计一个基于rbac的数据库模型,并解释每个模型之间的关系
- 全称:role-based access control 基于角色的权限访问控制
- 作用:实现访问控制
- RBAC权限授权的过程可以概括为:W是否可以对Z进行H的访问 *** 作,并对这个逻辑表达式进行判断是否为true的过程,也是将权限问题转换为Z、H的问题,W、Z、H构成了访问权限三元组。
- 权限与角色相关联,用户通过称为适当角色的成员而得到这些角色的权限,极大的简化了权限的管理
- 说一下什么是shrio,并且说出shiro的优点
- Apache Shiro 是Java 的一个安全框架。Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在JavaEE 环境。Shiro 可以帮助我们完成:认证、授权、加密、会话管理、与Web 集成、缓存等。
- 既然shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。
- shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro。
- java领域中spring security(原名Acegi)也是一个开源的权限管理框架,但是spring security依赖spring运行,而shiro就相对独立,最主要是因为shiro使用简单、灵活,所以现在越来越多的用户选择shiro。
- 简述Shiro的核心组件
Shiro的核心组件有三个:
- Subject
- SecurityManager
- Realms
- Subject 被Shiro 描述为一个主体,对于web应用来说,可以简单理解为用户
- Subject 的幕后推手是 SecurityManager,Subject 代表了当前用户的安全 *** 作,SecurityManager则管理所有用户的安全 *** 作。
- Realm 充当了 Shiro 与应用安全数据间的“桥梁”或者“连接器”。当切实与像用户帐户这类安全相关数据进行交互,执行认证(登录)和授权(访问控制)时,Shiro 会从应用配置的 Realm 中查找很多内容。
-
简述Shiro的认证过程
-
通过ini配置文件创建securityManager
-
调用subject.login方法主体提交认证,提交的token
-
securityManager进行认证,securityManager最终由ModularRealmAuthenticator进行认证。
-
ModularRealmAuthenticator调用IniRealm(给realm传入token) 去ini配置文件中查询用户信息
-
IniRealm根据输入的token(UsernamePasswordToken)从 shiro.ini查询用户信息,根据账号查询用户信息(账号和密码)
如果查询到用户信息,就给ModularRealmAuthenticator返回用户信息(账号和密码)如果查询不到,就给ModularRealmAuthenticator返回null -
ModularRealmAuthenticator接收IniRealm返回Authentication认证信息如果返回的认证信息是null,ModularRealmAuthenticator抛出异常(org.apache.shiro.authc.UnknownAccountException)
如果返回的认证信息不是null(说明inirealm找到了用户),对IniRealm返回用户密码 (在ini文件中存在)和 token中的密码 进行对比,如果不一致抛出异常(org.apache.shiro.authc.IncorrectCredentialsException)
-
-
简述Shiro的授权过程
- 对subject进行授权,调用方法isPermitted(“permission串”)
- SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
- ModularRealmAuthorizer执行realm(自定义的Realm)从数据库查询权限数据 调用realm的授权方法:doGetAuthorizationInfo
- realm从数据库查询权限数据,返回ModularRealmAuthorizer
- ModularRealmAuthorizer调用PermissionResolver进行权限串比对
- 如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。
- Maven有哪些优点和缺点
- 优点如下:
- 简化了项目依赖管理:
- 易于上手,对于新手可能一个"mvn clean package"命令就可能满足他的工作
- 便于与持续集成工具(jenkins)整合
- 便于项目升级,无论是项目本身升级还是项目使用的依赖升级。
- 有助于多模块项目的开发,一个模块开发好后,发布到仓库,依赖该模块时- 可以直接从仓库更新,而不用自己去编译。
- maven有很多插件,便于功能扩展,比如生产站点,自动发布版本等
- 缺点如下:
- maven是一个庞大的构建系统,学习难度大
- maven采用约定优于配置的策略(convention over configuration),虽然上手容易,但是一旦出了问题,难于调试。
- 当依赖很多时,m2eclipse 老是搞得Eclipse很卡。
- 中国的网络环境差,很多repository无法访问,比如google code, jboss 仓库无法访问等。
- Maven坐标由什么组成,分别代表什么意思
- 一般maven使用[groupID,artifactId,version,packaging]来表示一个项目的某个版本,有时还会使用classifier来表示项目的附属构建,常见的附属构建有javadoc和sources包。
-
groupId :定义当前Maven项目隶属的实际项目。首先,Maven项目和实际项目不一定是一对一的关系。比如SpringframeWork这一实际项目,其对应的Maven项目会有很多,如spring-core,spring-context等。这是由于Maven中模块的概念,因此,一个实际项目往往会被划分成很多模块。其次,groupId不应该对应项目隶属的组织或公司。原因很简单,一个组织下会有很多实际项目,如果groupId只定义到组织级别,而后面我们会看到,artifactId只能定义Maven项目(模块),那么实际项目这个层次将难以定义。最后,groupId的表示方式与Java包名的表达方式类似,通常与域名反向一一对应。
-
artifactId : 该元素定义当前实际项目中的一个Maven项目(模块),推荐的做法是使用实际项目名称作为artifactId的前缀。比如上例中的my-app。
-
version : 该元素定义Maven项目当前的版本
-
packaging :定义Maven项目打包的方式,首先,打包方式通常与所生成构件的文件扩展名对应,如上例中的packaging为jar,最终的文件名为my-app-0.0.1-SNAPSHOT.jar。也可以打包成war, ear等。当不定义packaging的时候,Maven 会使用默认值jar
-
classifier: 该元素用来帮助定义构建输出的一些附件。附属构件与主构件对应,如上例中的主构件为my-app-0.0.1-SNAPSHOT.jar,该项目可能还会通过一些插件生成如my-app-0.0.1-SNAPSHOT-javadoc.jar,my-app-0.0.1-SNAPSHOT-sources.jar, 这样附属构件也就拥有了自己唯一的坐标
-
- pom文件中常用的标签有哪些,分别代表什么意思
常见版:
父项目组Id 父项目构建Id父项目版本号 4.0.0 组Id 构件Id版本号 jar 项目名称 A maven project to study maven. org.apache.maven maven-artifact3.8.1 test spring-core org.springframework true 依赖项
详细版:
4.0.0 com.jsun.demo demo-maven010.0.1-SNAPSHOT jar org.springframework.boot spring-boot-starter-parent1.2.5.RELEASE Maven01 http://maven.apache.org 测试maven项目 001 jsun jsun@163.com developer com-jsun http://demo.jsun.com/jsun UTF-8 3.8.1 org.springframework spring-core1.2.6 jar test org.springframework.boot spring-boot-configuration-processortrue net.sf.json-lib json-libjdk15 2.4 junit junit${junit.version} myProject src/main/java ***.* org.apache.maven.plugins maven-source-plugin2.4 attach-sources package jar org.apache.maven.plugins maven-compiler-plugin1.8 UTF-8 true true true true 1.3 128m 512m -verbose -bootclasspath ${java.home}librt.jar org.apache.maven.plugins maven-assembly-pluginmake-assembly-platform package single package.xml patch falseorg.codehaus.mojo findbugs-maven-pluginHigh Default true target/site/findbugs maven-compiler-plugin 1.7 ${project.build.sourceEncoding}
- 常见的Maven私服的仓库类型有哪些?
- (宿主仓库)hosted repository
- (代理仓库)proxy repository
- (仓库组)group repository
- Maven 项目的关系有哪些?
- 注意:前提项目类型必须是maven项目 由maven统一管
-
依赖关系:
如果maven项目A需要使用Maven项目B的功能,需要将maven项目B的坐标配置在项目A的pom.xml文件中即可 那么A和B我们称为依赖关系
注意:maven会自动的根据依赖关系将相关资源导入到项目中,比如A依赖B但是B依赖C只在A中配置B的坐标而Maven也会根据链式的依赖关系将所有的资源导入到A中; -
继承关系:
maven中的子项目自动拥有父项目在pom.xml文件中管理的资源,子项目无需再重新配置java中的继承,是类与类之间的继承 子类从父类中继承的是功能maven中的继承 是项目与项目之间的继承, 子项目继承的是父项目的资源。
注意:像java中使用extends关键字来描述类与类之间的关系 maven中也要使用某种方式来声明项目之间的继承关系 -
聚合关系:
将本来在一个项目中声明的代码,分别拆分为多个项目来开发。
物理视图上是多个项目逻辑上在开发一个系统这样的项目关系成为聚合关系。
注意:
像继承关系一样,聚合关系也必须使用某种方式描述出来。
-
- 盒子模型的种类有几种,分别是什么?
- W3C盒模型(标准盒模型)
给一个标签添加:box-sizing:content-box;(元素默认)
这个标签就转换为了w3c盒模型
标签得实际宽度 = 设置的宽度 + border宽度 + padding的宽度 - 怪异盒模型(又称ie盒模型)
给一个标签添加:box-sizing:border-box;
这个标签就转换为了怪异盒模型
标签得实际宽度 = 设置的宽度
如果设置了padding和border就是从设置的实际宽高中减去,减去后才是内容的宽高。 - 区别
主要区别:对于宽高的定义不同
w3c盒模型:设置的宽度就等于内容的宽度
怪异盒模型:内容的宽度 = 设置的宽度 - border的宽度 - padding的宽度
- 容器中使用display 属性有几种值?都是什么意思?
- display:none;
设置元素隐藏,具体可见:display:none - display:block;
设置元素为块级元素,块级元素可以独占一行,可设宽高。 - display:inline;
设置元素为行内元素,一行可有多个行内块元素,可设宽高。 - display:inline-block
设置元素为行内块元素,既有行内元素的(一行可有多个)特性,又有块元素的(可设宽高)特性 - display:inline-table
inline-table得到的是,外面是“内联盒子”,里面是“table盒子”。 - display:table
元素会作为块级表格来显示,类似 table,表格前后带有换行符;配合table-cell使用可实现水平垂直居中,具体可见:水平垂直居中 - table-row
元素会作为一个表格行显示,类似 tr; - table-cell
元素会作为一个表格单元格显示,类似 td和 th。 - display:list-item
为元素内容生成一个块型盒,随后再生成一个列表型的行内盒。
会把元素作为列表显示,要完全模仿列表的话还需要加上 list-style-position,list-style-type
- display:none;
- d性盒子属性flex-direction的值有几种?都是什么意思?
- flex项目的属性
- order
- flex-grow
- flex-shrink
- flex-basis
- flex
- align-self
- order属性:order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
- flex-grow属性:flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。
- flex-shrink属性:flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。
- flex-basis属性:flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。 - flex属性:flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。 - align-self属性:align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
- 数据库中的锁包括什么
相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。
MySQL大致可归纳为以下3种锁:
- 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
- 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
-
数据库的优化
- 查询语句中不要使用select *
- 尽量减少子查询,使用关联查询(left join,right join,inner join)替代
- 减少使用IN或者NOT IN ,使用exists,not exists或者关联查询语句替代
- or 的查询尽量用 union或者union all 代替(在确认没有重复数据或者不用剔除重复数据时,union all会更好)
- 应尽量避免在 where 子句中使用!=或<> *** 作符,否则将引擎放弃使用索引而进行全表扫描。
- 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0
-
数据库的索引是什么
- 官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。
- 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。
- 我们通常所说的索引,包括聚集索引、覆盖索引、组合索引、前缀索引、唯一索引等,没有特别说明,默认都是使用B+树结构组织(多路搜索树,并不一定是二叉的)的索引。
-
索引的优缺点
- 优点
- 提高数据的检索速度,降低数据库的IO成本:使用索引的意义就是通过缩小表中需要查询的记录的数目村民个人加快搜索的速度
- 降低数据排序的成本,降低CPU消耗:索引之所以查的快,是因为先将数据排好序,若该字段正好需要排序,则正好降低了排序的成本
- 缺点
- 占用存储空间:索引实际上也是一张表,记录了主键与索引字段,一般以索引文件的形式存储在磁盘上
- 降低更新表的速度:表的数据发生了变化,对应的索引也需要一起变更,从而降低了更新速度。否则索引指向的物理数据可能不对,这也是索引失效的原因之一
- 事务
是数据库 *** 作的最小工作单元,是作为单个逻辑工作单元执行的一系列 *** 作;这些 *** 作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的 *** 作集合。
-
原子性(Atomicity)事务是一个原子 *** 作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
-
一致性(Consistency)事务在完成时,必须是所有的数据都保持一致状态。
-
隔离性(Isolation)并发事务执行之间无影响,在一个事务内部的 *** 作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性。
-
持久性(Durability)一旦事务完成,数据库的改变必须是持久化的。
在企业级应用中,多用户访问数据库是常见的场景,这就是所谓的事务的并发。事务并发所可能存在的问题:
- 脏读:一个事务读到另一个事务未提交的更新数据。
- 不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
- 幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
- 丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。
- MySQL事务隔离级别
- READ-UNCOMMITTED(未提交读):事务中的修改,即使没有提交,对其他事务也都是可见的。会导致脏读。
- READ-COMMITTED(提交读): 事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。会导致不可重复读。这个隔离级别,也可以叫做“不可重复读”。
- REPEATABLE-READ(可重复读): 一个事务按相同的查询条件读取以前检索过的数据,其他事务插入了满足其查询条件的新数据。产生幻行,会导致幻读。(MySQL 默认隔离级别)
- SERIALIZABLE(可串行化):强制事务串行执行。
- MySQL InnoDB 存储引擎的默认支持的隔离级别是 REPEATABLE-READ(可重复读)。
- 编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替输出到控制台
这个代码有待优化 :
public static void main(String[] args) throws IOException { List a = new ArrayList(); List b = new ArrayList(); try { BufferedReader bra = new BufferedReader( new InputStreamReader( new FileInputStream(new File("D:/Develop/a.txt"))));//桌面上的a文件 BufferedReader brb = new BufferedReader( new InputStreamReader( new FileInputStream(new File("D:/Develop/b.txt"))));//桌面上的b文件 String str = null; while ((str=bra.readLine()) != null){ a.add(str); } while ((str=brb.readLine()) != null){ b.add(str); } String s1 = a.get(0).toString(); String s2 = b.get(0).toString(); char[] chars1 = s1.toCharArray(); char[] chars2 = s2.toCharArray(); int index = chars1.length; if(chars1.length > chars2.length){ index = chars2.length; } for (int i = 0; i < index; i++) { System.out.print(chars1[i] + "" + chars2[i]); } if(chars1.length > index){ for (int i = index; iindex){ for (int i = index; i
- 给你一个字符串如:7as8asad6aad2as。让你编程输出里面的数字7862.
public class NumTest { public static void main(String[] args) { String str = "7as8asad6aad2as"; String s = str.replaceAll("[^0-9]", ""); System.out.println(s); } }
- 请写出遍历HashMap
的代码 public static void main(String[] args) { Mapmap = new HashMap<>(); map.put("k1","Andy"); map.put("k2","Sami"); map.put("k3","Sonja"); Set > entries = map.entrySet(); for (Map.Entry entry : entries) { String key = entry.getKey(); Object value = entry.getValue(); System.out.println("key = " + key + "t" + "value = " + value); } } Entry:
Mybatis
- 由于Map中存放的元素均为键值对,故每一个键值对必然存在一个映射关系。 Map中采用Entry内部类来表示一个映射项,映射项包含Key和Value (我们总说键值对键值对, 每一个键值对也就是一个Entry)Map.Entry里面包含getKey()和getValue()方法
- entrySet
entrySet是 java中 键-值 对的集合,Set里面的类型是Map.Entry,一般可以通过map.entrySet()得到。
entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V。
用来遍历map的一种方法。
即通过getKey()得到K,getValue得到V。- keySet
还有一种是keySet, keySet是键的集合,Set里面的类型即key的类型Redis
- Mybatis修改一个对象时,部分字段为空时不修改,怎么编写SQL语句(动态SQL)
- Redis的底层数据结构
六种底层数据结构:
- 简单动态字符串
- 双向链表
- 字典
- 跳跃表
- 整数集合
- 压缩列表
Redis为什么那么快
- 采用了多路复用io阻塞机制
- 数据结构简单, *** 作节省时间
- 是C语言编写的,运行在内存中,自然速度快
- 采用单线程,避免了不必要的上下文切换和竞争条件,安全;也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁 *** 作,没有因为可能出现死锁而导致的性能消耗;
- 使用底层模型不同;它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求
Redis保证数据一致性
- 所谓的redis数据一致性即当进行修改或者保存、删除之后,redis中的数据也应该进行相应变化,不然用户再次查询的时候很可能查询出已经删除过的脏数据。
方案:
- 当我们在进行插入 *** 作之后,我们把该条数据取出来同时保存到redis缓存中去,这样再次查询缓存的时候我们也可以看到新的数据
- 定期清除redis中的数据,例如设置一个定时任务,每当一个小时的时候就会清除redis中的数据,也就是让redis中的数据失效,然后再次保存、删除的时候之前的 redis中的数据已经不存在,所以相当于是将数据重新设置到redis中去,所以可以保证数据的一致性。
Redis持久化方式,数据崩了怎么办
redis支持四种持久化方式:
- Snapshotting(快照)也是默认方式
- Append-only file(缩写aof)的方式
- 虚拟内存方式
- diskstore方式
- 快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。
- aof 比快照方式有更好的持久化性,是由于在使用aof持久化方式时,redis会将每一个收到的写命令都通过write函数追加到文件中(默认是appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。
- redis的虚拟内存,就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他需要访问的数据。尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redis server外。另外的能够提高数据库容量的办法就是使用vm把那些不经常访问的数据交换的磁盘上。
- diskstore方式是作者放弃了虚拟内存方式后选择的一种新的实现方式,也就是传统的B-tree的方式。其实DiskStore类似于Hash算法,首先通过SHA1算法把Key转化成一个40个字符的Hash值,然后把Hash值的前两位作为一级目录,然后把Hash值的三四位作为二级目录,最后把Hash值作为文件名,类似于“/0b/ee/0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33”形式。不过DiskStore有个缺点,就是有可能发生两个不同的Key生成一个相同的SHA1 Hash值,这样就有可能出现丢失数据的问题。不过这种情况发生的几率比较少,所以是可以接受的。根据作者的意图,未来可能使用B+tree来替换这种高度依赖文件系统的实现方法。
数据崩了怎么办:
- Redis中的数据存在内存中,如果突然宕机,那么内存中的数据将全部丢失。如果数据能从后端数据库恢复还好,如果数据只存在Redis中,那数据就全丢失了。并且如果请求量很多,MySQL服务器的压力会很大。所以最好的方式是对数据进行持久化,并能当宕机的时候能快速恢复
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)