当前位置: 首页 > news >正文

平安建设 十户长网站地址柏乡网站建设

平安建设 十户长网站地址,柏乡网站建设,江苏神禹建设有限公司网站,大连网站建设方案案例分享一下自己总结的7万多字java面试笔记和一些面试视频#xff0c;简历啥的#xff0c;已大厂上岸 自己总结的面试简历资料#xff1a;https://pan.quark.cn/s/8b602fe53b58 文章目录 SSMspringspring 的优点#xff1f;IoC和AOP的理解**Bean 的生命周期****列举一些重要…分享一下自己总结的7万多字java面试笔记和一些面试视频简历啥的已大厂上岸 自己总结的面试简历资料https://pan.quark.cn/s/8b602fe53b58 文章目录 SSMspringspring 的优点IoC和AOP的理解**Bean 的生命周期****列举一些重要的Spring模块****Spring框架中用到了哪些设计模式****Component和Bean的区别是什么****Spring事务管理的方式有几种****Spring事务中的隔离级别有哪几种****Spring事务中有哪几种事务传播行为**spring常用的注入方式有哪些spring中的bean是线程安全的吗 springmvcSpringMVC的流程JSP 九大内置对象和四大作用域spring mvc有哪些组件RequestMapping的作用是什么Autowired的作用是什么Autowired 与Resource的区别Springmvc的优点:FactoryBean 与 BeanFactory 有什么区别Transactional 注解哪些情况下会失效项目中如何用 Spring 和 Spring MVC 框架的 mybatisMyBatis是什么有什么作用Mybaits 的优缺点#{} 和 ${} 的区别MyBatis 中实体类的属性名与表中的字段名不一致怎么处理Mapper 接口如何与写 SQL 的 XML 文件进行绑定的MyBatis 如何批量插入MyBatis 是如何与 Spring 集成的 springboot**为什么要用 Spring Boot****Spring Boot 的核心配置文件有哪几个它们的区别是什么****Spring Boot 的核心注解是哪个它主要由哪几个注解组成的**常用注解**开启 Spring Boot 特性有哪几种方式****运行 Spring Boot 有哪几种方式****Spring Boot 自动配置原理是什么**SpringBoot 有几种读取配置文件的方式**你如何理解 Spring Boot 配置加载顺序****Spring Boot 如何定义多套不同环境配置****Spring Boot 可以兼容老 Spring 项目吗如何做** springCloud微服务架构什么是微服务架构Spring Cloud 是什么SpringCloud的优缺点SpringBoot和SpringCloud的区别pringCloud由什么组成Spring Cloud 和dubbo区别?Eureka服务注册和发现是什么意思Spring Cloud 如何实现什么是EurekaEureka怎么实现高可用什么是Eureka的自我保护模式DiscoveryClient的作用Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别 Zuul什么是网关?网关的作用是什么网关与过滤器有什么区别常用网关框架有那些Zuul与Nginx有什么区别既然Nginx可以实现网关为什么还需要使用Zuul框架Zuul网关如何搭建集群 Ribbon负载平衡的意义什么Ribbon是什么Nginx与Ribbon的区别Ribbon底层实现原理LoadBalanced注解的作用 Hystrix什么是断路器什么是 Hystrix谈谈服务雪崩效应在微服务中如何保护服务?服务雪崩效应产生的原因谈谈服务降级、熔断、服务隔离服务降级底层是如何实现的 Feign什么是FeignSpringCloud有几种调用接口方式Ribbon和Feign调用服务的区别 Dubbo介绍一下DubboDubbo有哪些核心组件Dubbo框架分了哪些层Dubbo支持哪些序列化方式?Dubbo的主要作用Dubbo有哪些负载均衡策略**你觉得用 Dubbo 好还是 Spring Cloud 好** 数据库mysql事务的四大特性事务有哪些隔离级别数据库如何优化**MySql集群主从复制**主从同步mysql默认的存储引擎是什么MyISAM与InnoDB的区别Innodb引擎有什么特性数据库的三范式是什么有什么作用Mysql驱动程序是什么如何连接MySQL服务端、关闭连接左连接、右连接、内连接和全外连接的区别**什么是表分区****表分区与分表的区别****表分区有什么好处****分区表的限制因素****如何判断当前MySQL是否支持分区****MySQL支持的分区类型有哪些**如何实现分库分表怎么配置索引什么是索引什么场景使用索引如何创建与删除索引的种类有哪些MySQL创建和使用索引的注意事项说一些索引失效的情况索引对性能有哪些影响 列值为NULL时查询是否会用到索引**缓存****为什么使用数据索引能提高效率**锁**行级锁定的优点****行级锁定的缺点**MySQL的乐观锁和悲观锁MySQL中如何避免死锁MySQL 单表上亿怎么优化分页查询MySQL有哪些常用函数与Oracle相比Mysql有什么优势MySQL如何进行慢SQL优化如何避免sql注入什么是XSS攻击如何避免什么是CSRF攻击如何避免 OracleOracle中字符串链接符是什么**Oracle中有哪几种文件****Oracle优化**Oracle有哪几种索引?哪些因素影响oracle查询性能Oracle中排序对性能的影响**Oracle中字符串用什么符号链接**Oracle有哪些备份方式冷备和热备的优缺点Oracle怎么分页**怎样创建一个视图,视图的好处, 视图可以控制权限吗?****rowid, rownum的定义**oracle中存储过程游标和函数的区别Oracle怎样实现每天备份一次Oracle分区有哪些作用?Oracle数据库如何迁移oracle临时表有几种。Oracle存储文件类型的字段oracle数据库中有多行相同数据,只留一行怎么实现? Redis介绍一下RedisRedis支持哪些数据类型redis受到攻击怎么办Redis 缓存穿透、击穿、雪崩现象及解决方案缓存穿透缓存击穿缓存雪崩Redis 缓存穿透、击穿、雪崩的区别 Redis有哪些优缺点Redis的哨兵原理心跳检测 redis主从复制全量复制增量复制Redis主从同步策略 Redis持久化机制有哪些各有什么优缺点Redis使用过程中的注意事项Redis过期键的删除策略有哪些为什么Redis所有数据放到内存中说说Redis的同步机制说说Redis集群说说遇到的Redis集群方案不可用的情况Redis如何设置密码Redis 集群会有写操作丢失吗Redis如何做内存优化Redis集群之间是如何复制Redis如何选择数据库说一说你对Redis的事务的理解Redis如何设置过期时间MySQL里有2000w数据redis中只存20w的数据如何保证redis中的数据都是热点数据内存淘汰策略 Redis事务支持隔离性吗Redis事务保证原子性吗支持回滚吗 nginx什么是Nginx为什么要用NginxNginx怎么处理请求的什么是正向代理和反向代理Nginx的优缺点Nginx应用场景如何用Nginx解决前端跨域问题限流怎么做的漏桶算法Nginx负载均衡的算法怎么实现的?策略有哪些? Linuxlinux如何添加新系统用户?什么是bash别名linux指令-ls删除目录 rmdir改变 linux 系统文件或目录的访问权限 chmod查看文件内容有哪些命令可以使用复制文件用哪个命令如果需要连同文件夹一块复制呢如果需要有提示功能呢删除文件用哪个命令如果需要连目录及目录下文件一块删除呢删除空文件夹用什么命令Linux 下命令有哪几种可使用的通配符分别代表什么含义?用什么命令对一个文件的内容进行统计(行号、单词数、字节数)搜索文件用什么命令? 格式是怎么样的?使用什么命令查看用过的命令列表? docker什么是docker什么是docker镜像什么是docker容器docker容器有几种状态docker容器内部机制容器与主机之间的数据拷贝启动容器并挂在目录Docker容器有几种状态docker常用命令 JVMJVM内存结构内存划分一、程序计数器(Program Counter Register)二、Java虚拟机栈(VM Stack)三、本地方法栈(Native Method Stack)四、堆(Heap)五、方法区六直接内存 GC垃圾回收GC 优化新生代和老年代的区别(**阿里面试官的题目**)新生代老年代永久代元数据 JDK,JRE,JVM区别**说一下堆栈的区别****队列和栈是什么有什么区别****说一下类加载的执行过程**什么是乐观锁和悲观锁悲观锁乐观锁 Zookeeper**zookeeper 是什么****zookeeper 都有哪些功能****zookeeper 有几种部署模式****zookeeper 怎么保证主从节点的状态同步****集群中为什么要有主节点****集群中有 3 台服务器其中一个节点宕机这个时候 zookeeper 还可以使用吗**说一下 zookeeper 的通知机制 集合ArrayList和Vector的联系和区别Collection和Collections有什么区别List、Set、Map 之间的区别是什么HashMap和Hashtable 有什么区别如何决定使用HashMap还是TreeMapHashMap原理手动实现 HashMapArray和ArrayList有何区别如何实现数组和List之间的转换哪些集合类是线程安全的Iterator怎么使用有什么特点 多线程线程池什么是线程什么是线程安全和线程不安全线程安全线程不安全什么是多线程优缺点什么是多线程的上下文切换如何创建、启动 Java 线程**什么是线程池**一个线程池包括以下四个基本组成部分常见线程池线程池常用参数**为什么要使用线程池**如何在两个线程之间共享数据 java基础和equals的区别是什么?hashCode()相同equals()也一定为true吗final finally finalize()区别如何将字符串反转String类的常用方法有哪些普通类和抽象类有哪些区别方法重载和重写是什么有什么区别内存泄漏和内存溢出的区别什么是多态如何实现有什么好处用Lambda表达式实现RunnableString sabcd;创建了几个对象String s new String(xyz);创建几个String对象序列化**为什么要序列化** **什么情况下需要序列化****序列化的方式**序列化技术选型的几个关键点**Java 是如何实现序列化的****JAVA序列化中常见的问题** SSM SSM搭建的版本有很多例如有一个版本可以这么搭建两个核心配置文件web.xml,applicationContext.xml。1.前端控制器DispatcherServlet 2.过滤器CharacterEncodingFilter applicationContext.xml 1.扫描包 context:component-scan base-packagecn/ 2.mvc驱动 mvc:annotation-driven/ 3.事务驱动 tx:annotation-driven transaction-managertxManager/ 4.配置数据源 5.SqlSessionFactoryBean 6.配置事务 7.数据映射器 8.视图解析器 spring Spring是一个开源的轻量级的Java开发框架。是一种简化应用程序的开发。 在spring出来之前service层调用dao层都是用new的方式在spring出来之后service层和到dao层都会放在spring容器去管理这是spring的第一种特性我们称之为IOC控制反转。 spring还有一种特性我们称之为AOP大白话所谓“面向切面”说白了就是专门的人干专门的事。在项目很多公有的或是要被重复被调用的模块可以被抽取出来利用的就AOP的特性例如日志模块。spring 的优点 1.降低了组件之间的耦合性 实现了软件各层之间的解耦 2.可以使用容易提供的众多服务如事务管理消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术利用它很容易实现如权限拦截运行期监控等功能 5.容器提供了众多的辅助类能加快应用的开发 6.spring对于主流的应用框架提供了集成支持如hibernateJPAStruts等 7.spring属于低侵入式设计代码的污染极低 8.独立于各种应用服务器 9.spring的DI机制降低了业务对象替换的复杂性 10.Spring的高度开放性并不强制应用完全依赖于Spring开发者可以自由选择spring的部分或全部 IoC和AOP的理解 IoC控制反转 就是 将原本在程序中手动创建对象的控制权交由Spring框架来管理。 ​ IoC 容器是 Spring 用来实现 IoC 的载体 IoC 容器实际上就是个Mapkeyvalue,Map 中存放的是各种对象。将对象之间的相互依赖关系交给 IoC 容器来管理并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样当我们需要创建一个对象的时候只需要配置好配置文件/注解即可完全不用考虑对象是如何被创建出来的。 aop面向切面编程 面向切面编程AOP完善spring的依赖注入DI面向切面编程在spring中主要表现为两个方面 1.面向切面编程提供声明式事务管理 2.spring支持用户自定义的切面 面向切面编程aop是对面向对象编程oop的补充 面向对象编程将程序分解成各个层次的对象面向切面编程将程序运行过程分解成各个切面。 aop框架具有的两个特征 1.各个步骤之间的良好隔离性 2.源代码无关性 能够将那些与业务无关却为业务模块所共同调用的逻辑或责任例如事务处理、日志管理、权限控制等封装起来便于减少系统的重复代码降低模块间的耦合度并有利于未来的可拓展性和可维护性。 使用 AOP 之后我们可以把一些通用功能抽象出来在需要用到的地方直接使用即可这样大大简化了代码量。我们需要增加新功能时也方便这样也提高了系统扩展性。日志功能、事务管理等等场景都用到了 AOP 。 Bean 的生命周期 1.Bean容器找到配置文件中Spring Bean的定义。 2.Bean容器利用Java Reflection API创建一个Bean的实例。 3.如果涉及到一些属性值利用set()方法设置一些属性值。 4.如果Bean实现了BeanNameAware接口调用setBeanName()方法传入Bean的名字。 5.如果Bean实现了BeanClassLoaderAware接口调用setBeanClassLoader()方法传入ClassLoader对象的实例。 6.如果Bean实现了BeanFactoryAware接口调用setBeanClassFacotory()方法传入ClassLoader对象的实例。 7.与上面的类似如果实现了其他*Aware接口就调用相应的方法。 8.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象执行postProcessBeforeInitialization()方法。 9.如果Bean实现了InitializingBean接口执行afeterPropertiesSet()方法。 10.如果Bean在配置文件中的定义包含init-method属性执行指定的方法。 11.如果有和加载这个Bean的Spring容器相关的BeanPostProcess对象执行postProcessAfterInitialization()方法。 12.当要销毁Bean的时候如果Bean实现了DisposableBean接口执行destroy()方法。 13.当要销毁Bean的时候如果Bean在配置文件中的定义包含destroy-method属性执行指定的方法。列举一些重要的Spring模块 Spring Core基础可以说Spring其他所有的功能都依赖于该类库。主要提供IOC和DI功能。 Spring Aspects该模块为与AspectJ的集成提供支持。 Spring AOP提供面向方面的编程实现。 Spring JDBCJava数据库连接。 Spring JMSJava消息服务。 Spring ORM用于支持Hibernate等ORM工具。 Spring Web为创建Web应用程序提供支持。 Spring Test提供了对JUnit和TestNG测试的支持。 Spring框架中用到了哪些设计模式 1.工厂设计模式Spring使用工厂模式通过BeanFactory和ApplicationContext创建bean对象。 2.代理设计模式Spring AOP功能的实现。 3.单例设计模式Spring中的bean默认都是单例的。 4.模板方法模式Spring中的jdbcTemplate、hibernateTemplate等以Template结尾的对数据库操作的类它们就使用到了模板模式。 5.包装器设计模式我们的项目需要连接多个数据库而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。 6.观察者模式Spring事件驱动模型就是观察者模式很经典的一个应用。 7.适配器模式Spring AOP的增强或通知Advice使用到了适配器模式、Spring MVC中也是用到了适配器模式适配Controller。 Component和Bean的区别是什么 1.作用对象不同。Component注解作用于类而Bean注解作用于方法。 2.Component注解通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中我们可以使用ComponentScan注解定义要扫描的路径。Bean注解通常是在标有该注解的方法中定义产生这个bean告诉Spring这是某个类的实例当我需要用它的时候还给我。 3.Bean注解比Component注解的自定义性更强而且很多地方只能通过Bean注解来注册bean。比如当引用第三方库的类需要装配到Spring容器的时候就只能通过Bean注解来实现。 Spring事务管理的方式有几种 1.编程式事务在代码中硬编码不推荐使用。 2.声明式事务在配置文件中配置推荐使用分为基于XML的声明式事务和基于注解的声明式事务。 Spring事务中的隔离级别有哪几种 ISOLATION_DEFAULTPlatfromTransactionManager 默认隔离级别使用数据库默认的事务隔离级别。ISOLATION_READ_UNCOMMITTED读未提交允许事务在执行过程中读取其他事务未提交的数据。ISOLATION_READ_COMMITTED读已提交允许事务在执行过程中读取其他事务已经提交的数据。ISOLATION_REPEATABLE_READ可重复读在同一个事务内任意时刻的查询结果都是一致的。ISOLATION_SERIALIZABLE最严格的事务序列化执行。 Spring事务中有哪几种事务传播行为 在TransactionDefinition接口中定义了八个表示事务传播行为的常量。 支持当前事务的情况 PROPAGATION_REQUIRED如果当前存在事务则加入该事务如果当前没有事务则创建一个新的事务。 PROPAGATION_SUPPORTS 如果当前存在事务则加入该事务如果当前没有事务则以非事务的方式继续运行。 PROPAGATION_MANDATORY 如果当前存在事务则加入该事务如果当前没有事务则抛出异常。mandatory强制性。 不支持当前事务的情况 PROPAGATION_REQUIRES_NEW 创建一个新的事务如果当前存在事务则把当前事务挂起。 PROPAGATION_NOT_SUPPORTED 以非事务方式运行如果当前存在事务则把当前事务挂起。 PROPAGATION_NEVER 以非事务方式运行如果当前存在事务则抛出异常 spring常用的注入方式有哪些 1、xml中配置 2、注解 bean 的申明、注册 Component //注册所有bean Controller //注册控制层的bean Service //注册服务层的bean Repository //注册dao层的bean bean 的注入 Autowired 作用于 构造方法、字段、方法常用于成员变量字段之上。 Autowired Qualifier 注入指定 bean 的名称 Resource JDK 自带注解注入可以指定 bean 的名称和类型等 spring中的bean是线程安全的吗 Spring 不保证 bean 的线程安全。 默认 spring 容器中的 bean 是单例的。当单例中存在竞态条件即有线程安全问题。 springmvc spring mvc 是 spring web mvcspring 框架的一部分一个 mvc 设计模型的表现层框架。 Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架它是Spring的一个模块,无需中间整合层来整合 它和Struts2一样都属于表现层的框架。在web模型中MVC是一种很流行的框架通过把ModelViewController分离把较为复杂的web应用分成逻辑清晰的几部分简化开发减少出错方便组内开发人员之间的配合。 Spring MVC下我们一般把后端项目分为Service层处理业务、Dao层数据库操作、Entity层实体类、Controller层控制层返回数据给前台页面。 当用户发送请求到springmvc中的前端控制器中通过映射器和适配器返回ModelAndView对象到客户端。这就是SpringMVC的基本原理。 SpringMVC的流程 1用户发送请求至前端控制器DispatcherServlet 2 DispatcherServlet收到请求后调用HandlerMapping处理器映射器请求获取Handle 3处理器映射器根据请求url找到具体的处理器生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet 4DispatcherServlet 调用 HandlerAdapter处理器适配器 5HandlerAdapter 经过适配调用 具体处理器(Handler也叫后端控制器) 6Handler执行完成返回ModelAndView 7HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet 8DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析 9ViewResolver解析后返回具体View 10DispatcherServlet对View进行渲染视图即将模型数据填充至视图中 11DispatcherServlet响应用户。 JSP 九大内置对象和四大作用域 名称 类型 含义 获取方式 request HttpSevletRequest 封装所有请求信息 方法参数 response HttpServletResponse 封装所有响应信息 方法参数 session HttpSession 封装所有会话信息 req.getSession() application ServletContext 所有信息 getServletContext(); out PrintWriter 输出对象 response.getWriter() exception Exception 异常对象 response.getWriter() page Object 当前页面对象 pageContext PageContext 获取其他对象 config ServletConfig 配置信息 四大作用域 1.page 在当前页面不会重新实例化 2.request 在一次请求中同一个对象下次请求重新实例化一个request对象。 3.session 一次会话中只有一个session对象依赖于cookie只要Cookie中传递的Jsessionid不变Session就不会重新实例化在不超过默认生效时间的情况下 4.application:只有在tomcat启动项目时实例化只有当关闭tomcat服务器时销毁application spring mvc有哪些组件 前端控制器DispatcherServlet处理器映射器HandlerMapping处理器适配器HandlerAdapter拦截器HandlerInterceptor语言环境处理器LocaleResolver主题解析器ThemeResolver视图解析器ViewResolver文件上传处理器MultipartResolver异常处理器HandlerExceptionResolver数据转换DataBinder消息转换器HttpMessageConverter请求转视图翻译器RequestToViewNameTranslator页面跳转参数管理器FlashMapManager处理程序执行链HandlerExecutionChain RequestMapping的作用是什么 RequestMapping 是一个注解用来标识 http 请求地址与 Controller 类的方法之间的映射。 可作用于类和方法上方法匹配的完整是路径是 Controller 类上 RequestMapping 注解的 value 值加上方法上的 RequestMapping 注解的 value 值。 Autowired的作用是什么 Autowired 是一个注释它可以对类成员变量、方法及构造函数进行标注让 spring 完成 bean 自动装配的工作。 Autowired 默认是按照类去匹配配合 Qualifier 指定按照名称去装配 bean。 Autowired 与Resource的区别 Autowired与Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。 Autowired默认按类型装配这个注解是属业spring的默认情况下必须要求依赖对象必须存在如果要允许null值可以设置它的required属性为false Resource这个注解属于J2EE的默认按照名称进行装配名称可以通过name属性进行指定如果没有指定name属性当注解写在字段上时默认取字段名进行安装名称查找如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是如果name属性一旦指定就只会按照名称进行装配。 推荐使用Resource注解在字段上这样就不用写setter方法了并且这个注解是属于J2EE的减少了与spring的耦合。这样代码看起就比较优雅。 Springmvc的优点: 如下 1它是基于组件技术的。全部的应用对象,无论控制器和视图,还是业务对象之类的都是 java组件.并且和Spring提供的其他基础结构紧密集成 2不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的) 3可以任意使用各种视图技术,而不仅仅局限于JSP 4 支持各种请求资源的映射策略 5它应是易于扩展的 FactoryBean 与 BeanFactory 有什么区别 BeanFactory 是 IoC 底层容器提供了 bean 的管理FactoryBean 是创建 Bean 的一种方式帮助实现复杂的初始化逻辑 Transactional 注解哪些情况下会失效 1、Transactional 作用在非 public 修饰的方法上 2、Transactional 作用于接口使用 CGLib 动态代理 3、Transactional 注解属性 propagation 设置以下三种可能导致无法回滚 SUPPORTS如果当前存在事务则加入该事务如果当前没有事务则以非事务的方式继续运行。NOT_SUPPORTED以非事务方式运行如果当前存在事务则把当前事务挂起。NEVER以非事务方式运行如果当前存在事务则抛出异常。 4、同一类中加 Transactional 方法被无 Transactional 的方法调用事务失效 5、Transactional 方法内异常被捕获 6、默认 RuntimeException 和 Error 及子类抛出会回滚rollbackFor 指定的异常及子类发生才会回滚 7、数据库不支持事务如 MySQL 使用 MyISAM 存储引擎 8、Spring 的配置文件中未配置事务注解生效 Spring MVC的异常处理 答可以将异常抛给Spring框架由Spring框架来处理我们只需要配置简单的异常处理器在异常处理器中添视图页面即可。 SpringMvc的核心入口类是什么,Struts1,Struts2的分别是什么 答SpringMvc的是DispatchServlet,Struts1的是ActionServlet,Struts2的是StrutsPrepareAndExecuteFilter。 SpringMvc的控制器是不是单例模式,如果是,有什么问题,怎么解决 答是单例模式,所以在多线程访问的时候有线程安全问题,不要用同步,会影响性能的,解决方案是在控制器里面不能写字段。 SpingMvc中的控制器的注解一般用那个,有没有别的注解可以替代 答一般用Conntroller注解,表示是表现层,不能用用别的注解代替。 RequestMapping注解用在类上面有什么作用 答是一个用来处理请求地址映射的注解可用于类或方法上。用于类上表示类中的所有响应请求的方法都是以该地址作为父路径。 怎么样把某个请求映射到特定的方法上面 答直接在方法上面加上注解RequestMapping,并且在这个注解里面写上要拦截的路径。 如果在拦截请求中,我想拦截get方式提交的方法,怎么配置 答可以在RequestMapping注解里面加上methodRequestMethod.GET。 怎么样在方法里面得到Request,或者Session 答直接在方法的形参中声明request,SpringMvc就自动把request对象传入。 如果想在拦截的方法里面得到从前台传入的参数,怎么得到 答直接在形参里面声明这个参数就可以,但必须名字和传过来的参数一样。 如果前台有很多个参数传入,并且这些参数都是一个对象的,那么怎么样快速得到这个对象 答直接在方法中声明这个对象,SpringMvc就自动会把属性赋值到这个对象里面。 SpringMvc中函数的返回值是什么 答返回值可以有很多类型,有String, ModelAndView但一般用String比较好。 SpringMvc用什么对象从后台向前台传递数据的 答通过ModelMap对象,可以在这个对象里面用put方法,把对象加到里面,前台就可以通过el表达式拿到。 SpringMvc中有个类把视图和数据都合并的一起的,叫什么 答ModelAndView。 怎么样把ModelMap里面的数据放入Session里面 答可以在类上面加上SessionAttributes注解,里面包含的字符串就是要放入session里面的key。 当一个方法向AJAX返回特殊对象,譬如Object,List等,需要做什么处理 答要加上ResponseBody注解。 项目中如何用 Spring 和 Spring MVC 框架的 通过 web.xml 的配置、Controller、Service、Repository完成 http 请求到数据库的 crud 再到 view 层展示整个调用链。其中还要配置对象转 json 的 Converter、登录拦截器、文件上传大小限制、数据源及连接池相关等等… mybatis 支持自定义 SQL、存储过程以及高级映射免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJOPlain Old Java Objects普通老式 Java 对象为数据库中的记录 MyBatis是什么有什么作用 MyBatis前身是iBatis是一个支持普通SQL查询、存储过程以及高级映射的持久层框架它消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索并使用简单的XML或注解进行配置和原始映射用以将接口和Java的POJOPlain Old Java Object普通Java对象映射成数据库中的记录使得Java开发人员可以使用面向对象的编程思想来操作数据库。 MyBatis 框架也被称之为 ORMObject/Relational Mapping即对象关系映射框架。所谓的 ORM 就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术它通过描述Java对象与数据库表之间的映射关系自动将Java应用程序中的对象持久化到关系型数据库的表中。ORM框架的工作原理如下图所示。 从上图可以看出使用ORM框架后应用程序不再直接访问底层数据库而是以面向对象的方式来操作持久化对象Persisent ObjectPO而ORM框架则会通过映射关系将这些面向对象的操作转换成底层的SQL操作。 Mybaits 的优缺点 优点: 消除 JDBC 中的重复代码可以在 XML 或注解中直接编写 SQL 语句比较灵活方便对 SQL 的优化与调整SQL 写在 XML 中与代码解耦按照对应关系方便管理XML 中提供了动态 SQL 的标签方便根据条件拼接 SQL提供了 XML、注解与 Java 对象的映射机制与 Spring 集成比较方便 缺点: 字段较多、关联表多时编写 SQL 工作量较大SQL 语句依赖了数据库特性会导致程序的移植性较差切换数据库困难 #{} 和 ${} 的区别 都是用于传值 MyBatis 在处理 #{} 时会将 SQL 中的 #{} 替换为 ?预编译 SQL #是预编译占位符在sql语句中用代替可以防止sql注入 $是用于sql语句的拼接要判断参数类型不能防止sql注入 #{} 比 ${} 安全但还是提供了 ${} 这种动态替换参数的方式是因为有些复杂的 SQL 使用场景通过预编译的方式比较麻烦且在代码中完全可以做到控制非法参数有些参数可能是一些常量或字段值。 MyBatis 中实体类的属性名与表中的字段名不一致怎么处理 1、修改 SQL给查询字段重命名如 将 user_id 重命名为 userId 2、MyBatis 的 XML 映射文件中使用 标签定义数据库字段名与实体 bean 的属性字段名的映射关系 Mapper 接口如何与写 SQL 的 XML 文件进行绑定的 Mapper 接口与 XML 文件的绑定是通过 XML 里 mapper 标签的 namespace 值与 Mapper 接口的 包路径.接口名 进行绑定Mapper 接口的方法名与 XML 文件中的 sql、select、insert、update、delete 标签的 id 参数值进行绑定其中涉及到了 MappedStatement 的 id、SqlCommand 的 name 的值为 Mapper 接口的 包路径.接口名.方法名 MyBatis 如何批量插入 方式一、打开批量插入的 SqlSession SqlSession sqlSession sqlSessionFactory.openSession(ExecutorType.BATCH); UserMapper userMapper sqlSession.getMapper(UserMapper.class); for (int i 36; i 45; i) {userMapper.insertUser(new User(i, ConstXiong i)); } sqlSession.commit(); sqlSession.close();方式二、拼接批量插入的 insert SQL //Java 代码 ListUser userList new ArrayList(); for (int i 46; i 55; i) {userList.add(new User(i,ConstXiong i)); } userMapper.insertUserBatch(userList);!--Mapper xml 中配置-- insert idinsertUserBatch parameterTypejava.util.Listinsert into user valuesforeach collectionlist itemitem separator ,(#{item.id}, #{item.name})/foreach /insertMyBatis 是如何与 Spring 集成的 单纯使用 spring-context 和 spring-jdbc 集成 MyBatis配置步骤 加载 spring-context、spring-jdbc、MyBatis、MyBatis-Spring 的 jar 包spring 集成 MyBatis 的 xml 配置文件配置 dataSource、sqlSessionFactory、Mapper 接口包扫描路径Mapper 接口代理 bean 直接从 spring ioc 容器中获得使用即可 最核心的就是 spring 的配置文件如下 ?xml version1.0 encodingutf-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlns:contexthttp://www.springframework.org/schema/contextxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.3.xsdcontext:property-placeholder locationclasspath:db.properties ignore-unresolvabletrue /bean iddataSource classorg.apache.ibatis.datasource.pooled.PooledDataSource!-- 基本属性 url、user、password --property namedriver value${jdbc_driver} /property nameurl value${jdbc_url}/property nameusername value${jdbc_username}/property namepassword value${jdbc_password}//bean!-- spring 和 Mybatis整合 --bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBeanproperty namedataSource refdataSource/property namemapperLocations valueclasspath:constxiong/mapper/*.xml //bean!-- DAO接口所在包配置自动扫描 --bean classorg.mybatis.spring.mapper.MapperScannerConfigurerproperty namebasePackage valueconstxiong.mapper//bean/beans核心配置就是 dataSource、SqlSessionFactoryBean、MapperScannerConfigurer dataSource 是数据源 SqlSessionFactoryBean配置数据源、可以加载解析 MyBatis 的配置文件、可以设置 Mapper xml 的文件路径与解析、SqlSessionFactory 对象的创建等 buildSqlSessionFactory() 方法中利用 MyBatis 的核心类解析 MyBatis 的配置文件、Mapper xml 文件生成 Configuration 对象设置其中属性创建 SqlSessionFactory 对象 MapperScannerConfigurer设置 Mapper 接口的的包扫描路径加载所有的 Mapper 接口生成 BeanDefinition设置 BeanDefinition 的 beanClass 属性为 MapperFactoryBean设置 sqlSessionFactory 和 sqlSessionTemplate 属性 springboot SpringBoot是Spring推出用于解决传统框架配置文件冗余,装配组件繁杂的基于Maven的解决方案,旨在快速搭建单个微服务。 版本号2.1.6SpringBoot基于Spring4.0设计不仅继承了Spring框架原有的优秀特性而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突以及引用的不稳定性等问题得到了很好的解决。 [1] SpringBoot所具备的特征有 1可以创建独立的Spring应用程序并且基于其Maven或Gradle插件可以创建可执行的JARs和WARs 2内嵌Tomcat或Jetty等Servlet容器 3提供自动配置的“starter”项目对象模型POMS以简化Maven配置 4尽可能自动配置Spring容器 5提供准备好的特性如指标、健康检查和外部化配置 6绝对没有代码生成不需要XML配置。SpringBoot框架中还有两个非常重要的策略开箱即用和约定优于配置。开箱即用Outofbox是指在开发过程中通过在MAVEN项目的pom文件中添加相关依赖包然后使用对应注解来代替繁琐的XML配置文件以管理对象的生命周期。这个特点使得开发人员摆脱了复杂的配置工作以及依赖的管理工作更加专注于业务逻辑。约定优于配置Convention over configuration是一种由SpringBoot本身来配置目标结构由开发者在结构中添加信息的软件设计范式。这一特点虽降低了部分灵活性增加了BUG定位的复杂性但减少了开发人员需要做出决定的数量同时减少了大量的XML配置并且可以将代码编译、测试和打包等工作自动化。为什么要用 Spring Boot Spring Boot 优点非常多如 独立运行简化配置自动配置无代码生成和XML配置应用监控上手容易 Spring Boot 的核心配置文件有哪几个它们的区别是什么 SpringBoot的核心配置文件有application和bootstarp配置文件。 2.他们的区别是什么 application文件主要用于Springboot自动化配置文件。 bootstarp文件主要有以下几种用途 使用Spring Cloud Config注册中心时 需要在bootStarp配置文件中添加链接到配置中心的配置属性来加载外部配置中心的配置信息。 一些固定的不能被覆盖的属性 一些加密/解密的场景 都有什么格式 .properties 和 .yml .yml采取的是缩进的格式 不支持PeopertySource注解导入配置 **Spring Boot 的核心注解是哪个它主要由哪几个注解组成的**常用注解 启动类上面的注解是SpringBootApplication它也是 Spring Boot 的核心注解主要组合包含了以下 3 个注解 SpringBootConfiguration组合了 Configuration 注解实现配置文件的功能。 EnableAutoConfiguration打开自动配置的功能也可以关闭某个自动配置的选项如关闭数据源自动配置功能 SpringBootApplication(exclude { DataSourceAutoConfiguration.class })。 ComponentScanSpring组件扫描。 1、SpringBootApplication 这个注解是Spring Boot最核心的注解用在 Spring Boot的主类上 2、EnableAutoConfiguration 允许 Spring Boot 自动配置注解开启这个注解之后Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。 3、Configuration 用于定义配置类指出该类是 Bean 配置的信息源相当于传统的xml配置文件一般加在主类上。 4、ComponentScan 组件扫描。让spring Boot扫描到Configuration类并把它加入到程序上下文。 5、Repository 用于标注数据访问组件即DAO组件。 6、Service 一般用于修饰service层的组件 7、RestController 用于标注控制层组件(如struts中的action)表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器它是Controller和ResponseBody的合集。 8、ResponseBody 一般在异步获取数据时使用在使用RequestMapping后返回值通常解析为跳转路径加上responsebody后返回结果不会被解析为跳转路径而是直接写入HTTP response body中。比如异步获取json数据加上responsebody后会直接返回json数据。 9、Component 泛指组件当组件不好归类的时候我们可以使用这个注解进行标注。 10、Bean 相当于XML中的,放在方法的上面而不是类意思是产生一个bean,并交给spring管理。 11、AutoWired byType方式。把配置好的Bean拿来用完成属性、方法的组装它可以对类成员变量、方法及构造函数进行标注完成自动装配的工作。 12、Qualifier 当有多个同一类型的Bean时可以用Qualifier(“name”)来指定。与Autowired配合使用 13、Resource(name“name”,type“type”) 没有括号内内容的话默认byName。与Autowired干类似的事。 14、RequestMapping RequestMapping是一个用来处理请求地址映射的注解提供路由信息负责URL到Controller中的具体函数的映射可用于类或方法上。用于类上表示类中的所有响应请求的方法都是以该地址作为父路径。 15、RequestParam 用在方法的参数前面。 16、Profiles Spring Profiles提供了一种隔离应用程序配置的方式并让这些配置只能在特定的环境下生效。 17、PathVariable 路径变量。参数与大括号里的名字一样要相同。 开启 Spring Boot 特性有哪几种方式 1继承spring-boot-starter-parent项目 2导入spring-boot-dependencies项目依赖 运行 Spring Boot 有哪几种方式 1打包用命令或者放到容器中运行 2用 Maven/ Gradle 插件运行 3直接执行 main 方法运行 Spring Boot 自动配置原理是什么 注解 EnableAutoConfiguration, Configuration, ConditionalOnClass 就是自动配置的核心首先它得是一个配置文件其次根据类路径下是否有这个类去自动配置。 SpringBoot 有几种读取配置文件的方式 看配置文件 application.properties user.usernameCCCCXXX user.password123123123 user.age18 user.salary2000.00Value读取 PropertySource读取 PropertySource读取不支持yml文件配置* Environment读取 配置文件里面所有的配置都可以用Environment来获取 ConfigurationProperties读取 **这个注解就更屌了…**可以配合着别的注解一起使用 你如何理解 Spring Boot 配置加载顺序 在 Spring Boot 里面可以使用以下几种方式来加载配置。 1properties文件 2YAML文件 3系统环境变量 4命令行参数 Spring Boot 如何定义多套不同环境配置 提供多套配置文件如 applcation.propertiesapplication-dev.propertiesapplication-test.propertiesapplication-prod.propertiesSpring Boot 可以兼容老 Spring 项目吗如何做 可以兼容使用 ImportResource 注解导入老 Spring 项目配置文件。 springCloud微服务架构 什么是微服务架构 微服务架构就是将单体的应用程序分成多个应用程序这多个应用程序就成为微服务每个微服务运行在自己的进程中并使用轻量级的机制通信。这些服务围绕业务能力来划分并通过自动化部署机制来独立部署。这些服务可以使用不同的编程语言不同数据库以保证最低限度的集中式管理。 Spring Cloud 是什么 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等都可以用Spring Boot的开发风格做到一键启动和部署。 SpringCloud的优缺点 优点 1.耦合度比较低。不会影响其他模块的开发。 2.减轻团队的成本可以并行开发不用关注其他人怎么开发先关注自己的开发。 3.配置比较简单基本用注解就能实现不用使用过多的配置文件。 4.微服务跨平台的可以用任何一种语言开发。 5.每个微服务可以有自己的独立的数据库也有用公共的数据库。 6.直接写后端的代码不用关注前端怎么开发直接写自己的后端代码即可然后暴露接口通过组件进行服务通信。 缺点 1.部署比较麻烦给运维工程师带来一定的麻烦。 2.针对数据的管理比麻烦因为微服务可以每个微服务使用一个数据库。 3.系统集成测试比较麻烦 4.性能的监控比较麻烦。【最好开发一个大屏监控系统】 总的来说优点大过于缺点目前看来Spring Cloud是一套非常完善的分布式框架目前很多企业开始用微服务、Spring Cloud的优势是显而易见的。因此对于想研究微服务架构的同学来说学习Spring Cloud是一个不错的选择。 SpringBoot和SpringCloud的区别 SpringBoot专注于快速方便的开发单个个体微服务。 SpringCloud是关注全局的微服务协调整理治理框架它将SpringBoot开发的一个个单体微服务整合并管理起来 为各个微服务之间提供配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务 SpringBoot可以离开SpringCloud独立使用开发项目 但是SpringCloud离不开SpringBoot 属于依赖的关系 SpringBoot专注于快速、方便的开发单个微服务个体SpringCloud关注全局的服务治理框架。 pringCloud由什么组成 这就有很多了我讲几个开发中最重要的 Spring Cloud Eureka服务注册与发现 Spring Cloud Zuul服务网关 Spring Cloud Ribbon客户端负载均衡 Spring Cloud Feign声明性的Web服务客户端 Spring Cloud Hystrix断路器 Spring Cloud Confifig分布式统一配置管理 Spring Cloud 和dubbo区别? 1服务调用方式dubbo是RPC springcloud Rest Api 2注册中心dubbo 是zookeeper springcloud是eureka也可以是zookeeper 3服务网关dubbo本身没有实现只能通过其他第三方技术整合springcloud有Zuul路由网关作为路由服务器进行消费者的请求分发,springcloud支持断路器与git完美集成配置文件支持版本控制事物总线实现配置文件的更新与服务自动装配等等一系列的微服务架构要素。 Eureka 服务注册和发现是什么意思Spring Cloud 如何实现 什么是Eureka Eureka作为SpringCloud的服务注册功能服务器他是服务注册中心系统中的其他服务使用Eureka的客户端将其连接到Eureka Service中并且保持心跳这样工作人员可以通过EurekaService来监控各个微服务是否运行正常。 Eureka怎么实现高可用 集群吧注册多台 Eureka 然后把 SpringCloud 服务互相注册客户端从 Eureka 获取信息时按照Eureka 的顺序来访问。 什么是Eureka的自我保护模式 默认情况下如果 Eureka Service 在一定时间内没有接收到某个微服务的心跳 Eureka Service 会进入自我保护模式在该模式下Eureka Service 会保护服务注册表中的信息不在删除注册表中的数据当网络故障恢复后Eureka Servic 节点会自动退出自我保护模式 DiscoveryClient的作用 可以从注册中心中根据服务别名获取注册的服务器信息。 Eureka和ZooKeeper都可以提供服务注册与发现的功能,请说说两个的区别 ZooKeeper中的节点服务挂了就要选举 在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的 选举就是改微服务做了集群必须有一台主其他的都是从 Eureka各个节点是平等关系,服务器挂了没关系只要有一台Eureka就可以保证服务可用数据都是最新的。 如果查询到的数据并不是最新的就是因为Eureka的自我保护模式导致的 Eureka本质上是一个工程,而ZooKeeper只是一个进程 Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper 一样使得整个注册系统瘫痪 ZooKeeper保证的是CPEureka保证的是AP CAP C一致性Consistency; 取舍(强一致性、单调一致性、会话一致性、最终一致性、弱一致性) A可用性Availability; P分区容错性Partition tolerance; Zuul 什么是网关? 网关相当于一个网络服务架构的入口所有网络请求必须通过网关转发到具体的服务。 网关的作用是什么 统一管理微服务请求权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等 什么是Spring Cloud Zuul服务网关 网关与过滤器有什么区别 网关是对所有服务的请求进行分析过滤过滤器是对单个服务而言。 常用网关框架有那些 Nginx 、 Zuul 、 Gateway Zuul与Nginx有什么区别 Zuul 是 java 语言实现的主要为 java 服务提供网关服务尤其在微服务架构中可以更加灵活的对网关进行操作。Nginx 是使用 C 语言实现性能高于 Zuul 但是实现自定义操作需要熟悉 lua 语言对程序员要求较高可以使用Nginx 做 Zuul 集群。 既然Nginx可以实现网关为什么还需要使用Zuul框架 Zuul 是 SpringCloud 集成的网关使用 Java 语言编写可以对 SpringCloud 架构提供更灵活的服务。 Zuul网关如何搭建集群 使用 Nginx 的 upstream 设置 Zuul 服务集群通过 location 拦截请求并转发到 upstream 默认使用轮询机制对Zuul 集群发送请求。 Ribbon 负载平衡的意义什么 Ribbon是什么 Nginx与Ribbon的区别 Ribbon底层实现原理 Ribbon 使用 discoveryClient 从注册中心读取目标服务信息对同一接口请求进行计数使用 % 取余算法获取目标服务集群索引返回获取到的目标服务信息。 LoadBalanced注解的作用 开启客户端负载均衡。 Hystrix 什么是断路器 什么是 Hystrix 谈谈服务雪崩效应 在微服务中如何保护服务? 服务雪崩效应产生的原因 因为 Tomcat 默认情况下只有一个线程池来维护客户端发送的所有的请求这时候某一接口在某一时刻被大量访问就会占据tomcat 线程池中的所有线程其他请求处于等待状态无法连接到服务接口。 谈谈服务降级、熔断、服务隔离 整体资源快不够了忍痛将某些服务先关掉待渡过难关再开启回来。 1、服务降级的特征 原因整体负荷超出整体负载承受能力。 目的保证重要或基本服务正常运行非重要服务延迟使用或暂停使用 大小降低服务粒度要考虑整体模块粒度的大小将粒度控制在合适的范围内 可控性在服务粒度大小的基础上增加服务的可控性后台服务开关的功能是一项必要配置单机可配置文件其他可领用数据库和缓存可分为手动控制和自动控制。 次序一般从外围延伸服务开始降级需要有一定的配置项重要性低的优先降级比如可以分组设置等级1-10当服务需要降级到某一个级别时进行相关配置 2、降级的方式 1、延迟服务比如发表了评论重要服务比如在文章中显示正常但是延迟给用户增加积分只是放到一个缓存中等服务平稳之后再执行。2、在粒度范围内关闭服务片段降级或服务功能降级比如关闭相关文章的推荐直接关闭推荐区3、页面异步请求降级比如商品详情页上有推荐信息/配送至等异步加载的请求如果这些信息响应慢或者后端服务有问题可以进行降级3、页面跳转页面降级比如可以有相关文章推荐但是更多的页面则直接跳转到某一个地址4写降级比如秒杀抢购我们可以只进行Cache的更新然后异步同步扣减库存到DB保证最终一致性即可此时可以将DB降级为Cache。5读降级比如多级缓存模式如果后端服务有问题可以降级为只读缓存这种方式适用于对读一致性要求不高的场景服务降级底层是如何实现的 Hystrix实现服务降级的功能是通过重写HystrixCommand中的getFallback()方法当Hystrix的run方法或construct执行发生错误时转而执行getFallback()方法。 Feign 什么是Feign Feign 是一个声明web服务客户端这使得编写web服务客户端更容易 他将我们需要调用的服务方法定义成抽象方法保存在本地就可以了不需要自己构建Http请求了直接调用接口就行了不过要注意调用方法要和本地抽象方法的签名完全一致。 SpringCloud有几种调用接口方式 Feign RestTemplate Ribbon和Feign调用服务的区别 Dubbo 介绍一下Dubbo Dubbo 是一个分布式、高性能、透明化的 RPC 服务框架提供服务自动注册、自动发现等高效服务治理方案 可以和 Spring 框架无缝集成 Dubbo有哪些核心组件 Provider服务的提供方Consumer调用远程服务的服务消费方Registry服务注册和发现的注册中心Monitor统计服务调用次数和调用时间的监控中心Container服务运行容器 Dubbo框架分了哪些层 Dubbo 框架设计一共划分了 10 层 服务接口层(Service)该层是与实际业务逻辑相关的根据服务提供方和服务消费方的业务设计对应的接口和实现配置层(Config)对外配置接口以 ServiceConfig 和 ReferenceConfig 为中心服务代理层(Proxy)服务接口透明代理生成服务的客户端 Stub 和服务器端 Skeleton服务注册层(Registry)封装服务地址的注册与发现以服务 URL 为中心集群层(Cluster)封装多个提供者的路由及负载均衡并桥接注册中心以 Invoker 为中心监控层(Monitor)RPC 调用次数和调用时间监控远程调用层(Protocol)封将 RPC 调用以 Invocation 和 Result 为中心扩展接口为 Protocol、Invoker、Exporter信息交换层(Exchange)封装请求响应模式同步转异步以 Request 和 Response 为中心网络传输层(Transport)抽象 mina 和 netty 为统一接口以 Message 为中心数据序列化层(Serialize)序列化的一些工具 Dubbo支持哪些序列化方式? Hessian 序列化是修改过的 hessian lite默认启用json 序列化使用 FastJson 库java 序列化JDK 提供的序列化性能不理想dubbo 序列化未成熟的高效 java 序列化实现不建议在生产环境使用 Dubbo的主要作用 透明化的远程方法调用像调用本地方法一样调用远程方法负载均衡及容错机制负载分发请求到不同的服务提供者解决单点故障服务自动注册与发现动态服务注册与请求分发能够平滑添加或删除服务提供者 Dubbo有哪些负载均衡策略 Dubbo 实现了常见的集群策略并提供扩展点予以自行实现。 Random LoadBalance随机选取提供者策略随机转发请求可以加权RoundRobin LoadBalance轮循选取提供者策略请求平均分布LeastActive LoadBalance最少活跃调用策略可以让慢提供者接收更少的请求ConstantHash LoadBalance一致性 Hash 策略相同参数请求总是发到同一提供者一台机器宕机可以基于虚拟节点分摊至其他提供者 缺省时为 Random LoadBalance 你觉得用 Dubbo 好还是 Spring Cloud 好 扩展性的问题没有好坏只有适合不适合不过我好像更倾向于使用 Dubbo, Spring Cloud 版本升级太快组件更新替换太频繁配置太繁琐还有很多我觉得是没有 Dubbo 顺手的地方…… 数据库 mysql 事务的四大特性 原子性Atomicity 事务最基本的操作单元要么全部成功要么全部失败不会结束在中间某个环节。事务在执行过程中发生错误会被回滚到事务开始前的状态就像这个事务从来没有执行过一样。 一致性Consistency 事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。如果事务成功地完成那么系统中所有变化将正确地应用系统处于有效状态。如果在事务中出现错误那么系统中的所有变化将自动地回滚系统返回到原始状态。 隔离性Isolation 指的是在并发环境中当不同的事务同时操纵相同的数据时每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时数据所处的状态要么是另一事务修改它之前的状态要么是另一事务修改它之后的状态事务不会查看到中间状态的数据。 持久性Durability 指的是只要事务成功结束它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃重新启动数据库系统后数据库还能恢复到事务成功结束时的状态。 事务有哪些隔离级别 读未提交Read Uncommitted是最低的事务隔离级别它允许另外一个事务可以看到这个事务未提交的数据。会出现脏读幻读不可重复读所有并发问题都可能遇到。读已提交Read Committed保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。不会出现脏读现象但是会出现幻读不可重复读。可重复读Repeatable Read这种事务隔离级别可以防止脏读不可重复读但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了不可重复读。串行化Serializable这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。防止脏读、不可重复读、幻象读。 数据库如何优化 1优化sql语句 原则: 1.尽量根据主键查询 2.尽量使用单表查询/不要关联查询3.查询时可以使用in但是绝对不要使用not in2.创建索引 为搜索字段建索引create index 索引名称 on 表名称(列名称)为什么使用数据索引能提高效率数据索引的存储是 有序的在有序的情况下, 通过索引查询一个数据是无需遍历索引记录的极端情况下数据索引的查询效率为二分法查询效率,趋近于log2(N)3.添加缓存例如:mybatis 一/二级缓存 该操作效率低主要:redis/memercache作用:可以有效的缓解数据库压力。4.使用数据库的读写分离5.定期将历史数据进行转储当前表/查询历史表 6.进行分库分表(最后策略最有效的策略)数据库服务器数量和运维都要花费很多的时间和精力什么是表分区?表分区是指根据一定规则将数据库中的一张表分解成多个更小的容易管理的部分。从逻辑上看只有一张表但是底层却是由多个物理分区组成表分区与分表的区别?分表指的是通过一定规则 将一张表分解成多 张不同的表。比如将用户订单记录根据时间成多个表。分表与分区的区别在于:分区从逻辑上来讲只有一张表 ,而分表则是将一张表分解成多张表。表分区有什么好处?存储更多数据。分区表的数据可以分布在不同的物理设备上从而高效地利用多个硬件设备。和单个磁盘或者文件系统相比可以存储更多数据优化E询。在where语句中包含分区条件时可以只扫描一个或多 个分区表来提高查询效率;涉及sum和count语句时也可以在多个分区上并行处理最后汇总结果。分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。避免某些特殊的瓶颈例如InnoDB的单个索引的互斥访问 ext3问价你系统的inode锁竞争等。 7.选择正确的存储引擎MySql集群主从复制主从同步 原理 主(master) 从(slave) master将数据改变记录到二进制日志binary log中即配置文件log-bin指定的文件这些记录叫做二进制日志事件binary log events slave 将 master 的 binary log events 拷贝到它的中继日志relay log slave重做中继日志中的事件将改变反映它自己的数据数据重演 \1. 主库和从库的版本要一致 \2. 主库和从库的数据一致 \3. 主库开启二进制日志主库和从库的server_id都必须唯一 在项目中使用读写分离本质上就是增加数据库服务器资源 网络带宽来分摊对数据库的读写请求从而提高了性能和可用性。主从复制实现读写分离最大的缺点就是从库同步到主库的数据存在延迟网络不好的时候延迟比较严重。 mysql默认的存储引擎是什么 Mysql在V5.1之前默认存储引擎是MyISAM在此之后默认存储引擎是InnoDB。 MyISAM不支持事务InnoDB支持事务。 MySIAM不支持外键InnoDB支持外键 MySIAM支持全文索引InnoDB不支持全文索引。MyISAM与InnoDB的区别 InnoDB 支持事务MyISAM 不支持事务 InnoDB 支持行级锁MyISAM 支持表级锁 InnoDB 支持 MVCC(多版本并发控制)MyISAM 不支持 InnoDB 支持外键MyISAM 不支持 MySQL 5.6 以前的版本InnoDB 不支持全文索引MyISAM 支持MySQL 5.6 及以后的版本MyISAM 和 InnoDB 存储引擎均支持全文索引 InnoDB 不保存表的总行数执行 select count(*) from table 时 需要全表扫描MyISAM 用一个变量保存表的总行数查总行数速度很快 InnoDB 是聚集索引数据文件是和索引绑在一起的必须要有主键 通过主键索引效率很高。辅助索引需要两次查询先查询到主键再通过主键查询到数据。主键太大其他索引也会很大MyISAM 是非聚集索引数据文件是分离的索引保存的是数据文件的指针主键索引和辅助索引是独立的 总结 InnoDB 存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全与 MyISAM 比 InnoDB 写的效率差一些并且会占用更多的磁盘空间以保留数据和索引 MyISAM 不支持事务、也不支持外键优势是访问的速度快。对事务的完整性没有要求、以 SELECT 和 INSERT 为主的应用可以使用这个存储引擎 Innodb引擎有什么特性 插入缓冲(insert buffer)二次写(double write)自适应哈希索引(ahi)预读(read ahead) 数据库的三范式是什么有什么作用 列不可分确保表的每一列都是不可分割的原子数据项。作用方便字段的维护、查询效率高、易于统计。属性字段完全依赖完全依赖指不能存在仅依赖主键的部分属性于主键。作用保证每行数据都是按主键划分的独立数据。任何非主属性字段不依赖于其它非主属性字段。作用减少表字段与数据存储让相互依赖的非主键字段单独成为一张关系表记录被依赖字段即可。 Mysql驱动程序是什么 Mysql 提供给 Java 编程语言的驱动程序就是这样 mysql-connector-java-5.1.18.jar 包针对不同的数据库版本驱动程序包版本也不同不同的编程语言驱动程序的包形式也是不一样的驱动程序主要帮助编程语言与 MySQL 服务端进行通信如果连接、关闭、传输指令与数据等 如何连接MySQL服务端、关闭连接 连接使用指令 mysql -u -p -h -P (-u:指定用户名 -p:指定密码 -h:主机 -P:端口) 连接 MySQL 服务端关闭使用指令 exit 或 quit 左连接、右连接、内连接和全外连接的区别 左连接(left join)返回包括左表中的所有记录和右表中连接字段相等的记录。右连接(right join)返回包括右表中的所有记录和左表中连接字段相等的记录。内连接(inner join)只返回两个表中连接字段相等的记录。全外连接(full join)返回左右表中连接字段相等的记录和剩余所有记录。 什么是表分区 表分区是指根据一定规则将数据库中的一张表分解成多个更小的容易管理的部分。从逻辑上看只有一张表但是底层却是由多个物理分区组成。 表分区与分表的区别 分表指的是通过一定规则将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。 分表与分区的区别在于分区从逻辑上来讲只有一张表而分表则是将一张表分解成多张表。 表分区有什么好处 1、存储更多数据。分区表的数据可以分布在不同的物理设备上从而高效地利用多个硬件设备。和单个磁盘或者文件系统相比可以存储更多数据 2、优化查询。在where语句中包含分区条件时可以只扫描一个或多个分区表来提高查询效率涉及sum和count语句时也可以在多个分区上并行处理最后汇总结果。 3、分区表更容易维护。例如想批量删除大量数据可以清除整个分区。 4、避免某些特殊的瓶颈例如InnoDB的单个索引的互斥访问ext3问价你系统的inode锁竞争等。 分区表的限制因素 一个表最多只能有1024个分区MySQL5.1中分区表达式必须是整数或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。如果分区字段中有主键或者唯一索引的列那么多有主键列和唯一索引列都必须包含进来。即分区字段要么不包含主键或者索引列要么包含全部主键和索引列。分区表中无法使用外键约束MySQL的分区适用于一个表的所有数据和索引不能只对表数据分区而不对索引分区也不能只对索引分区而不对表分区也不能只对表的一部分数据分区。 如何判断当前MySQL是否支持分区 命令show variables like ‘%partition%’ 运行结果: have_partintioning 的值为YES表示支持分区。 MySQL支持的分区类型有哪些 RANGE分区 这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区LIST分区 这种模式允许系统通过预定义的列表的值来对数据进行分割。按照List中的值分区与RANGE的区别是range分区的区间范围值是连续的。HASH分区 这中模式允许通过对表的一个或多个列的Hash Key进行计算最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。KEY分区 上面Hash模式的一种延伸这里的Hash Key是MySQL系统产生的。 如何实现分库分表怎么配置 分库分表的实现方案一般分为两种 1、增加一个中间层中间层实现 MySQL 客户端协议可以做到应用程序无感知地与中间层交互。由于是基于协议层的代理可以做到支持多语言但需要多启动一个进程、SQL 的解析也耗费大量性能、由于协议绑定仅支持单个种类的数据库库。 2、在代码层面增加一个路由程序控制对数据库与表的读写。路由程序写在项目里与编程语言绑定、连接数高、但相对轻量比如 Java 仅需要引入 SharingShpere 组件中 Sharding-JDBC 的 jar 即可、支持任意数据库。 索引 Mysql索引使用的数据结构主要有BTree索引 和 哈希索引 。对于哈希索引来说底层的数据结构就是哈希表因此在绝大多数需求为单条记录查询的时候可以选择哈希索引查询性能最快其余大部分场景建议选择BTree索引。 Mysql的BTree索引使用的是B数中的BTree但对于主要的两种存储引擎的实现方式是不同的。 MyISAM: BTree叶节点的data域存放的是数据记录的地址。在索引检索的时候首先按照BTree搜索算法搜索索引如果指定的Key存在则取出其data域的值然后以data域的值为地址读取相应的数据记录。这被称为“非聚簇索引”。 InnoDB: 其数据文件本身就是索引文件。相比MyISAM索引文件和数据文件是分离的其表数据文件本身就是按BTree组织的一个索引结构树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键因此InnoDB表数据文件本身就是主索引。这被称为“聚簇索引或聚集索引”。而其余的索引都作为辅助索引辅助索引的data域存储相应记录主键的值而不是地址这也是和MyISAM不同的地方。在根据主索引搜索时直接找到key所在的节点即可取出数据在根据辅助索引查找时则需要先取出主键的值在走一遍主索引。 因此在设计表的时候不建议使用过长的字段作为主键也不建议使用非单调的字段作为主键这样会造成主索引频繁分裂。 什么是索引什么场景使用 索引是对数据库表中一列或多列的值进行排序的一种结构使用索引可快速访问数据库表中的特定信息 使用索引目的是加快检索表中数据 使用场景 中到大数据量表适合使用索引小数据量表大部分情况全表扫描效率更高特大数据量表建立和使用索引的代价会随之增大适合使用分区或分库 索引如何创建与删除 创建单个字段索引的语法CREATE INDEX 索引名 on 表名(字段名)创建联合索引的语法CREATE INDEX 索引名 on 表名(字段名1字段名2)索引命名格式一般可以这样idx_表名_字段名。注意有长度限制删除索引DROP INDEX 索引名 ON 表名 索引的种类有哪些 普通索引最基本的索引没有任何约束限制。列值可以取空值或重复值。创建使用关键字INDEX或KEY唯一索引和普通索引类似但是具有唯一性约束可以有 null创建使用关键字UNIQUE主键索引特殊的唯一索引主键索引是系统自动创建的主键索引并且是唯一的。与唯一索引区别是列值不能为空组合索引多列值组成一个索引用于组合搜索效率大于索引合并聚簇索引就是数据存储的物理存储顺序非聚簇索引就是索引顺序与数据的物理顺序无关。一个表只能有一个聚簇索引。目前只有InoDB和solidDB支持。全文索引对文本的内容进行分词、搜索覆盖索引查询列要被所建的索引覆盖不必读取数据行 MySQL创建和使用索引的注意事项 适合创建索引的列是出现在 WHERE 或 ON 子句中的列而不是出现在 SELECT 关键字后的列索引列的基数越大数据区分度越高索引的效果越好对字符串列进行索引可制定一个前缀长度节省索引空间避免创建过多的索引索引会额外占用磁盘空间降低写操作效率主键尽可能选择较短的数据类型可减少索引的磁盘占用提高查询效率联合索引遵循前缀原则LIKE 查询%在前不到索引可考虑使用 ElasticSearch、Lucene 等搜索引擎MySQL 在数据量较小的情况可能会不使用索引因为全表扫描比使用索引速度更快关键词 or 前面的条件中的列有索引后面的没有所有列的索引都不会被用到列类型是字符串查询时一定要给值加引号否则索引失效联合索引要遵从最左前缀原则否则不会用到索引 说一些索引失效的情况 如果条件中有 or即使其中有部分条件是索引字段也不会使用索引复合索引查询条件不使用索引前面的字段后续字段也将无法使用索引以 % 开头的 like 查询索引列的数据类型存在隐形转换where 子句里对索引列有数学运算where 子句里对索引列使用函数MySQL 引擎估算使用全表扫描要比使用索引快则不使用索引 索引对性能有哪些影响 优点 减少数据库服务器需要扫描的数据量帮助数据库服务器避免排序和临时表将随机 I/O 变顺序I/O提高查询速度唯一索引能保证数据的唯一性 缺点 索引的创建和维护耗时随着数据量的增加而增加对表中数据进行增删改时索引也要动态维护降低了数据的维护速度增大磁盘占用 列值为NULL时查询是否会用到索引 MySQL 中存在 NULL 值的列也是走索引的 计划对列进行索引应尽量避免把它设置为可空因为这会让 MySQL 难以优化引用了可空列的查询同时增加了引擎的复杂度 缓存 my.cnf加入以下配置重启Mysql开启查询缓存 query_cache_type1query_cache_size600000Mysql执行以下命令也可以开启查询缓存 set global query_cache_type1;set global query_cache_size600000;如上开启查询缓存后在同样的查询条件以及数据情况下会直接在缓存中返回结果。这里的查询条件包括查询本身、当前要查询的数据库、客户端协议版本号等一些可能影响结果的信息。因此任何两个查询在任何字符上的不同都会导致缓存不命中。此外如果查询中包含任何用户自定义函数、存储函数、用户变量、临时表、Mysql库中的系统表其查询结果也不会被缓存。 缓存建立之后Mysql的查询缓存系统会跟踪查询中涉及的每张表如果这些表数据或结构发生变化那么和这张表相关的所有缓存数据都将失效。 缓存虽然能够提升数据库的查询性能但是缓存同时也带来了额外的开销每次查询后都要做一次缓存操作失效后还要销毁。 因此开启缓存查询要谨慎尤其对于写密集的应用来说更是如此。如果开启要注意合理控制缓存空间大小一般来说其大小设置为几十MB比较合适。此外还可以通过sql_cache和sql_no_cache来控制某个查询语句是否需要缓存 select sql_no_cache count(*) from usr;为什么使用数据索引能提高效率 数据索引的存储是有序的在有序的情况下通过索引查询一个数据是无需遍历索引记录的极端情况下数据索引的查询效率为二分法查询效率趋近于 log2(N) 锁 MyISAM和InnoDB存储引擎使用的锁 MyISAM采用表级锁(table-level locking)。 InnoDB支持行级锁(row-level locking)和表级锁,默认为行级锁 表级锁和行级锁对比 表级锁 Mysql中锁定 粒度最大 的一种锁对当前操作的整张表加锁实现简单资源消耗也比较少加锁快不会出现死锁。其锁定粒度最大触发锁冲突的概率最高并发度最低MyISAM和 InnoDB引擎都支持表级锁。 行级锁 Mysql中锁定 粒度最小 的一种锁只针对当前操作的行进行加锁。 行级锁能大大减少数据库操作的冲突。其加锁粒度最小并发度高但加锁的开销也最大加锁慢会出现死锁。 InnoDB存储引擎的锁的算法有三种 Record lock单个行记录上的锁 Gap lock间隙锁锁定一个范围不包括记录本身 Next-key lockrecordgap 锁定一个范围包含记录本身 行级锁定的优点 1、当在许多线程中访问不同的行时只存在少量锁定冲突。 2、回滚时只有少量的更改 3、可以长时间锁定单一的行。 行级锁定的缺点 比页级或表级锁定占用更多的内存。当在表的大部分中使用时比页级或表级锁定速度慢因为你必须获取更多的锁。如果你在大部分数据上经常进行GROUP BY操作或者必须经常扫描整个表比其它锁定明显慢很多。用高级别锁定通过支持不同的类型锁定你也可以很容易地调节应用程序因为其锁成本小于行级锁定。 MySQL的乐观锁和悲观锁 乐观锁每次去获取数据的时候都认为别人不会修改不会上锁但是在提交修改的时候会判断一下在此期间别人有没有修改这个数据。 悲观锁每次去获取数据的时候都认为别人会修改每次都会上锁阻止其他线程获取数据直到这个锁释放。 MySQL 的乐观锁需要自己实现。一般在表里面添加一个 version 字段每次修改成功值加 1每次其他字段值的时候先对比一下自己拥有的 version 和数据库现在的 version 是否一致如果不一致就可以返回失败也可以进行重试。 MySQL 的悲观锁以 Innodb 存储引擎为例将 MySQL 设置为非 autoCommit 模式 begin; select * from table where id 1 for update; insert ... update ... commit;当上面语句未 commitid 1 的数据是被锁定的即其他事务中的查到这条语句会被阻塞直到事务提交。 数据的锁定还涉及到索引的不同可能是行锁、表锁的问题。 MySQL中如何避免死锁 尽量以相同的顺序来访问索引记录和表业务上能够接受幻读和不可重复读考虑降低锁的级别到 Read committed降低死锁发生的概率添加合理的索引走索引避免为每一行加锁降低死锁的概率在事务中一次锁定所需要的所有资源如 MyISAM 引擎的表锁避免大事务尽量将大事务拆成多个小事务来处理尽量避免同时并发对同一表进行读写操作特别是执行加锁且操作数据量较大的语句设置锁等待超时参数 MySQL 单表上亿怎么优化分页查询 1、表容量的问题 首先MySQL 不管怎么优化也是很难支持单表一亿数据量带查询条件的分页查询需要提前考虑分表分库。单表设计以 200-500 万为宜优化的好单表数据到一两千万性能也还行。出现那么单表那么大的数据量已经是设计问题了。 2、总页数的问题 页面不需要显示总页数仅显示附近的页码这样可以避免单表总行数的查询。 需要显示总页数这种情况就比较难处理一些。首先 MySQL 的 MyISAM 引擎把一个表的总行数记录在磁盘中查询 count(*) 可以直接返回InnoDB 引擎是一行行读出来累加计数大数据量时性能堪忧大几秒甚至几十秒都有可能我相信你一定遇到过。所以 MyISAM 的总行数查询速度是比 InnoDB 快的但这个快也仅限于不带 where 条件的。MyISAM 还有一个硬伤不支持事务。 3、具体的 SQL 优化 新增表记录业务表的总数也是无法彻底解决带查询条件的总行数查询慢的问题。这里只能借助具体的 SQL 优化。 不带条件 自增 id 字段连续 这种理想情况就不讨论了通过 pageNo 和 pageSize 算出 id 的起始与结束值 where id ? and id ? where id between where id ? limit 10就可以直接搞定了。 带查询条件 主键 id 不连续 这种就是我们最需要解决的情况。使用 limit 分页有个查询耗时与起始记录的位置成正比的问题所以不能直接使用。 可以这样根据主键进行关联查询 select * from table t1 join (select id from table where condition limit 10) t2 on t1.id t2.id order by t1.id asc其中 condition 是包含索引的查询条件使用 id 字段进行具体信息的关联回查。当然查询条件 condition 中索引是否生效对性能影响也很大。 索引没有生效的一些情况 组合索引的「最左前缀」原则or 的使用可能导致索引未生效可使用 union all 替代like 查询以 % 开头对 null 值判断使用 ! 或 操作符索引列上使用计算、函数 4、其他解法 继续优化数据库配置提升数据库服务器硬件性能引入大数据组件引入大型商业数据库或者非关系型数据库解决大表问题 MySQL有哪些常用函数 数值型函数 ABS计算绝对值 SQRT计算二次方根 MOD计算余数 CEIL、CEILING返回不小于参数的最小整数即向上取整 FLOOR向下取整返回值转化为一个 BIGINT RAND生成一个 0~1 之间的随机数 ROUND四舍五入SIGN返回参数的符号POW、POWER参数次方的值 字符串函数 LENGTH返回字符串的字节长度CONCAT合并字符串返回结果为连接参数产生的字符串参数可以使一个或多个INSERT替换字符串LOWER将字符串中的字母转换为小写UPPER将字符串中的字母转换为大写LEFT从左侧字截取符串返回字符串左边的若干个字符RIGHT从右侧字截取符串返回字符串右边的若干个字符TRIM删除字符串左右两侧的空格REPLACE字符串替换返回替换后的新字符串SUBSTRING截取字符串返回从指定位置开始的指定长度的字符换REVERSE字符串反转返回与原始字符串顺序相反的字符串 聚合函数 MAX查询指定列的最大值MIN查询指定列的最小值COUNT统计查询结果的行数SUM求和返回指定列的总和AVG求平均值返回指定列数据的平均值 流程控制函数 IF判断是否为 trueIFNULL判断是否为空CASE分支判断 与Oracle相比Mysql有什么优势 Mysql 是开源软件、无需付费操作简单、部署方便用户可以根据应用的需求去定制数据库Mysql 的引擎是插件式 MySQL如何进行慢SQL优化 思路 通过慢查询日志去寻找哪些 SQL 执行效率低使用 explain 获取低效率 SQL 的执行计划结合 SQL 与执行计划进行分析与优化 引起 SQL 查询很慢的原因与解决办法 1、没有索引。解决办法 根据 where 和 order by 使用比较频繁的字段创建索引提高查询效率索引不宜过多单表最好不要超过 6 个。索引过多会导致占用存储空间变大insert、update 变慢删除未使用的索引 2、索引未生效。解决办法 避免在 where 子句中对字段进行 null 值判断创建表默认值是 NULL。尽量使用 NOT NULL或使用特殊值如 0、-1避免在 where 子句中使用 ! 或 操作符 MySQL 只有对以下操作符才使用索引、、、、、BETWEEN、IN、非 % 开头的 LIKE避免在 where 子句中使用 or 来连接条件可以使用 UNION 进行连接能用 union all 就不用 unionunion 过滤重复数据要耗费更多的 CPU 资源避免部分 like 查询如 ‘%ConstXiong%’避免在索引列上使用计算、函数in 和 not in 慎用能用 between 不要用 inselect 子句中避免使用 * 3、单表数据量太大。解决办法 分页查询(在索引上完成排序分页操作、借助主键进行关联)单表数据过大进行分库分表考虑使用非关系型数据库提高查询效率全文索引场景较多考虑使用 ElasticSearch、solr 提升性能的一些技巧 尽量使用数字型字段只需要一行数据时使用 limit 1索引尽量选择较小的列不需要的数据在 GROUP BY 之前过滤掉大部分时候 exists、not exists 比 in、not in 效率除了子查询是小表的情况使用 in 效率比 exists 高不确定长度的字符串字段使用 varchar/nvarchar如使用 char/nchar 定长存储会带来空间浪费不要使用 select *去除不需要的字段查询避免一次性查询过大的数据量使用表别名减少多表关联解析时间多表 join 最好不超过 5 个视图嵌套最好不超过 2 个or 条件查询可以拆分成 UNION 多个查询count(1) 比 count(*) 有效判断是否存在数据使用 exists 而非 countcount 用来获取数据行数 如何避免sql注入 严格限制 Web 应用的数据库的操作权限给连接数据库的用户提供满足需要的最低权限最大限度的减少注入攻击对数据库的危害校验参数的数据格式是否合法可以使用正则或特殊字符的判断对进入数据库的特殊字符进行转义处理或编码转换预编译 SQLJava 中使用 PreparedStatement参数化查询方式避免 SQL 拼接发布前利用工具进行 SQL 注入检测报错信息不要包含 SQL 信息输出到 Web 页面 什么是XSS攻击如何避免 XSS 攻击即跨站脚本攻击Cross Site Scripting它是 web 程序中常见的漏洞。 web 页面中可由用户输入的地方如果对输入的数据转义、过滤处理后台输出页面的时候也需要对输出内容进行转义、过滤处理因为攻击者可能通过其他方式把恶意脚本写入数据库前端对 html 标签属性、css 属性赋值的地方进行校验 什么是CSRF攻击如何避免 CSRFCross Site Request Forgery跨站点请求伪造。 CSRF 攻击者在用户已经登录目标网站之后诱使用户访问一个攻击页面利用目标网站对用户的信任以用户身份在攻击页面对目标网站发起伪造用户操作的请求达到攻击目的。 避免方法 CSRF 漏洞进行检测的工具如 CSRFTester、CSRF Request Builder…验证 HTTP Referer 字段添加并验证 token添加自定义 http 请求头敏感操作添加验证码使用 post 请求 Oracle Oracle中字符串链接符是什么 Oracle中使用 || 这个符号连接字符串 如 ‘Const’ || ‘Xiong’ Oracle中有哪几种文件 数据文件一般后缀为.dbf或者.ora日志文件(后缀名.log)控制文件后缀名为.ctl* Oracle优化 个人理解数据库性能最关键的因素在于IO因为操作内存是快速的但是读写磁盘是速度很慢的优化数据库最关键的问题在于减少磁盘的IO就个人理解应该分为物理的和逻辑的优化 物理的是指oracle产品本身的一些优化逻辑优化是指应用程序级别的优化 物理优化的一些原则 1). Oracle的运行环境网络硬件等 2). 使用合适的优化器 3). 合理配置oracle实例参数 4). 建立合适的索引减少IO 5). 将索引数据和表数据分开在不同的表空间上降低IO冲突 6). 建立表分区将数据分别存储在不同的分区上以空间换取时间减少IO 逻辑上优化 1). 可以对表进行逻辑分割如中国移动用户表可以根据手机尾数分成10个表这样对性能会有一定的作用 2). Sql语句使用占位符语句并且开发时候必须按照规定编写sql语句如全部大写全部小写等oracle解析语句后会放置到共享池中 如 select * from Emp where name? 这个语句只会在共享池中有一条而如果是字符串的话那就根据不同名字存在不同的语句所以占位符效率较好 3). 数据库不仅仅是一个存储数据的地方同样是一个编程的地方一些耗时的操作可以通过存储过程等在用户较少的情况下执行从而错开系统使用的高峰时间提高数据库性能 4). 尽量不使用*号如select * from Emp因为要转化为具体的列名是要查数据字典比较耗时 5). 选择有效的表名 对于多表连接查询可能oracle的优化器并不会优化到这个程度 oracle 中多表查询是根据FROM字句从右到左的数据进行的那么最好右边的表也就是基础表选择数据较少的表这样排序更快速如果有link表多对多中间表那么将link表放最右边作为基础表在默认情况下oracle会自动优化但是如果配置了优化器的情况下可能不会自动优化所以平时最好能按照这个方式编写sql 6). Where字句 规则 Oracle 中Where字句时从右往左处理的表之间的连接写在其他条件之前能过滤掉非常多的数据的条件放在where的末尾 另外!符号比较的列将不使用索引列经过了计算如变大写等不会使用索引需要建立起函数 is null、is not null等优化器不会使用索引 7). 使用Exits Not Exits 替代 In Not in 8). 合理使用事务合理设置事务隔离性 数据库的数据操作比较消耗数据库资源的尽量使用批量处理以降低事务操作次数 Oracle有哪几种索引? 单列索引与复合索引 单列索引是基于单列所创建的索引复合索引是基于两列或者多列所创建的索引 唯一索引与非唯一索引 唯一索引是索引列值不能重复的索引非唯一索引是索引列可以重复的索引。都允许取 NULL 值默认 Oracle 创建的索引是不唯一索引 B 树索引 B 树索引是按 B 树算法组织并存放索引数据的B 树索引主要依赖其组织并存放索引数据的算法来实现快速检索功能 位图索引 它采用位图偏移方式来与表的行 ROWID 号对应通过位图索引中的映射函数完成位到行的 ROWID 的转换 主要用于节省空间减少oracle对数据块的访问 采用位图索引一般是重复值太多、只有几个枚举值的表字段 函数索引 Oracle 对包含列的函数或表达式创建的索引 哪些因素影响oracle查询性能 硬件处理器速度内存大小磁盘读写速度网络传输速度等索引是否建立了索引索引是否合理碎片表碎片和索引碎片生产库长时间运营碎片可能导致查询使用错误的执行计划导致查询速度变慢initial 参数表或索引的 initial 参数配置不同导致数据扩展区大小不一也可能导致查询速度降低慢 SQL编写的 SQL 执行效率低查询速度慢负载数据库负载过大 Oracle中排序对性能的影响 order by 只有满足如下情况才会使用索引 order by中的列必须包含相同的索引并且索引顺序和排序顺序一致不能有 null 值的列 所以排序的性能并不高尽量避免 order by Oracle中字符串用什么符号链接 Oracle中使用 || 这个符号连接字符串 如 ‘abc’ || ‘d’ Oracle有哪些备份方式 备份就是把数据库复制到转储设备的过程 从物理与逻辑的角度 物理备份对数据库操作系统的物理文件(数据文件、控制文件、日志文件)的备份。物理备份又可以分为脱机备份(冷备份)和联机备份(热备份)前者是在关闭数据库的时候进行的后者是以归档日志的方式对运行的数据库进行备份逻辑备份对数据库逻辑组件(如表和存储过程等数据库对象)的备份。逻辑备份的手段很多如 EXP、EXPDP、第三方工具 从数据库的备份角度 完全备份每次对数据库进行完整备份增量备份在上次完全备份或增量备份后被修改的文件才会被备份差异备份备份自从上次完全备份之后被修改过的文件 冷备和热备的优缺点 冷备发生在数据库已经正常关闭的情况下将数据库文件拷贝到其他位置 热备是在数据库运行的情况下采用归档方式备份数据 冷备的优缺点 只需拷贝文件非常快速 拷贝即可容易归档 文件拷贝回去即可恢复到某个时间点上 能与归档方法相结合 冷备份的不足 只能提供到数据库文件备份的时间点的恢复 在冷备过程中数据库必须是关闭状态不能工作 不能按表或按用户恢复 热备的优缺点 可在表空间或数据文件级备份 备份时数据库可用 可达到秒级恢复到某时间点 可对几乎所有数据库实体作恢复 数据完整性与一致性好 热备份的不足 维护较复杂 设备要求高网络环境稳定性要求高 若热备份不成功所得结果不可用 Oracle怎么分页 Oracle 使用 rownum 进行分页 select col1,col2 from ( select rownum r,col1,col2 from tablename where rownum 20 ) where r 10 怎样创建一个视图,视图的好处, 视图可以控制权限吗? create view 视图名 as select 列名 [别名] … from 表 [unio [all] select … ] ] 好处 \1. 可以简单的将视图理解为sql查询语句视图最大的好处是不占系统空间 \2. 一些安全性很高的系统不会公布系统的表结构可能会使用视图将一些敏感信息过虑或者重命名后公布结构 \3. 简化查询 可以控制权限的在使用的时候需要将视图的使用权限grant给用户 rowid, rownum的定义 \1. rowid和rownum都是虚列 \2. rowid是物理地址用于定位oracle中具体数据的物理存储位置 \3. rownum则是sql的输出结果排序从下面的例子可以看出其中的区别。 oracle中存储过程游标和函数的区别 游标类似指针游标可以执行多个不相关的操作.如果希望当产生了结果集后,对结果集中的数据进行多 种不相关的数据操作 函数可以理解函数是存储过程的一种 函数可以没有参数,但是一定需要一个返回值存储过程可以没有参数,不需要返回值两者都可以通过out参数返回值, 如果需要返回多个参数则建议使用存储过程在sql数据操纵语句中只能调用函数而不能调用存储过程 Oracle怎样实现每天备份一次 通过操作系统的定时任务调用脚本导出数据库 windows 在 任务计划程序 里创建基本任务设置备份周期执行 bat 脚本脚本参考 cd d:\oracle_back del oracle.dmp expdp username/passwordorcl directoryDIR_EXP dumpfileoracle.dmplinux 通过 crontab 制作定时任务执行 shell 脚本脚本参考 cd /back/oracle_back rm oracle.dmp expdp username/passwordorcl directoryDIR_EXP dumpfileoracle.dmpOracle分区有哪些作用? Oracle的分区分为列表分区、范围分区、散列分区、复合分区增强可用性表的一个分区由于系统故障不能使用其他好的分区仍可以使用减少故障修复时间如果系统故障只影响表的一部份分区只需修复部分分区比修复整个表花的时间少维护轻松独产管理公区比管理单个大表轻松均衡 I/O把表的不同分区分配到不同的磁盘平衡 I/O改善性能对大表的查询、增加、修改等操作可以分解到表的不同分区来并行执行加快执行速度在使用层是感觉不到分区的存在 Oracle数据库如何迁移 使用 imp/exp 将老库中的数据导入到新的库中。可以跨平台使用但停机时间长如果是存储迁移直接将存储设备挂到新机器上在新机器上启动数据库。这种方式操作简单但要求新老库版本一致使用 rman适合跨文件系统的迁移使用 dataguard 迁移借助工具如 pl/sql oracle临时表有几种。 临时表和普通表的主要区别有哪些使用临时表的主要原因是什么 在Oracle中可以创建以下两种临时表 a。会话特有的临时表 CREATE GLOBAL TEMPORARY ( ) ON COMMIT PRESERVE ROWS b。事务特有的临时表 CREATE GLOBAL TEMPORARY ( ) ON COMMIT DELETE ROWS CREATE GLOBAL TEMPORARY TABLE MyTempTable 所建的临时表虽然是存在的但是你试一下insert 一条记录然后用别的连接登上去select记录是空的明白了吧。 下面两句话再贴一下 –ON COMMIT DELETE ROWS 说明临时表是事务指定每次提交后ORACLE将截断表删除全部行 –ON COMMIT PRESERVE ROWS 说明临时表是会话指定当中断会话时ORACLE将截断表。 Oracle存储文件类型的字段 clob可变长度的字符型数据文本型数据类型nclob可变字符类型的数据存储的是 Unicode 字符集的字符数据blob可变长度的二进制数据Bfile存储在数据库外的操作系统文件变二进制数据不参与数据库事务操作 oracle数据库中有多行相同数据,只留一行怎么实现? distinct 函数查询出来 插入另一张表 最简单了 select distinct col1,col2,col3 from table Redis 介绍一下Redis Redis 是一款使用 C 语言编写的高性能 key-value 数据库开源免费遵守 BSD 协议。 特点 性能极高能到 100000 次/s 读写速度支持数据的持久化对数据的更新采用Copy-on-write技术可以异步地保存到磁盘上丰富的数据类型String(字符串)、List(列表)、Hash(字典)、Set(集合)、Sorted Set(有序集合)原子性Redis 的所有操作都是原子性的多个操作通过 MULTI 和 EXEC 指令支持事务丰富的特性key 过期、publish/subscribe、notify支持数据的备份快速的主从复制节点集群很容易将数据分布到多个Redis实例中 Redis支持哪些数据类型 string字符串 hash哈希 list列表 set集合 sorted set有序集合 redis受到攻击怎么办 1.主从配置 2.持久化储存redis不以root账户启动 3,。增加redis密码验证设置复杂密码 4.不允许key方式登录 5.以非root权限启动redis 6.禁止公网开放redis端口 7.检查authorized_keys是否非法 Redis 缓存穿透、击穿、雪崩现象及解决方案 缓存穿透 1、缓存空结果 如果系统发现 Redis 及 DB 中都不存在该资源就缓存空结果一段时间。需要注意哈这次的失效时间不能设置的太长否则数据的实效性会产生很大的问题。 2、用户合法性校验 对用户的请求合法性进行校验拦截恶意重复请求。 3、布隆过滤器 看到这个名词不要慌。简单来说布隆过滤器的用途就是帮助你判断某个值是否存在。举个例子来看下假设我们现在有一个长度为 9 的 bit 数组该数组的每个位置上只能保存 1 或者 01 标识该位置被占用0 标识该位置未被使用。 对于 key1我们借助三个 Hash 函数分别对其哈希运算。 再将得到的这三个哈希值对 9 求模。 最后将这三个模值落入到 bit 数组上。 key2、key3 按照同样的方式再处理一遍。 缓存击穿 关键词定点打击 试想如果所有请求对着一个 key 照死里搞这是不是就是一种定点打击呢 怎么理解呢举个极端的例子比如某某明星爆出一个惊天狠料海量吃瓜群众同时访问微博去查看该八卦新闻而微博 Redis 集群中数据在此刻正好过期了那么无数的请求则直接打到了微博系统的物理 DB 上DB 瞬间挂了。 解决方案 1、热点数据永远不过期 比如我们可以将某个 key 的缓存时间设置为 25 小时然后后台有个 JOB 每隔 24 小时就去批量刷新一下热点数据。就可以解决这个问题了。 2、使用互斥锁 容易影响吞吐量大部分项目设置热点 key 永不过期就妥妥的了。 缓存雪崩 关键词Redis 崩了没有数据了 这里的 Redis 崩了指的并不是 Redis 集群宕机了。而是说在某个时刻 Redis 集群中的热点 key 都失效了。如果集群中的热点 key 在某一时刻同时失效了的话试想海量的请求都将直接打到 DB 上DB 可能在瞬间就被打爆了。 解决方案 1、Redis 失效时间加上随机数 Redis 失效时间加上随机数是一种比较取巧的解决方案。在一定程度上减轻了 DB 的瞬时压力但是这种方案也在一定程度上增加了维护的成本。 2、Redis 永不过期 实现方案在上文中简单提过了。 Redis 缓存穿透、击穿、雪崩的区别 缓存穿透—穿过绕过 Redis 和 DB 来搞你缓存击穿—定点打击来搞你缓存雪崩—热点 key 在某一个时刻同时失效 Redis有哪些优缺点 优点 性能极高能到 100000 次/s 读写速度支持数据的持久化对数据的更新采用Copy-on-write技术可以异步地保存到磁盘上丰富的数据类型String(字符串)、List(列表)、Hash(字典)、Set(集合)、Sorted Set(有序集合)原子性Redis 的所有操作都是原子性的多个操作通过 MULTI 和 EXEC 指令支持事务丰富的特性key 过期、publish/subscribe、notify支持数据的备份快速的主从复制节点集群很容易将数据分布到多个Redis实例中 缺点 数据库容量受到物理内存的限制不能用作海量数据的高性能读写适合的场景主要局限在较小数据量的高性能操作和运算上 Redis的哨兵原理 每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown). 若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master彻底死亡(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。 虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel)。 哨兵有三个定时监控任务完成对各节点的发现和监控 任务1每个哨兵节点每10秒会向主节点和从节点发送info命令获取最拓扑结构图哨兵配置时只要配置对主节点的监控即可通过向主节点发送info获取从节点的信息并当有新的从节点加入时可以马上感知到 **任务2**每个哨兵节点每隔2秒会向redis数据节点的指定频道上发送该哨兵节点对于主节点的判断以及当前哨兵节点的信息同时每个哨兵节点也会订阅该频道来了解其它哨兵节点的信息及对主节点的判断其实就是通过消息publish和subscribe来完成的 **任务3**每隔1秒每个哨兵会向主节点、从节点及其余哨兵节点发送一次ping命令做一次心跳检测这个也是哨兵用来判断节点是否正常的重要依据 主观下线和客观下线 **主观下线**刚知道哨兵节点每隔1秒对主节点和从节点、其它哨兵节点发送ping做心跳检测当这些心跳检测时间超过down-after-milliseconds时哨兵节点则认为该节点错误或下线这叫主观下线这可能会存在错误的判断。 **客观下线**当主观下线的节点是主节点时此时该哨兵3节点会通过指令sentinel is-masterdown-by-addr寻求其它哨兵节点对主节点的判断当超过quorum法定人数个数此时哨兵节点则认为该主节点确实有问题这样就客观下线了大部分哨兵节点都同意下线操作也就说是客观下线 领导者哨兵选举流程 **a,**每个在线的哨兵节点都可以成为领导者当它确认比如哨兵3主节点下线时会向其它哨兵发is-master-down-by-addr命令征求判断并要求将自己设置为领导者由领导者处理故障转移 **b,**当其它哨兵收到此命令时可以同意或者拒绝它成为领导者 **c,**如果哨兵3发现自己在选举的票数大于等于num(sentinels)/21时将成为领导者如果没有超过继续选举………… 心跳检测 在命令传播阶段从服务器默认以每秒一次的频率向主服务器发送命令 REPLCONF ACK replication_offset //replication_offset是从服务器当前的复制偏移量。 心跳检测的作用检测主服务器的网络连接状态辅助实现min-slaves选项检测命令丢失。 检测主从服务器的网络连接状态 通过向主服务器发送INFO replication命令可以列出从服务器列表可以看出从最后一次向主发送命令距离现在过了多少秒。 redis主从复制 Redis主从复制可以根据是否是全量分为全量同步和增量同步。 全量复制 Redis全量复制一般发生在Slave初始化阶段这时Slave需要将Master上的所有数据都复制一份。具体步骤如下   1Slave 连接Master 发送SYNC命令   2Master 接收到SYNC命名后开始执行BGSAVE命令生成RDB文件 , 同时将这之后新的写命令记入缓冲区   3Master BGSAVE执行完后向所有Slave 发送快照文件 并继续记录写命令   4Slave 收到快照文件后丢弃所有旧数据载入收到的快照   5Master 快照发送完毕后开始向Slave 发送缓冲区中的写命令   6Slave 完成对快照的载入开始接收命令请求并执行来自Master 缓冲区的写命令   完成上面几个步骤后就完成了从服务器数据初始化的所有操作从服务器此时可以接收来自用户的读请求。 增量复制 增量复制的过程主要是主服务器每执行一个写命令就会向从服务器发送相同的写命令从服务器接收并执行收到的写命令。 Redis主从同步策略 主从刚刚连接的时候进行全量同步全同步结束后进行增量同步。当然如果有需要slave 在任何时候都可以发起全量同步。redis 策略是无论如何首先会尝试进行增量同步如不成功要求从机进行全量同步。 Redis持久化机制有哪些各有什么优缺点 持久化就是把内存的数据写到磁盘中去防止服务宕机了内存数据丢失。 Redis 提供两种持久化机制 RDB 和 AOF RDB(**RDBRedis DataBase*) 指用数据集快照的方式半持久化模式记录 redis 数据库的所有键值对在某个时间点将数据写入一个临时文件持久化结束后用这个临时文件替换上次持久化的文件可恢复数据 优点 只有一个文件 dump.rdb恢复操作简单容灾性好性能较高fork 子进程进行写操作主进程继续处理命令大数据集比 AOF 的恢复效率高 缺点 数据安全性低RDB 是每间隔一段时间进行持久化若期间 redis 发生故障可能会发生数据丢失 AOFAOFAppend-only file 指所有的命令行记录以 redis 命令请求协议的格式完全持久化存储保存为 aof 文件 优点 数据安全aof 持久化可以配置 appendfsync 属性为 always记录每个命令操作到 aof 文件中一次通过 append 模式写文件即使中途服务器宕机也可以通过 redis-check-aof 工具解决数据一致性问题AOF 机制的 rewrite 模式AOF 文件没被 rewrite 之前可以进行处理如删除文件中的 flushall 命令 缺点 AOF 的持久化文件比 RDB 大恢复速度慢 Redis使用过程中的注意事项 主库压力很大可以考虑读写分离Master 最好不要做持久化工作如 RDB 内存快照和 AOF 日志文件。(Master 写内存快照save 命令调度 rdbSave 函数会阻塞主线程文件较大时会间断性暂停服务AOF 文件过大会影响 Master 重启的恢复速度)如果数据比较重要使用 AOF 方式备份数据设置合理的备份频率保证主从复制的速度和网络连接的稳定性主从机器最好在同一内网官方推荐使用 sentinel 集群配合多个主从节点集群解决单点故障问题实现高可用 Redis过期键的删除策略有哪些 定时删除在设置键的过期时间的同时创建一个定时器达到过期时间执行键的删除操作惰性删除不主动删除过期键从键空间中获取键时都检查取得的键是否过期过期则删除没过期则返回定期删除每隔一段时间对数据库进行一次检查删除里面的过期键。删除多少过期键、检查多少个数据库由算法决定。 为什么Redis所有数据放到内存中 Redis 为了达到最快的读写速度将数据都读到内存中并通过异步的方式将数据写入磁盘所以 Redis 具有高速读写和数据持久化的特征如果程序直接与磁盘交互磁盘 IO 速度会严重影响 Redis 的性能内存的硬件成本降低使得 Redis 更受欢迎 说说Redis的同步机制 Redis 通过同步(sync)和指令传播(command propagate)两个操作完成同步 同步(sync)将从节点的数据库状态更新至与主节点的数据库状态一致 从节点向主节点发送 SYNC 指令收到 SYNC 指令主节点执行 BGSAVE 指令在后台生成一个 RDB 文件并使用一个缓冲区记录从现在开始执行的所有写指令主节点 BGSAVE 指令执行后会将生成的 RDB 文件发送给从节点从节点接收、载入 RDB 文件将数据库状态更新至主节点执行 BGSAVE 指令时的数据库状态从节点加载完 RDB 文件通知主节点将记录在缓冲区里面的所有写指令发送给从节点从节点执行这些写指令将数据库状态更新至主节点当前数据库状态 说说Redis集群 主从同步/复制解决读写分离的问题。分为主库 master、从库 slave。一般主库可以写数据从库只读自动同步主库更新的数据。集群情况下有节点宕机会导致请求不可用主机宕机可能会导致数据不一致从机重启同步数据需要考虑主机的 io 压力。生产环境建议使用下面两种方法Redis Sentinel哨兵机制解决主从节点高可用的问题。监控主从服务器运行状态检测到 master 宕机时会发布消息进行选举自动将 slave 提升为 masterRedis Cluster分布式解决方案解决单点故障与扩展性以及哨兵机制中每台 Redis 服务器都存储相同的数据浪费内存的问题。实现了 Redis 的分布式存储也就是每台 Redis 节点上存储不同的内容 说说遇到的Redis集群方案不可用的情况 集群主库半数宕机(根据 failover 原理fail 掉一个主需要一半以上主都投票通过才可以)集群某一节点的主从全数宕机 Redis如何设置密码 配置文件修改 requirepass 属性重启有效 指令设置密码为 123456无需重启 config set requirepass 123456设置验证密码为 654321登录完之后没有通过密码认证还是无法访问 Redis auth 654321Redis 集群会有写操作丢失吗 以下情况可能导致写操作丢失 过期 key 被清理最大内存不足导致 Redis 自动清理部分 key 以节省空间主库故障后自动重启从库自动同步单独的主备方案网络不稳定触发哨兵的自动切换主从节点切换期间会有数据丢失 Redis如何做内存优化 缩减键值对象满足业务要求下 key 越短越好value 值进行适当压缩共享对象池即 Redis 内部维护[0-9999]的整数对象池开发中在满足需求的前提下尽量使用整数对象以节省内存尽可能使用散列表(hashes)编码优化控制编码类型控制 key 的数量 Redis集群之间是如何复制 2.8 版以前Redis 通过同步(sync)和指令传播(command propagate)两个操作完成同步 同步(sync)将从节点的数据库状态更新至与主节点的数据库状态一致指令传播(command propagate)主节点数据被修改会主动向从节点发送执行的写指令从节点执行之后两个节点数据状态又保持一致 2.8 版开始新增 PSYNC 指令PSYNC 具有两种模式 完整重同步(full resynchronization)与 SYNC 过程基本一致部分重同步(partial resynchronization)借助复制偏移量、复制积压缓冲区、服务器运行 ID 完成主从节点断开连接后从节点重连主节点后条件允许主节点将连接断开期间执行的写指令发送给从节点从节点接收并执行写指令将数据库更新至主节点当前状态 Redis如何选择数据库 SELECT index切换到指定的数据库数据库索引号 index 用数字值指定0 作为起始索引值 连接建立后如果不 select默认对 db 0 操作 说一说你对Redis的事务的理解 Redis事务的特性 事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中不会被其他客户端发送来的命令请求所打断。没有隔离级别事务提交前结果不可见事务提交执行后可见不保证原子性Redis 同一个事务中有命令执行失败其后的命令仍然会被执行不会回滚 事务三阶段 开启MULTI 指令开启一个事务入队将多个命令入队到事务中这些命令不会立即执行而是放到等待执行的事务队列执行由 EXEC 指令触发事务执行 相关指令 multi标记一个事务块的开始返回 okexec执行所有事务块内事务块内所有命令执行的先后顺序的返回值操作被返回空值 nildiscard取消事务放弃执行事务块内的所有命令返回 okwatch监视 key 在事务执行之前是否被其他指令改动若已修改则事务内的指令取消执行返回 okunwatch取消 watch 命令对 key 的监视返回 ok Redis如何设置过期时间 redis.expire(key, expiration)setex name2 10 wangwu 设置一个键值对时间为10秒过期后自动删除 MySQL里有2000w数据redis中只存20w的数据如何保证redis中的数据都是热点数据 这个问题主要考察了以下几点内容 1.Redis的内存淘汰策略。 2.Redis的最大内存设置。 思路首先计算出20w数据所需的内存空间设置最大内存然后选择合适的内存淘汰策略。 内存淘汰策略 1volatile-lru从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。 2volatile-ttl从已设置过期时间的数据集中挑选将要过期的数据淘汰。 3volatile-random从已设置过期时间的数据集中任意选择数据淘汰。 4volatile-lfu从已设置过期时间的数据集挑选使用频率最低的数据淘汰。 5allkeys-lru从数据集中挑选最近最少使用的数据淘汰 6allkeys-lfu从数据集中挑选使用频率最低的数据淘汰。 7allkeys-random从数据集server.db[i].dict中任意选择数据淘汰 8 no-enviction驱逐禁止驱逐数据这也是默认策略。意思是当内存不足以容纳新入数据时新写入操作就会报错请求可以继续进行线上任务也不能持续进行采用no-enviction策略可以保证数据不被丢失。 Redis事务支持隔离性吗 Redis 是单进程程序并且它保证在执行事务时不会对事务进行中断事务可以运行直到执行完所有事务队列中的命令为止。因此Redis 的事务是总是带有隔离性的。 Redis事务保证原子性吗支持回滚吗 Redis中单条命令是原子性执行的但事务不保证原子性且没有回滚。事务中任意命令执行失败其余的命令仍会被执行。 nginx 什么是Nginx Nginx是一个 轻量级/高性能的反向代理Web服务器他实现非常高效的反向代理、负载平衡他可以处理2-3万并发连接数官方监测能支持5万并发现在中国使用nginx网站用户有很多例如新浪、网易、 腾讯等。 为什么要用Nginx 跨平台、配置简单、方向代理、高并发连接处理2-3万并发连接数官方监测能支持5万并发内存消耗小开启10个nginx才占150M内存 nginx处理静态文件好耗费内存少 而且Nginx内置的健康检查功能如果有一个服务器宕机会做一个健康检查再发送的请求就不会发送到宕机的服务器了。重新将请求提交到其他的节点上。 使用Nginx的话还能 节省宽带支持GZIP压缩可以添加浏览器本地缓存 稳定性高宕机的概率非常小 接收用户请求是异步的 为什么Nginx性能这么高 因为他的事件处理机制异步非阻塞事件处理机制运用了epoll模型提供了一个队列排队解决 Nginx怎么处理请求的 nginx接收一个请求后首先由listen和server_name指令匹配server模块再匹配server模块里的locationlocation就是实际地址 server { # 第一个Server区块开始表示一个独立的虚拟主机站点 listen 80 # 提供服务的端口默认80 server_name localhost # 提供服务的域名主机名 location / { # 第一个location区块开始 root html # 站点的根目录相当于Nginx的安装目录 index index.html index.htm # 默认的首页文件多个用空格分开 } # 第一个location区块结果 什么是正向代理和反向代理 正向代理就是一个人发送一个请求直接就到达了目标的服务器 反方代理就是请求统一被Nginx接收nginx反向代理服务器接收到之后按照一定的规 则分发给了后端的业务处理服务器进行处理了 使用“反向代理服务器的优点是什么? 反向代理服务器可以隐藏源服务器的存在和特征。它充当互联网云和web服务器之间的中间层。这对于安全方面来说是很好的特别是当您使用web托管服务时。 Nginx的优缺点 优点 占内存小可实现高并发连接处理响应快 可实现http服务器、虚拟主机、方向代理、负载均衡 Nginx配置简单 可以不暴露正式的服务器IP地址 缺点 动态处理差nginx处理静态文件好,耗费内存少但是处理动态页面则很鸡肋现在一般前端用nginx作为反向代理抗住压力 Nginx应用场景 http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。 虚拟主机。可以实现在一台服务器虚拟出多个网站例如个人网站使用的虚拟机。 反向代理负载均衡。当网站的访问量达到一定程度后单台服务器不能满足用户的请求时需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载不会应为某台服务器负载高宕机而某台服务器闲置的情况。 nginz 中也可以配置安全管理、比如可以使用Nginx搭建API接口网关,对每个接口服务进行拦截。 如何用Nginx解决前端跨域问题 使用Nginx转发请求。把跨域的接口写成调本域的接口然后将这些接口转发到真正的请求地址。 Nginx虚拟主机怎么配置? 1、基于域名的虚拟主机通过域名来区分虚拟主机——应用外部网站 2、基于端口的虚拟主机通过端口来区分虚拟主机——应用公司内部网站外部网站的管理后台 3、基于ip的虚拟主机。 限流怎么做的 Nginx限流就是限制用户请求速度防止服务器受不了 限流有3种 正常限制访问频率正常流量 限制一个用户发送的请求我Nginx多久接收一个请求。 Nginx中使用ngx_http_limit_req_module模块来限制的访问频率限制的原理实质是基于漏桶算法原理来实现的。在nginx.conf配置文件中可以使用limit_req_zone命令及limit_req命令限制单个IP的请求处理频率。 突发限制访问频率突发流量 限制一个用户发送的请求我Nginx多久接收一个。 上面的配置一定程度可以限制访问频率但是也存在着一个问题如果突发流量超出请求被拒绝处理无法处理活动时候的突发流量这时候应该如何进一步处理呢Nginx提供burst参数结合nodelay参数可以解决流量突发的问题可以设置能处理的超过设置的请求数外能额外处理的请求数。 限制并发连接数 Nginx中的ngx_http_limit_conn_module模块提供了限制并发连接数的功能可以使用limit_conn_zone指令以及limit_conn执行进行配置。 Nginx的限流都是基于漏桶流算法 漏桶算法 漏桶算法是网络世界中流量整形或速率限制时经常使用的一种算法它的主要目的是控制数据注入到网络的速率平滑网络上的突发流量。漏桶算法提供了一种机制通过它突发流量可以被整形以便为网络提供一个稳定的流量。也就是我们刚才所讲的情况。漏桶算法提供的机制实际上就是刚才的案例突发流量会进入到一个漏桶漏桶会按照我们定义的速率依次处理请求如果水流过大也就是突发流量过大就会直接溢出则多余的请求会被拒绝。所以漏桶算法能控制数据的传输速率。 Nginx负载均衡的算法怎么实现的?策略有哪些? 为了避免服务器崩溃大家会通过负载均衡的方式来分担服务器压力。将对台服务器组成一个集群当用户访问时先访问到一个转发服务器再由转发服务器将访问分发到压力更小的服务器。 Nginx负载均衡实现的策略有以下五种 1 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器如果后端某个服务器宕机能自动剔除故障系统。 upstream backserver { server 192.168.0.12; server 192.168.0.13; } 2 权重 weight weight的值越大分配到的访问概率越高主要用于后端每台服务器性能不均衡的情况下。其次是为在主从的情况下设置不同的权值达到合理有效的地利用主机资源。 upstream backserver { server 192.168.0.12 weight2; server 192.168.0.13 weight8; } 权重越高在被访问的概率越大如上例分别是20%80%。 3 ip_hash( IP绑定) 每个请求按访问IP的哈希结果分配使来自同一个IP的访客固定访问一台后端服务器并且可以有效解决动态网页存在的session共享问题 upstream backserver { ip_hash; server 192.168.0.12:88; server 192.168.0.13:80; 4 fair(第三方插件) 必须安装upstream_fair模块。 对比 weight、ip_hash更加智能的负载均衡算法fair算法可以根据页面大小和加载时间长短智能地进行负载均衡响应时间短的优先分配。 upstream backserver { server server1; server server2; fair; 哪个服务器的响应速度快就将请求分配到那个服务器上。 5、url_hash(第三方插件) 必须安装Nginx的hash软件包 按访问url的hash结果来分配请求使每个url定向到同一个后端服务器可以进一步提高后端缓存服务器的效率。 upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; } Linux linux如何添加新系统用户? 以 root 身份登录 linux 系统进入终端增加一个新用户useradd 用户名设置密码passwd 用户名 什么是bash别名 相当于自定义 shell 指令 如ll 指令可以查看文件的详细信息ll 就是一个被定义好的别名能够大大的简化指令 1.通过 alias 命令可以查看命令别名 [root]# alias alias cpcp -i alias egrepegrep --colorauto alias fgrepfgrep --colorauto alias grepgrep --colorauto 2.定义新的别 [root]#alias rmall rm -rf 3.取消别名 [root]# unalias rmalllinux指令-ls list 的缩写通过 ls 命令不仅可以查看 linux 文件夹包含的文件而且可以查看文件权限(包括目录、文件夹、文件权限)、查看目录信息等等。 删除目录 rmdir 改变 linux 系统文件或目录的访问权限 chmod 该命令有两种用法一种是包含字母和操作符表达式的文字设定法另一种是包含数字的数字设定法 每一文件或目录的访问权限都有三组每组用三位代号表示 文件属主的读、写和执行权限与属主同组的用户的读、写和执行权限系统中其他用户的读、写和执行权限 常用参数 -c 当发生改变时报告处理信息 -R 处理指定目录以及其子目录下所有文件 权限范围 u目录或者文件的当前的用户 g目录或者文件的当前的群组 o除了目录或者文件的当前用户或群组之外的用户或者群组 a所有的用户及群组 权限代号 r读权限用数字4表示 w写权限用数字2表示 x执行权限用数字1表示 -删除权限用数字0表示 s特殊权限查看文件内容有哪些命令可以使用 vi 文件名 #编辑方式查看可修改 cat 文件名 #显示全部文件内容 more 文件名 #分页显示文件内容 less 文件名 #与 more 相似更好的是可以往前翻页 tail 文件名 #仅查看尾部还可以指定行数 head 文件名 #仅查看头部,还可以指定行数 复制文件用哪个命令如果需要连同文件夹一块复制呢如果需要有提示功能呢 cp cp -r 删除文件用哪个命令如果需要连目录及目录下文件一块删除呢删除空文件夹用什么命令 rm rm -r rmdir Linux 下命令有哪几种可使用的通配符分别代表什么含义? “”可替代单个字符。 “*”可替代任意多个字符。 方括号“[charset]”可替代 charset 集中的任何单个字符如[a-z][abABC] 用什么命令对一个文件的内容进行统计(行号、单词数、字节数) wc 命令 - c 统计字节数 - l 统计行数 - w 统计字数。 搜索文件用什么命令? 格式是怎么样的? find 指定目录 指定条件 指定动作 whereis 加参数与文件名 locate 只加文件名 find 直接搜索磁盘较慢。 find / -name “string*” 使用什么命令查看用过的命令列表? history docker 什么是docker什么是docker镜像 docker是一个容器化平台它以容器的形式将您的应用程序及其所有依赖项打包在一起以确保您的应用程序在任何环境中无缝运行。 是docker容器的源代码用于创建容器。使用build命令创建镜像。 什么是docker容器docker容器有几种状态docker容器内部机制容器与主机之间的数据拷贝启动容器并挂在目录 1docker容器docker容器包括应用程序及其所有依赖项作为操作系统的独立进程运行。 2docker容器4种状态运行已暂停重新启动已退出 3docker容器内部机制每个容器都在自己的命名空间中运行但使用与所有其他容器完全相同的内核。发生隔离是因为内核知道分配给进程的命名空间并且在API调用期间确保进程只能访问其自己的命名空间中的资源。 【操作系统的一个功能是允许将全局资源如网络和磁盘共享到进程。如果将这些全局资源包装在命名空间中以使它们仅对在同一命名空间中运行的那些进程可见】 4主机copy到容器docker cp /www 96f7f14e99ab:/www/ 容器copy到主机docker cp 96f7f14e99ab:/www /tmp/ 5启动nginx容器(随机端口映射)并挂载本地文件目录到容器html的命令 docker run -d -P --name nginx2 -v /home/nginx:/usr/share/nginx/html nginx docker run Docker容器有几种状态 四种状态运行、已暂停、重新启动、已退出。 docker常用命令 docker pull 拉取或者更新指定镜像 docker push 将镜像推送至远程仓库 docker rm 删除容器 docker rmi 删除镜像 docker images 列出所有镜像 docker ps 列出所有容器 JVM JVM内存结构 JVM内存结构主要有三大块堆内存、方法区和栈。 堆内存是JVM中最大的一块由年轻代和老年代组成而年轻代内存又被分成三部分Eden空间、From Survivor空间、To Survivor空间,默认情况下年轻代按照8:1:1的比例来分配方法区存储类信息、常量、静态变量等数据是线程共享的区域为与Java堆区分方法区还有一个别名Non-Heap(非堆)栈又分为java虚拟机栈和本地方法栈主要用于方法的执行。 JAVA的JVM的内存可分为3个区堆(heap)、栈(stack)和方法区(method) 内存划分 Java虚拟机按照运行时内存使用区域划分如图 一、程序计数器(Program Counter Register) 程序计数器就是记录当前线程执行程序的位置改变计数器的值来确定执行的下一条指令比如循环、分支、方法跳转、异常处理线程恢复都是依赖程序计数器来完成。 Java虚拟机多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。为了线程切换能恢复到正确的位置每条线程都需要一个独立的程序计数器所以它是线程私有的。 如果线程正在执行的是一个Java方法这个计数器记录的是正在执行的虚拟机字节码指令的地址如果正在执行的是Native方法这个计数器值则为空Undefined。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。 二、Java虚拟机栈(VM Stack) Java虚拟机栈是线程私有生命周期与线程相同。创建线程的时候就会创建一个java虚拟机栈。 虚拟机执行java程序的时候每个方法都会创建一个栈帧栈帧存放在java虚拟机栈中通过压栈出栈的方式进行方法调用。 栈帧又分为一下几个区域局部变量表、操作数栈、动态连接、方法出口等。 平时我们所说的变量存在栈中这句话说的不太严谨应该说局部变量存放在java虚拟机栈的局部变量表中。 Java的8中基本类型的局部变量的值存放在虚拟机栈的局部变量表中如果是引用型的变量则只存储对象的引用地址。 注意 当用户请求web服务器每个请求开启一个线程负责用户的响应计算每个线程分配一个虚拟机栈空间如果并发量大时可能会导致内存溢出OutOfMemoneyError可以适当的把每个虚拟机栈的大小适当调小一点减少内存的使用量来提高系统的并发量。 当栈空间调小以后又会引发方法调用深度的的问题。因为每个方法都会生成一个栈帧如果方法调用深度很深就意味着栈里面存放大量的栈帧可能导致栈内存溢出StackOverFlowError。 三、本地方法栈(Native Method Stack) 本地方法栈 为虚拟机使用到本地方法服务native。本地方法栈为线程私有功能和虚拟机栈非常类似。线程在调用本地方法时来存储本地方法的局部变量表本地方法的操作数栈等等信息。 本地方法是非java语言实现的方法例如java调用C语言来操作某些硬件信息。 四、堆(Heap) 堆是被所有线程共享的区域实在虚拟机启动时创建的。堆里面存放的都是对象的实例new 出来的对象都存在堆中。 我们平常所说的垃圾回收主要回收的就是堆区。为了提升垃圾回收的性能又把堆分成两块区新生代young和年老代old更细一点划分新生代又可划分为Eden区和2个Survivor区From Survivor和To Survivor。 如下图结构 **Eden**新创建的对象存放在Eden区 **From Survivor和To Survivor**保存新生代gc后还存活的对象。使用复制算法导致有一个Survivor空间浪费Hotspot虚拟机新生代Eden和Survivor的大小比值为41因为有两个Survivor所以Eden:From Survivor:To Survivor比值为811。 **老年代**对象存活时间比较长经过多次新生代的垃圾收集默认是15次的对象则进入老年的。当堆中分配的对象实例过多且大部分对象都在使用就会报内存溢出异常OutOfMemoneyError。 五、方法区 方法区是被所有线程共享区域用于存放已被虚拟机加载的类信息常量静态变量等数据。被Java虚拟机描述为堆的一个逻辑部分。习惯是也叫它永久代permanment generation 永久代也会垃圾回收主要针对常量池回收类型卸载比如反射生成大量的临时使用的Class等信息。 常量池用于存放编译期生成的各种字节码和符号引用常量池具有一定的动态性里面可以存放编译期生成的常量运行期间的常量也可以添加进入常量池中比如string的intern()方法。 当方法区满时无法在分配空间就会抛出内存溢出的异常OutOfMemoneyError。 Java8中已经没有方法区了取而代之的是元空间Metaspace。 六直接内存 直接内存Direct Memory并不是虚拟机运行时数据区的一部分也不是Java虚拟机规范中定义的内存区域但是这部分内存也被频繁地使用而且也可能导致OutOfMemoryError异常出现。 JDK1.4加的NIO中ByteBuffer有个方法是allocateDirect(int capacity) 这是一种基于通道Channel与缓冲区Buffer的I/O方式它可以使用Native函数库直接分配堆外内存然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能因为避免了在Java堆和Native堆中来回复制数据。 GC垃圾回收 主要就是为了提高内存利用率只回收“托管堆中的内存资源”没有引用的对象。不回收“栈”上的资源比如值类型。 一个跟踪过程它传递性地跟踪指向当前使用的对象的所有指针以便找到可以引用的所有对象然后重新使用在此跟踪过程中未找到的任何堆内存。公共语言运行库垃圾回收器还压缩使用中的内存以缩小堆所需要的工作空间。 Java语言中一个显著的特点就是引入了垃圾回收机制使c程序员最头疼的内存管理的问题迎刃而解它使得Java程序员在编写程序的时候不再需要考虑内存管理。由于有个垃圾回收机制Java中的对象不再有“作用域”的概念只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露有效的使用可以使用的内存。垃圾回收器通常是作为一个单独的低级别的线程运行不可预知的情况下对内存堆中已经死亡的或者长时间没有使用的对象进行清楚和回收程序员不能实时的调用垃圾回收器对某个对象或所有对象进行垃圾回收。回收机制有分代复制垃圾回收和标记垃圾回收增量垃圾回收。 Java 程序员不用担心内存管理因为垃圾收集器会自动进行管理。要请求垃圾收集可以调用下面的方法之一 System.gc() Runtime.getRuntime().gc() GC垃圾回收机制 引入“代”的概念 ①总共有三代0~2代。 ②每次新建对象都在第0代中。 ③每代有固定大小。 这个叫“自动回收”肯定有小朋友会问那是不是可以手动回收。答案是肯定的比如析构函数就可以达到这个目的。 将引用可分为强引用、软引用、弱引用、虚引用。 强引用如果一个对象具有强引用垃圾回收器绝不会回收它。当内存空间不足Java虚拟机宁愿抛出OutOfMemoryError使程序异常终止 软引用如果内存空间够垃圾回收器就不会回收它如果内存空间不足了就会回收这些对象的内存只要垃圾回收器没有回收它该对象就可以被程序使用软引用可用来实现内存敏感的高速缓存。 弱引用比软引用更弱一些弱引用关联的对象只能生存到下一次垃圾回收发生之前。当垃圾收集器工作时无论当前内存是否足够都会回收掉只被弱引用关联的对象。 虚引用在任何时候都可能被垃圾回收器回收主要用于跟踪对象被垃圾回收器回收的活动 弱引用 人就是这样得不到的永远在骚动得到的有恃无恐。当失去了才追悔莫及。假如对象要被回收了但是我又想再次用这个对象该怎么办这个时候就出来了这个–“弱引用”。 为什么需要弱对象呢因为有一些数据创建起来很容易但是却需要很多内存。 例如有一个程序需要去访问用户硬盘上的所有文件夹和文件名你可以在程序第一次需要这个数据时访问用户磁盘生成一次数据数据生成之后你就可以访问内存中的数据来得到用户文件数据而不是每次都去读磁盘获得数据这样做可以提升程序的性能。 你可以这么理解你跟你女朋友闹分手微信电话什么的全部删除了但是还留着QQ以后想要联系可以通过这个QQ来联系而此时的这个QQ就相当于是弱引用了。至于为什么分手了还要联系这个原因也就是为什么要有弱引用的原因了~ 软引用、弱引用都在引用对象被垃圾回收之后JVM才把引用加入到与之关联的引用队列中而虚引用对象在垃圾回收之前JVM把引用加入到阈值关联的引用队列中。虚引用必须和引用队列联合使用当垃圾回收器准备回收一个对象时若发现它还有虚引用就会在回收对象的内存之前把这个虚引用加入到与之关联的引用队列中。这样就可以通过判断引用队列中是否已经加入了虚引用来了解被引用对象是否将要被垃圾回收器回收 GC 优化 将进入老年代的对象数量降到最低减少Full GC的执行时间优化JVM参数——堆和栈的大小设置垃圾收集器的模式 新生代和老年代的区别(阿里面试官的题目) 所谓的新生代和老年代是针对于分代收集算法来定义的新生代又分为Eden和Survivor两个区。加上老年代就这三个区。数据会首先分配到Eden区 当中当然也有特殊情况如果是大对象那么会直接放入到老年代大对象是指需要大量连续内存空间的java对象。当Eden没有足够空间的时候就会 触发jvm发起一次Minor GC。如果对象经过一次Minor GC还存活并且又能被Survivor空间接受那么将被移动到Survivor空 间当中。并将其年龄设为1对象在Survivor每熬过一次Minor GC年龄就加1当年龄达到一定的程度默认为15时就会被晋升到老年代 中了当然晋升老年代的年龄是可以设置的。如果老年代满了就执行Full GC 因为不经常执行因此采用了 Mark-Compact算法清理 新生代 新生代存放一些新生的对象实例。 新生代内又划分了3个区域分别是 Eden SurvivorFrom SurvivorTo 一般情况占据的位置是8:1:1 当新生代的Eden区区域不够的时候就会发生minor GC。 每当进行一次minor GC时区域间进行数据交换Eden区和SurvivorFrom区域会把存活的对象放进SurvivorTo区域。 在新生代之中一般采用复制算法进行GC。 老年代 老年代存放比较稳定存活的对象。 对于老年代有Major GC的垃圾回收机制。 有两个触发条件 一个是当新生代发生minor GC之后仍然不够位置存放新生对象时借用老年代空间不足时会发生major GC 另一个是当申请一个大的连续空间如大数组给较大对象时也会触发Major GC进行垃圾回收。 永久代 永久代在方法区内存放Class和Meta的信息。 在GC里面回收永久代的信息有两个 一是废弃变量 一个是无用的类 废弃变量比较好处理只要常量池中没有String对象引用也没有其他对象引用就会回收。 无用的类的话就有比较多的判断标准。 一是Java堆中没有这个类的实例对象 二是这个类的类加载器以及被回收 三是该类对应的Class对象没有被其他方法引用不能通过反射访问该类的方法 元数据 在Java8中完全移除了永久代这个概念新创建了元数据这个概念。 原本永久代存放的Meta的数据不再存在于方法区内而是依赖于Native Memory本地内存里而String常量池和类的静态变量转移到Java堆里因此Java堆内存有所变动。 默认情况下元数据只受本地内存限制操作系统的虚拟内存可以定义新参数MaxMetaspaceSize来限制元数据的大小如果不限制元空间就会根据需要动态调整。 JDK,JRE,JVM区别 Jdk中包括了JreJre中包括了JVM jdk Jdk还包括了一些Jre之外的东西 就是这些东西帮我们编译Java代码的 还有就是监控Jvm的一些工具 Java Development Kit是提供给Java开发人员使用的其中包含了Java的开发工具也包括了JRE。 jre Jre大部分都是 C 和 C 语言编写的他是我们在编译java时所需要的基础的类库 Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。 jvm Java程序需要运行在虚拟机上不同的平台有自己的虚拟机因此Java语言可以实现跨平台。 说一下堆栈的区别 \1. 栈内存存储的是局部变量而堆内存存储的是实体 \2. 栈内存的更新速度要快于堆内存因为局部变量的生命周期很短 \3. 栈内存存放的变量生命周期一旦结束就会被释放而堆内存存放的实体会被垃圾回收机制不定时的回收。 队列和栈是什么有什么区别 队列和栈都是被用来预存储数据的。队列允许先进先出检索元素但也有例外的情况Deque 接口允许从两端检索元素。栈和队列很相似但它运行对元素进行后进先出进行检索。 说一下类加载的执行过程 类加载分为以下 5 个步骤 加载根据查找路径找到相应的 class 文件然后导入检查检查加载的 class 文件的正确性准备给类中的静态变量分配内存空间解析虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示而在直接引用直接指向内存中的地址初始化对静态变量和静态代码块执行初始化工作 什么是乐观锁和悲观锁 悲观锁 Java在JDK1.5之前都是靠synchronized关键字保证同步的这种通过使用一致的锁定协议来协调对共享状态的访问可以确保无论哪个线程持有共享变量的锁都采用独占的方式来访问这些变量。独占锁其实就是一种悲观锁所以可以说synchronized是悲观锁。 乐观锁 乐观锁 Optimistic Locking其实是一种思想。相对悲观锁而言乐观锁假设认为数据一般情况下不会造成冲突所以在数据进行提交更新的时候才会正式对数据的冲突与否进行检测如果发现冲突了则让返回用户错误的信息让用户决定如何去做。 Zookeeper zookeeper 是什么 zookeeper 是一个分布式的开放源码的分布式应用程序协调服务是 google chubby 的开源实现是 hadoop 和 hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件提供的功能包括配置维护、域名服务、分布式同步、组服务等。 zookeeper 都有哪些功能 集群管理监控节点存活状态、运行请求等。主节点选举主节点挂掉了之后可以从备用的节点开始新一轮选主主节点选举说的就是这个选举的过程使用 zookeeper 可以协助完成这个过程。分布式锁zookeeper 提供两种锁独占锁、共享锁。独占锁即一次只能有一个线程使用资源共享锁是读锁共享读写互斥即可以有多线线程同时读同一个资源如果要使用写锁也只能有一个线程使用。zookeeper可以对分布式锁进行控制。命名服务在分布式系统中通过使用命名服务客户端应用能够根据指定名字来获取资源或服务的地址提供者等信息。配置中心 zookeeper 有几种部署模式 zookeeper 有三种部署模式 单机部署一台集群上运行集群部署多台集群运行伪集群部署一台集群启动多个 zookeeper 实例运行。 zookeeper 怎么保证主从节点的状态同步 zookeeper 的核心是原子广播这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 zab 协议。 zab 协议有两种模式分别是恢复模式选主和广播模式同步。当服务启动或者在领导者崩溃后zab 就进入了恢复模式当领导者被选举出来且大多数 server 完成了和 leader 的状态同步以后恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。 集群中为什么要有主节点 在分布式环境中有些业务逻辑只需要集群中的某一台机器进行执行其他的机器可以共享这个结果这样可以大大减少重复计算提高性能所以就需要主节点。 集群中有 3 台服务器其中一个节点宕机这个时候 zookeeper 还可以使用吗 可以继续使用单数服务器只要没超过一半的服务器宕机就可以继续使用。 说一下 zookeeper 的通知机制 客户端端会对某个 znode 建立一个 watcher 事件当该 znode 发生变化时这些客户端会收到 zookeeper 的通知然后客户端可以根据 znode 变化来做出业务上的改变。 集合 集合有两个父接口一个collection一个Map 而collection有两个子接口一个List一个Set List有两个常见的实现类 ArrayListLinkedList Set有两个常见的实现类 HashSetTreeSet Map有两个常见的实现类 HashMapHashTable。 ArrayList和Vector的联系和区别 相同点 底层都使用数组实现功能相同实现增删改查等操作的方法相似长度可变的数组结构 不同点 Vector是早期JDK版本提供ArrayList是新版本替代Vector的Vector 的方法都是同步的线程安全ArrayList 非线程安全但性能比Vector好默认初始化容量都是10Vector 扩容默认会翻倍可指定扩容的大小ArrayList只增加 50% Collection和Collections有什么区别 Collection 是JDK中集合层次结构中的最根本的接口。定义了集合类的基本方法。 Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法,不能实例化Collection 集合框架的工具类。 List、Set、Map 之间的区别是什么 List有序集合元素可重复Set不重复集合LinkedHashSet按照插入排序SortedSet可排序HashSet无序Map键值对集合存储键、值和之间的映射Key无序唯一value 不要求有序允许重复 HashMap和Hashtable 有什么区别 线程安全性不同。HashMap 线程不安全Hashtable 中的方法是 synchronized 的。key、value 是否允许 null。HashMap 的 key 和 value 都是可以是 nullkey 只允许一个 nullHashtable 的 key 和 value 都不可为 null。迭代器不同。HashMap 的 Iterator 是 fail-fast 迭代器Hashtable 还使用了 enumerator 迭代器。hash的计算方式不同。HashMap 计算了 hash值Hashtable 使用了 key 的 hashCode方法。默认初始大小和扩容方式不同。HashMap 默认初始大小 16容量必须是 2 的整数次幂扩容时将容量变为原来的2倍Hashtable 默认初始大小 11扩容时将容量变为原来的 2 倍加 1。是否有 contains 方法。HashMap 没有 contains 方法Hashtable 包含 contains 方法类似于 containsValue。父类不同。HashMap 继承自 AbstractMapHashtable 继承自 Dictionary。 如何决定使用HashMap还是TreeMap HashMap基于散列桶数组和链表实现TreeMap基于红黑树实现。HashMap不支持排序TreeMap默认是按照Key值升序排序的可指定排序的比较器主要用于存入元素时对元素进行自动排序。HashMap大多数情况下有更好的性能尤其是读数据。在没有排序要求的情况下使用HashMap。都是非线程安全。 HashMap原理 1无序的。 2可以接受null键值和值 3非同步的线程不安全的 1hashmap是我们几乎每天用到的集合类,它以键值对的形式存在。 2,在jdk1.7中底层是数组加链表1.8中采用的是数组加链表加红黑树红黑树的引入是为了提高查询效率 31.7中hash碰撞采用头插法头插法会形成循环链表1.8尾插法 4hash算法1.8进行了简化 5最好传入一个二的次幂的初始化容量 put时会初始化数组容量为大于等于初始化容量的最近的二次幂比如初始化容量为6他初始化就是8。 6key的hash值 与 上容量-1计算出所在位置 7扩容的问题加载因子0.75达到 容量 *0.75后就会扩容两倍扩容 8树化数组容量达到64,链表长度大于等于8后才会进行树化链表长度小于6就会解除树化 简单来说HashMap由数组链表组成的数组是HashMap的主体链表则是主要为了解决哈希冲突而存在的如果定位到的数组位置不含链表当前entry的next指向null,那么对于查找添加等操作很快仅需一次寻址即可如果定位到的数组包含链表对于添加操作其时间复杂度为O(n)首先遍历链表存在即覆盖否则新增对于查找操作来讲仍需遍历链表然后通过key对象的equals方法逐一比对查找。所以性能考虑HashMap中的链表出现越少性能才会越好。 ​ 以键值对key-value的形式存储元素 通过 hashcode() 和 equals() 方法定位键值对存储的准确位置 首先通过 hashcode() 获得key映射的散列值也叫 hash 值通过 hash 值确定键值对存储在哪个链表。不过不同的 key 生成的 hash 值可能是一样的。如果 hash 值定位到的存储空间存在其它的键值对那就通过 equals() 比较 key 如果一样就更新它的 value如果不一样就添加在链表后面通俗的说hashcode() 就相当于字典目录确定好某个字所在的页数equals()相当于页数上存放的位置 在场景应用上hashcode() 和 equals() 是重点修改的部分 手动实现 HashMap // 键值对存储 package HashMap;public class Entry {public Object key;public Object value;public Entry(Object key, Object value){this.key key;this.value value;}Overridepublic String toString() {return [key key , value value ];} }// putget接口 package HashMap;public interface IHashMap {public void put(Object key, Object object);public Object get(Object key); }package HashMap;import java.util.LinkedList;public class MyHashMap implements IHashMap {LinkedListEntry[] values new LinkedList[2000];Overridepublic void put(Object key, Object value) {// 获得 hash 值int hashcode hashcode(key);// 根据 hash 值确定存储在哪个链表位置LinkedListEntry list values[hashcode];if (null list) {list new LinkedList();values[hashcode] list;}boolean found false;for (Entry entry : list) {// 通过比较确定存储的链表位置if (key.equals(entry.key)) {entry.value value;found true;break;}}if (!found) {Entry entry new Entry(key, value);list.add(entry);}}Overridepublic Object get(Object key) {// 获得 hash 值int hashcode hashcode(key);// 根据 hash 值确定存储在哪个链表位置LinkedListEntry list values[hashcode];if (null list)return null;Object result null;// 通过比较确定存储的链表位置并取出相应的 valuefor (Entry entry : list) {if (entry.key.equals(key)) {result entry.value;}}return result;}// 自定义 hash 值使其落在 0~1999 之间private int hashcode(Object obj) {String str obj.toString();if (0 str.length())return 0;int hashcode 0;char[] cs str.toCharArray();for (int i 0; i cs.length; i) {hashcode cs[i];}hashcode * 23;// 取绝对值Math.abs(hashcode);// 取值落在 0 - 1999 之间hashcode % 2000;return hashcode;}public static void main(String[] args) {MyHashMap map new MyHashMap();map.put(test, 坦克);map.put(test, 物理);map.put(t, 坦克2);System.out.println(map.get(test));}}运行结果 场景应用 有一个 people 类HashMap 的 key 想通过 name 和 age 判断 people 是否相等而不是通过 people 对象的存储地址 实现方法根据 HashMap 原理需同时重写 equals() 和 hashCode()。很容易犯的错误是只重写 equals()而忘记重写 hashCode() package HashMap;import java.util.HashMap; import java.util.Set;class People {private String name;private int age;public People(String name, int age) {this.name name;this.age age;}public void setAge(int age) {this.age age;}Overridepublic int hashCode() {return name.hashCode() * 37 age;}Overridepublic boolean equals(Object obj) {return this.name.equals(((People) obj).name) this.age ((People) obj).age;}public static void main(String[] args) {People p1 new People(Jack, 12);HashMapPeople, Integer hashMap new HashMapPeople, Integer();hashMap.put(p1, 1);System.out.println(hashMap.get(new People(Jack, 12)));} }运行结果 ArrayList 基于动态数组实现的非线程安全的集合LinkedList 基于双向链表实现的非线程安全的集合。扩容问题ArrayList 使用数组实现无参构造函数默认初始化长度为 10数组扩容是会将原数组中的元素重新拷贝到新数组中长度为原来的 1.5 倍(扩容代价高)LinkedList 不存在扩容问题新增元素放到集合尾部修改相应的指针节点即可。LinkedList 比 ArrayList 更占内存因为 LinkedList 为每一个节点存储了两个引用节点一个指向前一个元素一个指向下一个元素。对于随机 index 访问的 get 和 set 方法一般 ArrayList 的速度要优于 LinkedList。因为 ArrayList 直接通过数组下标直接找到元素LinkedList 要移动指针遍历每个元素直到找到为止。新增和删除元素一般 LinkedList 的速度要优于 ArrayList。因为 ArrayList 在新增和删除元素时可能扩容和复制数组LinkedList 实例化对象需要时间外只需要修改节点指针即可。LinkedList 集合不支持高效的随机访问RandomAccessArrayList 的空间浪费主要体现在在list列表的结尾预留一定的容量空间LinkedList 的空间花费则体现在它的每一个元素都需要消耗存储指针节点对象的空间。 都是非线程安全允许存放 null Array和ArrayList有何区别 Array 即数组 定义一个 Array 时必须指定数组的数据类型及数组长度即数组中存放的元素个数固定并且类型相同。 ArrayList 是动态数组长度动态可变会自动扩容。不使用泛型的时候可以添加不同类型元素。 如何实现数组和List之间的转换 数组转 List 使用 JDK 中 java.util.Arrays 工具类的 asList 方法 List 转数组使用 List 的 toArray 方法。无参 toArray 方法返回 Object 数组传入初始化长度的数组对象返回该对象数组 哪些集合类是线程安全的 VectorStackHashtablejava.util.concurrent 包下所有的集合类 ArrayBlockingQueue、ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentLinkedDeque… Iterator怎么使用有什么特点 java.lang.Iterable 接口被 java.util.Collection 接口继承java.util.Collection 接口的 iterator() 方法返回一个 Iterator 对象next() 方法获得集合中的下一个元素hasNext() 检查集合中是否还有元素remove() 方法将迭代器新返回的元素删除forEachRemaining(Consumer? super E action) 方法遍历所有元素 多线程线程池 什么是线程 线程是操作系统能够进行运算调度的最小单位它被包含在进程之中是进程中的实际运作单位可以使用多线程对进行运算提速。 比如如果一个线程完成一个任务要100毫秒那么用十个线程完成改任务只需10毫秒 什么是线程安全和线程不安全 通俗的说加锁的就是是线程安全的不加锁的就是是线程不安全的 线程安全 线程安全: 就是多线程访问时采用了加锁机制当一个线程访问该类的某个数据时进行保护其他线程不能进行访问直到该线程读取完其他线程才可使用。不会出现数据不一致或者数据污染。 一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。很显然你可以将集合类分成两组线程安全和非线程安全的。Vector 是用同步方法来实现线程安全的, 而和它相似的ArrayList不是线程安全的。 线程不安全 线程不安全就是不提供数据访问保护有可能出现多个线程先后更改数据造成所得到的数据是脏数据 如果你的代码所在的进程中有多个线程在同时运行而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的而且其他的变量的值也和预期的是一样的就是线程安全的。 线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作而无写操作一般来说这个全局变量是线程安全的若有多个线程同时执行写操作一般都需要考虑线程同步否则的话就可能影响线程安全。 什么是多线程优缺点 什么是多线程 多线程是指从软件或者硬件上实现多个线程的并发技术。 多线程的好处 使用多线程可以把程序中占据时间长的任务放到后台去处理如图片、视屏的下载发挥多核处理器的优势并发执行让系统运行的更快、更流畅用户体验更好 多线程的缺点 大量的线程降低代码的可读性更多的线程需要更多的内存空间当多个线程对同一个资源出现争夺时候要注意线程安全的问题。 什么是多线程的上下文切换 即使是单核CPU也支持多线程执行代码CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间因为时间片非常短所以CPU通过不停地切换线程执行让我们感觉多个线程时同时执行的时间片一般是几十毫秒ms 上下文切换过程中CPU会停止处理当前运行的程序并保存当前程序运行的具体位置以便之后继续运行 CPU通过时间片分配算法来循环执行任务当前任务执行一个时间片后会切换到下一个任务。但是在切换前会保存上一个任务的状态以便下次切换回这个任务时可以再次加载这个任务的状态 从任务保存到再加载的过程就是一次上下文切换 如何创建、启动 Java 线程 一、重写 Thread 类的 run() 方法。 表现形式有两种1new Thread 对象匿名重写 run() 方法 2继承 Thread 对象重写 run() 方法 二、实现 Runnable 接口重写 run() 方法。 表现形式有两种1new Runnable 对象匿名重写 run() 方法 2实现 Runnable 接口重写 run() 方法 三、实现 Callable 接口使用 FutureTask 类创建线程 四、使用线程池创建、启动线程 package constxiong.concurrency.a006;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** 线程池的方式启动线程* author ConstXiong*/ public class TestCreateThreadByThreadPool {public static void main(String[] args) {// 使用工具类 Executors 创建单线程线程池ExecutorService singleThreadExecutor Executors.newSingleThreadExecutor();//提交执行任务singleThreadExecutor.submit(() - {System.out.println(单线程线程池执行任务);});//关闭线程池singleThreadExecutor.shutdown();} }什么是线程池 线程池就是创建若干个可执行的线程放入一个池容器中有任务需要处理时会提交到线程池中的任务队列处理完之后线程并不会被销毁而是仍然在线程池中等待下一个任务。 一个线程池包括以下四个基本组成部分 1、线程池管理器ThreadPool用于创建并管理线程池包括 创建线程池销毁线程池添加新任务 2、工作线程PoolWorker线程池中线程在没有任务时处于等待状态可以循环的执行任务 3、任务接口Task每个任务必须实现的接口以供工作线程调度任务的执行它主要规定了任务的入口任务执行完后的收尾工作任务的执行状态等 4、任务队列taskQueue用于存放没有处理的任务。提供一种缓冲机制。 常见线程池 ①newSingleThreadExecutor 单个线程的线程池即线程池中每次只有一个线程工作单线程串行执行任务 ②newFixedThreadExecutor(n) 固定数量的线程池没提交一个任务就是一个线程直到达到线程池的最大数量然后后面进入等待队列直到前面的任务完成才继续执行 ③newCacheThreadExecutor推荐使用 可缓存线程池当线程池大小超过了处理任务所需的线程那么就会回收部分空闲一般是60秒无执行的线程当有任务来时又智能的添加新线程来执行。 ④newScheduleThreadExecutor 大小无限制的线程池支持定时和周期性的执行线程 线程池常用参数 corePoolSize核心线程数量会一直存在除非allowCoreThreadTimeOut设置为true maximumPoolSize线程池允许的最大线程池数量 keepAliveTime线程数量超过corePoolSize空闲线程的最大超时时间 unit超时时间的单位 workQueue工作队列保存未执行的Runnable 任务 threadFactory创建线程的工厂类 handler当线程已满工作队列也满了的时候会被调用。被用来实现各种拒绝策略。 为什么要使用线程池 因为 Java 中创建一个线程需要调用操作系统内核的 API操作系统要为线程分配一系列的资源成本很高所以线程是一个重量级的对象应该避免频繁创建和销毁。 使用线程池就能很好地避免频繁创建和销毁。 如何在两个线程之间共享数据 1如果每个线程执行的代码相同可以使用同一个Runnable对象这个Runnable对象中有那个共享数据例如卖票系统就可以这么做。 2如果每个线程执行的代码不同这时候需要用不同的Runnable对象例如设计4个线程。其中两个线程每次对j增加1另外两个线程对j每次减1银行存取款 java基础 和equals的区别是什么? 是关系运算符equals() 是方法结果都返回布尔值Object 的 和 equals() 比较的都是地址作用相同 作用 基本类型比较值是否相等引用类型比较内存地址值是否相等不能比较没有父子关系的两个对象 equals()方法的作用 JDK 中的类一般已经重写了 equals()比较的是内容自定义类如果没有重写 equals()将调用父类默认 Object 类的 equals() 方法Object 的 equals() 比较使用了 this obj可以按照需求逻辑重写对象的 equals() 方法重写 equals 方法一般须重写 hashCode 方法 hashCode()相同equals()也一定为true吗 首先答案肯定是不一定。同时反过来 equals() 为truehashCode() 也不一定相同。 类的 hashCode() 方法和 equals() 方法都可以重写返回的值完全在于自己定义。hashCode() 返回该对象的哈希码值equals() 返回两个对象是否相等。 关于 hashCode() 和 equals() 是方法是有一些 常规协定 1、两个对象用 equals() 比较返回true那么两个对象的hashCode()方法必须返回相同的结果。 2、两个对象用 equals() 比较返回false不要求hashCode()方法也一定返回不同的值但是最好返回不同值以提高哈希表性能。 3、重写 equals() 方法必须重写 hashCode() 方法以保证 equals() 方法相等时两个对象 hashcode() 返回相同的值。 final finally finalize()区别 final 表示最终的、不可改变的。用于修饰类、方法和变量。final 修饰的类不能被继承final 方法也同样只能使用不能重写但能够重载final 修饰的成员变量必须在声明时给定初值或者在构造方法内设置初始值只能读取不可修改final 修饰的局部变量必须在声明时给定初值final 修饰的变量是非基本类型对象的引用地址不能变但对象的属性值可以改变finally 异常处理的一部分它只能用在 try/catch 语句中表示希望 finally 语句块中的代码最后一定被执行存在一些情况导致 finally 语句块不会被执行如 jvm 结束finalize() 是在 java.lang.Object 里定义的Object 的 finalize() 方法什么都不做对象被回收时 finalize() 方法会被调用。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要清理工作在垃圾收集器删除对象之前被调用的。一般情况下此方法由JVM调用。特殊情况下可重写 finalize() 方法当对象被回收的时候释放一些资源须调用 super.finalize() 。 如何将字符串反转 使用 StringBuilder 或 StringBuffer 的 reverse 方法本质都调用了它们的父类 AbstractStringBuilder 的 reverse 方法实现。JDK1.8不考虑字符串中的字符是否是 Unicode 编码自己实现。递归 String类的常用方法有哪些 String 类的常用方法 equals字符串是否相同equalsIgnoreCase忽略大小写后字符串是否相同compareTo根据字符串中每个字符的Unicode编码进行比较compareToIgnoreCase根据字符串中每个字符的Unicode编码进行忽略大小写比较indexOf目标字符或字符串在源字符串中位置下标lastIndexOf目标字符或字符串在源字符串中最后一次出现的位置下标valueOf其他类型转字符串charAt获取指定下标位置的字符codePointAt指定下标的字符的Unicode编码concat追加字符串到当前字符串isEmpty字符串长度是否为0contains是否包含目标字符串startsWith是否以目标字符串开头endsWith是否以目标字符串结束format格式化字符串getBytes获取字符串的字节数组getChars获取字符串的指定长度字符数组toCharArray获取字符串的字符数组join以某字符串连接某字符串数组length字符串字符数matches字符串是否匹配正则表达式replace字符串替换replaceAll带正则字符串替换replaceFirst替换第一个出现的目标字符串split以某正则表达式分割字符串substring截取字符串toLowerCase字符串转小写toUpperCase字符串转大写trim去字符串首尾空格 普通类和抽象类有哪些区别 抽象类不能被实例化抽象类可以有抽象方法抽象方法只需申明无需实现含有抽象方法的类必须申明为抽象类抽象类的子类必须实现抽象类中所有抽象方法否则这个子类也是抽象类抽象方法不能被声明为静态抽象方法不能用 private 修饰抽象方法不能用 final 修饰 **重写**在子类中将父类的成员方法的名称保留重新编写成员方法的实现内容更改方法的访问权限修改返回类型的为父类返回类型的子类。 一些规则 重写发生在子类继承父类 参数列表必须完全与被重写方法的相同 重写父类方法时修改方法的权限只能从小范围到大范围 返回类型与被重写方法的返回类型可以不相同但是必须是父类返回值的子类(JDK1.5 及更早版本返回类型要一样JDK1.7 及更高版本可以不同) 访问权限不能比父类中被重写的方法的访问权限更低。如父类的方法被声明为 public那么子类中重写该方法不能声明为 protected 重写方法不能抛出新的检查异常和比被重写方法申明更宽泛的异常(即只能抛出父类方法抛出异常的子类) 声明为 final 的方法不能被重写 声明为 static 的方法不能被重写 声明为 private 的方法不能被重写 **重载**一个类中允许同时存在一个以上的同名方法这些方法的参数个数或者类型不同 重载条件 方法名相同参数类型不同 或 参数个数不同 或 参数顺序不同 规则 被重载的方法参数列表(个数或类型)不一样 被重载的方法可以修改返回类型 被重载的方法可以修改访问修饰符 被重载的方法可以修改异常抛出 方法能够在同一个类中或者在一个子类中被重载 无法以返回值类型作为重载函数的区分标准 方法重载和重写是什么有什么区别 作用范围重写的作用范围是父类和子类之间重载是发生在一个类里面参数列表重载必须不同重写不能修改返回类型重载可修改重写方法返回相同类型或子类抛出异常重载可修改重写可减少或删除一定不能抛出新的或者更广的异常访问权限重载可修改重写一定不能做更严格的限制 内存泄漏和内存溢出的区别 内存溢出(out of memory)指程序在申请内存时没有足够的内存空间供其使用出现 out of memory。内存泄露(memory leak)指程序在申请内存后无法释放已申请的内存空间内存泄露堆积会导致内存被占光。memory leak 最终会导致 out of memory。 什么是多态如何实现有什么好处 多态 同一个接口使用不同的实例而执行不同操作。同一个行为具有多个不同表现形式或形态的能力。 实现多态有三个条件 继承子类重写父类的方法父类引用变量指向子类对象 用Lambda表达式实现Runnable Test public void test1(){//使用Java8之前new Thread(new Runnable() {Overridepublic void run() {System.out.println(使用Lambda表达式之前需要这么写);}}).start();//使用Lambda表达式new Thread(() - System.out.println(使用Lambda表达式只需要这一句话)).start();String s“a”“b”“c”“d”;创建了几个对象 1个 Java 编译器对字符串常量直接相加的表达式进行优化不等到运行期去进行加法运算在编译时就去掉了加号直接将其编译成一个这些常量相连的结果。 所以 “a”“b”“c”“d” 相当于直接定义一个 “abcd” 的字符串。 String s new String(“xyz”);创建几个String对象 两个或一个 第一次调用 new String(“xyz”); 时会在堆内存中创建一个字符串对象同时在字符串常量池中创建一个对象 “xyz”第二次调用 new String(“xyz”); 时只会在堆内存中创建一个字符串对象指向之前在字符串常量池中创建的 “xyz” 序列化 **序列化**把对象转化为可传输的字节序列过程称为序列化。 **反序列化**把字节序列还原为对象的过程称为反序列化。 为什么要序列化 如果光看定义我想你很难一下子理解序列化的意义那么我们可以从另一个角度来推导出什么是序列化, 那么究竟序列化的目的是什么 其实序列化最终的目的是为了对象可以跨平台存储和进行网络传输。而我们进行跨平台存储和网络传输的方式就是IO而我们的IO支持的数据格式就是字节数组。 因为我们单方面的只把对象转成字节数组还不行因为没有规则的字节数组我们是没办法把对象的本来面目还原回来的所以我们必须在把对象转成字节数组的时候就制定一种规则**序列化那么我们从IO流里面读出数据的时候再以这种规则把对象还原回来反序列化。** 如果我们要把一栋房子从一个地方运输到另一个地方去序列化就是我把房子拆成一个个的砖块放到车子里然后留下一张房子原来结构的图纸反序列化就是我们把房子运输到了目的地以后根据图纸把一块块砖头还原成房子原来面目的过程 什么情况下需要序列化 通过上面我想你已经知道了凡是需要进行“跨平台存储”和”网络传输”的数据都需要进行序列化。 本质上存储和网络传输 都需要经过 把一个对象状态保存成一种跨平台识别的字节格式然后其他的平台才可以通过字节信息解析还原对象信息。 序列化的方式 序列化只是一种拆装组装对象的规则那么这种规则肯定也可能有多种多样比如现在常见的序列化方式有 JDK不支持跨语言、JSON、XML、Hessian、Kryo不支持跨语言、Thrift、Protostuff、FST不支持跨语言 序列化技术选型的几个关键点 序列化协议各有千秋不能简单的说一种序列化协议是最好的只能从你的当时环境下去选择最适合你们的序列化协议如果你要为你的公司项目进行序列化技术的选型那么主要从以下几个因素。 协议是否支持跨平台 如果你们公司有好多种语言进行混合开发那么就肯定不适合用有语言局限性的序列化协议要不然你JDK序列化出来的格式其他语言并没法支持。 序列化的速度 如果序列化的频率非常高那么选择序列化速度快的协议会为你的系统性能提升不少。 序列化出来的大小 如果频繁的在网络中传输的数据那就需要数据越小越好小的数据传输快也不占带宽也能整体提升系统的性能。 Java 是如何实现序列化的 前面主要介绍了一下什么是序列化那么下面主要讲下JAVA是如何进行序列化的以及序列化的过程中需要注意的一些问题 java 实现序列化很简单只需要实现Serializable 接口即可。 JAVA序列化中常见的问题 问题一static 属性不能被序列化 原因序列化保存的是对象的状态静态变量属于类的状态因此 序列化并不保存静态变量。 问题二Transient 属性不会被序列化
http://www.zqtcl.cn/news/538801/

