1、JAVA的跨平台原理
java通过不同系统,位数,版本的虚拟机来屏蔽不同的指令集差异,对外提供统一的接口(java api)
2、JAVA特性
封装:属性私有化,对外提供方法(set/get)
继承:在一个现有类基础上,修改或新增新的内容
多态:引用变量指向的具体类型和方法在运行时才确定
3、String、StringBuffer、StringBuiler区别
String是内容不可变的字符串,StringBuffer、StringBuiler是内容可变的字符串
StringBuffer是线程安全的、StringBuiler是非线程安全的
4、集合
(1)集合分两种,值集合和键值集合
值集合主要是List和Set,都继承了Collection接口
键值集合主要是Map
(2)List:有序,可重复
分为ArrayLIst、LinkedList和Vector
ArrayList底层是数组实现,为连续的内存空间,所以查找速度快,增删速度慢
LinkedList底层是链表实现,不连续的内存空间,所以增删速度快,查找速度慢
Vector底层是数组,线程安全
(3)Set:无序,不可重复
重写equals和hashcode方法,因为在add,会先用equals判断值是否相等,再判断是否具有相同的hash值(属性相同的对象被看作同一个对象)
(4)Map:键值对
hashMap:可以存储空值,非线程安全。
put存储键值对的时候,会调用hashcode方法返回一个hashcode值,找到bucket位置存储Entry对象,使用get(key)获取对象
解决hashmap非线程安全问题:
因为hashmap内部类似链表结构,在多线程环境下有可能成环,解决方法ConcurrentHashMap(把一个Map分成N个segment,分别加锁,保证线程安全)。
hashtable:线程安全
5、拷贝文件
思路:源文件、源地址、目标文件、目标地址
缓存输入输出流(FileInputStream、FileOutputStream)
改进:FileChannels(transferTo),适合拷贝大文件
6、线程池
为了避免重复的创建和销毁线程,让创建的线程进行复用,存放空闲线程的一个池子
Executors.NewFixedThreadPool()创建一个固定大小的线程池
7、存储过程的好处
(1)预编译,只在创建时进行编译,提高数据库执行速度
(2)比较复杂的业务需要多条sql,提高网络传输速度
(3)安全性
8、ajax参数
url:请求地址
type:get/post
data:请求数据
dataType:服务器返回数据类型(json、text、xml、html)
success:成功调用函数
erroe:失败调用函数
9、Struts2执行流程
(1)服务端接收客户端请求,经过一系列的过滤器,到达核心过滤器(StrutsPrepareAndExecuteFilter)
(2)StrutsPrepareAndExecuteFilter通过ActionMapper将请求交给ActionProxy代理
(3)ActionProxy通过Configeration Manager找到配置文件,找到需要调用的Action
(4)创建一个ActionInvocation实例,调用Action方法,调用前后还会执行相关的拦截器
(5)通过结果集的name返回对应的结果集,对浏览器进行响应
10、Struts2拦截器
通过动态配置,在action前后加入一些相关的逻辑
包括:
登录判断,未登录跳转到登录页面
用户权限判断,没有权限给出判断信息
操作日志
11、SpringMvc工作流程
(1)用户向服务器发起请求,请求交给前端控制器DispatcherServlet处理
(2)DispatcherServlet对请求的URL进行解析,得到URI,调用HandlerMapping获得Handler配置的所有相关对象
(3)DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter,执行Handler
(4)Handler执行完成后,返回一个ModelAndView对象
(5)DispatcherServlet根据返回的ModelAndView,选择一个合适的视图解析器,返回客户端
12、Struts1工作流程
(1)服务段接收到客户端请求,交给ActionServlet处理
(2)拦截所有.do请求,将客户请求封装到actionForm里面,到配置文件去匹配对应的action(主要有几个属性,name对应封装的actionform,input匹配拦截的路径和方法,type匹配action的实现类)
(3)action处理完返回actionforward对象,根据配置文件找到对应页面返回给客户端
13、SpringMvc和Struts2区别
(1)核心控制器不同,SpringMvc是Servlet,Struts2是filter
(2)控制器实例不同,SpringMvc是基于方法级别,只会有一个实例,线程不安全,Struts2基于对象,针对不同的请求,产生不同的ActionInvaction实例
(3)参数传递:Struts2是通过值栈传递,SpringMvc是通过方法的参数传递
(4)intercepter拦截器:Struts2有自己的拦截器,SpringMvc用aop实现
(5)SpringMvc处理ajax请求直接返回数据@ResponseBody
14、Struts1和Struts2的区别
(1)因为forward都是返回到具体的jsp页面,每一个forward对应配置文件的一个forward标签,每一次改动配置文件都要重启Tomcat
(2)struts1里的action是单例模式的,供多个请求共享,所以不是线程安全的。
(3)Struts1中ActionForm的唯一缺点是对于大型的Struts应用,必需以编程的方式创建大量的ActionForm类,如果HTML表单字段发生变化,就必须修改并编译相关的ActionForm类
15、Spring的IOC和AOP
在运行时,动态的向某个对象提供它所需要的其他对象,通过依赖注入实现,通过容器来控制业务对象之间的依赖关系,这就是IOC
把一些业务无关的功能抽离出来,动态插入到各业务逻辑里面,这就是AOP。应用场景:日志、事务、组件管理
15、事务的传播特性
一般都是用REQUIRED,如果存在一个事务,则支持当前事务。如果没有事务则开启。
REQUIREDS_NEW:总是开启一个新事务,如果事务已经存在,则挂起。
16、Mybatis和Hibernate区别
(1)Hibernate有HQL,可以自动生成SQL语句,可以通过SQLQuery接口实现原生SQL(不建议,破坏跨数据库特性)
(2)Mybatis可以在配置文件编写SQL语句,提供了将结果集自动封装成实体对象的功能(queryForList 返回对象集合、queryForObject 返回单个对象)
17、Hibernate对象状态
(1)瞬时状态:new
(2)持久化状态:已经被持久化,在session中
(3)游离态:已经被持久化,不在session中
(4)删除状态:commit删除
18、批量处理百万级数据
(1)、关闭事务自动提交
connection.setAutoCommit(false);
(2)、变多次提交一次(多条insert语句变成一条)
1 //记录1 2 statement.setInt(1, 1); 3 statement.setString(2, "Cujo"); 4 statement.addBatch(); 5 6 //记录2 7 statement.setInt(1, 2); 8 statement.setString(2, "Fred"); 9 statement.addBatch(); 10 11 //记录3 12 statement.setInt(1, 3); 13 statement.setString(2, "Mark"); 14 statement.addBatch(); 15 16 //批量执行上面3条语句. 一口吞了,很爽 17 int [] counts = statement.executeBatch();
(4)、最后再提交
19、spring的启动机制
(1)在Tomcat下根据web.xml来启动
(2)web.xml中负责启动spring和spring mvc
2.1、启动springmvc并将所有资源文件映射
1 <servlet> 2 <servlet-name>springMVC</servlet-name> 3 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 4 <init-param> 5 <param-name>contextConfigLocation</param-name> 6 <param-value>/WEB-INF/cfg/springmvc-servlet.xml</param-value> 7 </init-param> 8 <load-on-startup>1</load-on-startup> 9 </servlet> 10 <servlet-mapping> 11 <servlet-name>springMVC</servlet-name> 12 <url-pattern>/</url-pattern> 13 </servlet-mapping>
2.2、启动spring,通过ContextLoaderListener
1 <listener> 2 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 3 </listener> 4 <context-param> 5 <param-name>contextConfigLocation</param-name> 6 <param-value>/WEB-INF/cfg/spring.xml</param-value> 7 </context-param>
2.3、orm框架的启动基本都是通过sqlsessionFactory bean来启动的。并配置各种bean到ioc容器中。
<context:component-scan base-package=”com.eric.spring”> @Service用于标注业务层组件 @Controller用于标注控制层组件(Action) @Repository用于标注数据访问组件(DAO组件) @autowired 自动装配 @Qualifier 当自动装配对应多个,使用byName,唯一标识
重点(有待完善)
一、反射
概念:反射是一种间接操作目标对象的机制,可以在程序程序运行时获取或者设置对象信息。
通过反射来动态创建对象,实现框架组件的可插拔策略
举例:JDBC连接数据库
Class.forName("oracle.jdbc.driver.OracleDriver");//找到oracle驱动器所在的类
反射步骤:
1 //获取对象或者类的Class实例 2 Class<?> clazz1 clazz1 = Class.forName(sshClient.getClass().getName()); 3 //通过构造函数构造对象 4 SSHClient client = (SSHClient) clazz1.newInstance(); 5 //获取类定义的方法、属性 6 Method setHostMethod = clazz1.getDeclaredMethod("setHost", String.class); 7 setHostMethod.invoke(client, "111");
二、数据库优化:
1.定位查找慢查询并优化
2.建立索引 创建合适的索引。我们就可以在索引中查询到记录。
3.分表 当一张表数据比较多或者某些字段值比较多,并且很少使用采用水平或者垂直分表进行优化
4.读写分离 当一台服务器不能满足,采用读写分离的形式进行分离
5.缓存redis 使用redis来进行缓存
详细解释:
(1)如何定位慢查询?
在项目自验或启动时。在启动Mysql时开启慢查询,并且把执行慢的数据记录到日志。通过查看日志找到对应的慢查询语句
//MySQL默认配置中多少秒才算慢查询(默认10秒) show variables like 'long%'; //修改慢查询时间 set long_query_time=1; //是否打开日志记录 slow_query_log //日志存放位置 slow_query_log_file //开启慢查询 mysql> set global slow_query_log='ON';
(2)索引优化小技巧
复合索引:不使用第一部分就不会使用索引
对于like:如果是'%aaa'不会使用,推荐'aa%'
对于or:全部都要使用索引
列类型是字符串:都必须用单引号
避免使用null值判断
(3)数据库分表[对于热数据,使用水平分表,对于冷数据,使用垂直分表]
水平分表:按时间、ID
INSERT INTO user1(user1.id,user1.name,user1.sex) SELECT (user.id,user.name,user.sex)FROM old_user where user.id <= 5000000
垂直分表:
1、针对一些变化频率慢,查询多的数据(冷数据),使用MyIsam存储引擎[非事务安全,速度快]
2、变化频率比较高的数据(活跃数据),使用Innodb[事务安全]
3、对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库
(4)数据库的读写分离
一般数据库都是读多写少,分成多个库,主库用来写数据,从库用来读数据,主要是实现读写数据一致。
方案1(应用层实现):
放在dao层,将所有的insert/update/delete都访问主库,所有的select 都访问从库
方案2(中间件 mysql-proxy、maxScale)
(5)缓存
Hibernate二级缓存、redis
三、Redis
1、是什么:redis就是一个key-value的非关系型数据库,先存到内存中,根据一定策略持久化到硬盘,断电不丢失数据。
2、做什么:存放一些经常访问,很少修改的数据,提高访问速度。
应用场景:做缓存数据库、web集群做中央缓存存放session
3、redis对象保存方式:
(1)JSON:把对象转换成json,直接使用set/get获取(jsonlib)
(2)字节:把对象序列化为字节保存
4、redis的数据淘汰机制
内存大小有限,保存有限的数据
1、从已经过期的数据中选择最少使用的数据淘汰
2、选择最近使用最少的数据进行淘汰
5、java访问redis方式
(1)使用redis java客户端
(2)spring data
5、二叉树:
先序遍历:遍历顺序规则为【根左右】
中序遍历:遍历顺序规则为【左根右】
后序遍历:遍历顺序规则为【左右根】
6、bean和javabean区别:
bean(POJO):普通JAVA类,一些属性和set/get方法
当一个POJO可序列化,有一个无参的构造函数,使用getter和setter方法来访问属性时,他就是一个JavaBean
7、抽象类应用场景
接口不能实例化变量,抽象类(状态)
8、多态
前提:
1. 要有继承
2. 要有重写
3. 父类引用指向子类对象
子类在继承的时候,可以通过重写(override)父类的某个方法,从而使得不同的子类,在使用和父类同名方法时,有不同效果