相关文章:

  • 标书制作教程视频网站福田祥菱v1单排
  • 点网站出图片怎么做能看人与动物做的网站
  • 免费开源建站系统源码wordpress公共函数在哪里
  • 西昌市建设工程管理局网站模块化网站开发
  • 无限看片的视频大全免费下载上海网络优化方法
  • 物流公司做网站注重什么问题中国建设银行征信中心网站
  • 教务处网站建设专业做鞋子的网站吗
  • 梦幻创意网站建设成都做网站设计哪家便宜
  • 织梦网站栏目修改教程丝绸之路网站建设意义
  • 如何知道一个网站是谁做的北京装饰公司前十名
  • 杭州网站建设哪个平台好visualstudio 做网站
  • 广州站是哪个站h5建站系统
  • 网站首页网址应该有对应的域名南京高端模板建站
  • 自己做的网站竞价优化怎么做网站流量赚钱吗
  • 人力资源网站建设mip网站模板
  • 太原市住房和城乡建设部网站网站 备案 换空间
  • 怎么做网站备份网站运营数据周报表怎么做
  • 度更新网站做详情页网站
  • 酷炫网站模板wordpress自动发货插件
  • 网站做多个镜像wordpress无法显示向导
  • 交易类网站建设费用工厂招工最新招聘信息
  • 俄语网站建设网站建设的实训报告
  • 朝阳市做网站的公司wordpress msg
  • 企业管理系统免费版seo关于网站
  • 几度设计网站设计制作平板电脑支架
  • 游戏设计 网站上海中企动力做网站多少钱
  • flash 开发的网站网上国网app推广经验
  • pyhton可以做网站吗文章wordpress
  • 省住房城乡建设厅门户网站电子商务网站建设用什么软件
  • 怎么给自己的网站做模版企业网站开发外包