1、jvm:java虚拟机,负责把.class 二进制文件翻译成不同系统上的机器操 作指令。因此JVM实现了java的跨平台运行。
jvm负责把class文件加载进内存, 它包含类加载器子系统,
运行时数据区:方法区(静态区)、堆(new的对象)、栈(局部变量和方法的中间结果)、程序计数器、本地方法,垃圾回收系统、执行引擎。
2、jre:java运行环境,它包含了jvm和java项目运行所需要的java 类库,
java.util java.sql java.long java.net 等。如果不编译只运行,那么有jre就可以了,java 命令负责拉起 JVM。
3、jdk:包含jre和编译等开发java项目所需要的一些工具,这些工具都在jdk安装目录下的 bin目录下,
包括 javac.exe java.exe jar.exe jvisiovm.exe、jconsole 等负责 编译、运行 和项目调试等。
java.lang 包装类,线程等都在该包
java.match 有BigDecimal 精确数字类型
java.util 并发,集合等都在该包内
简单类型 boolean byte char short int(长度 -231-231-1) long float double void
二进制位数 1 8 16 16 32 64 32 64 –
封装器类 Boolean Byte Character Short Integer Long Float Double Void
1、Integer是int的包装类,int则是java的一种基本数据类型
2、Integer变量必须实例化后才能使用,而int变量不需要
3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
4、Integer的默认值是null,int的默认值是0
值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。
数组没有length()方法,有length属性。String有length()方法。
在JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆。
// 字符串转数字
String s = "123.456 "; //要确保字符串为一个数值,否则会出异常
double d = Double.parseDouble(s);
float f = Float.parseFloat(s);
int i = Integer.parseInt(s);
数字转字符串
int i = 7;
String str = String.valueOf(i); // 第一种
Integer it = i;
String str2 = it.toString();// 第二种
因为byte,short,char以及他们的包装类都可以,因为他们可以隐式转换成int
但是long类型不符合语法规定,
String也可以,但是要求case中也为String类型
1.利用 StringBuffer 或 StringBuilder 的 reverse 成员 方法
2.利用 String 的 toCharArray 方法先将字符串转化为 char 类型数组,然后将各个字符进行重新拼接、
3.利用 String 的 CharAt 方法取出字符串中的各个字符
StringBuffer:线程安全,StringBuilder:线程不安全。
因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 并没有修饰。
StringBuilder性能大于StringBuffer
String字符串长度声明后不可改变
StringBuffer可以改变
equals比较的是两个字符串内容是否相等
==比较的是两个字符串的内存地址是否相同
1.字段不可再分
2.表中必须要有主键
3.表中的非主键列之间不能有相互依赖
对数据库一系列的连续的操作,这些操作必须要看做是一个整体,要么都成功,要么都失败
原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
隔离性:多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离
一致性:如果事务执行之前数据库是一个完整的状态,那么事务结束后,无论事务是否执行成功,数据库仍然是一个完整的状态
持久性:指一个事务一旦被提交,他对数据库的影响是永久性的
方法的重载 Overload
重载指的是同一个类中有多个同名方法,但是参数的类型和数量不同
方法的重写 Override
重写指的是子类重写父类的方法,同样的方法在子类和父类中有着不同的表现方式
当第一次访问jsp页面时,会向一个servlet容器(tomcat等)发出请求,
servlet容器先要把 jsp页面转化为servlet代码(.java),再编译成.class 文件 再进行调用。
当再次访问jsp页面时 跳过翻译和编译的过程 直接调用
父类静态属性
父类静态块
子类静态属性
子类静态块
父类非静态属性
父类非静态块
父类构造方法
子类非静态属性
子类非静态块
子类构造方法
异同点如下:
相同点:都是JVM加载类时且在构造函数执行之前执行,在类中都可以定义多个,一般在代码块中对一些static变量进行赋值。
不同点:静态代码块在非静态代码块之前执行(静态代码块 > 非静态代码块)。静态代码块只在第一次new时执行一次,之后不再执行。
而非静态代码块每new一次就执行一次。
序列化 是将对象状态转换为字节流的过程,可以将其保存到磁盘文件中
反序列化 是将字节流还原为对象的过程
实现java.io.Serializable接口,可以在Java类中启用可序列化
1.被创建:执行init方法,只执行一次
Servlet什么时候被创建?
--默认情况下,第一次被访问时,Servlet被创建,然后执行init方法;
--可以配置执行Servlet的创建时机;
2.提供服务:执行service方法,执行多次
3.被销毁:当Servlet服务器正常关闭时,执行destroy方法,只执行一次
· request:封装客户端的请求,其中包含来自 get 或 post 请求的参数;
· response:封装服务器对客户端的响应;
· pageContext:通过该对象可以获取其他对象;
· session:封装用户会话的对象;
· application:封装服务器运行环境的对象;
· out:输出服务器响应的输出流对象;
· config:Web 应用的配置对象;
· page:JSP 页面本身(相当于 Java 程序中的 this);
· exception:封装页面抛出异常的对象。
page(pageContext):只在一个页面中保存属性。 跳转之后无效。
request:只在一次请求中有效,服务器跳转之后有效。 客户端跳无效
session:在一次会话中有效。服务器跳转、客户端跳转都有效。 网页关闭重新打开无效
application:在整个服务器上保存,所有用户都可使用。 重启服务器后无效
注意:如果设置过多的application属性范围会影响服务器性能。
jsp是在前台写java代码,servlet是在后台写前端代码
存储位置不同:session 存储在服务器端;cookie 存储在浏览器端。
安全性不同:cookie 安全性一般,在浏览器存储,可以被伪造和修改。
容量和个数限制:cookie 有容量限制,每个站点下的 cookie 也有个数限制,session是保存一段时间才会消失,但是过多的session会给服务器造成压力
存储的多样性:session 可以存储在 Redis 中、数据库中、应用程序中;而 cookie 只能存储在浏览器中。
一般默认情况下,在会话中,服务器存储 session 的 sessionid 是通过 cookie 存到浏览器里。
如果浏览器禁用了 cookie,浏览器请求服务器无法携带 sessionid,服务器无法识别请求中的用户身份,session失效。
但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session。
通过url重写,把 sessionid 作为参数追加的原 url 中,后续的浏览器与服务器交互中携带 sessionid 参数。
服务器的返回数据中包含 sessionid,浏览器发送请求时,携带 sessionid 参数。
通过 Http 协议其他 header 字段,服务器每次返回时设置该 header 字段信息,浏览器中 js 读取该 header 字段,请求服务器时,js设置携带该 header 字段。
EL表示用法(Expression Language)
1)访问bean属性
第一种方式:
语法 ${user.username}
执行过程: 从某些指定范围内查找绑定名为"user"的对象,如果找到了,则调用“getUsername”方法然后输出。
第二种方式:
语法 ${user['username']}
说明: 有两种特殊用法,允许[]里面出现绑定名,允许里面出现从0开始的下标,如访问某个元素。
2)做一些运算(算术、关系运算、逻辑运算)
注:运算结果可以给jsp标签的属性赋值,也可以直接输出。
JSTL(JSP标准标签库)
Step1:导入jstl.jar
Step2: 用taglib指令导入要使用的jsp标签
<% taglib uri="jsp标签的命名空间" prefix="指定命名空间的别名,前缀"%>
核心标签:
if标签:类似于java中if语句
标签体
当test属性为true,执行标签体内容,test属性也可以用el表达式赋值。
choose标签:类似于java中switch…case语句
...
forEach标签
hashCode(); 返回该对象的哈希码值,哈希码是根据内存地址生成的
equals(); 比较
clone(); 克隆
wait(); 使当前线程等待,直到其他线程调用此对象的notify()或者notifyAll()方法
notify(); 唤醒此对象监视器上等待的单个线程
notifyAll(); 唤醒在此对象监视器上等待的所有线程
toString(); 将对象转换成字符串的表现形式,类型@哈希码
getClass(); 返回一个对象的运行时类
indexOf() 返回指定字符得索引
charAt() 返回指定索引处得字符
repalce() 字符串替换
trim() 去除字符串两端的空白
split() 分割字符串 返回分割后的字符串数组
getBytes() 返回字符串的byte类型数组
length() 返回字符串的长度
toLowerCase() 字符串转小写
toUpperCase() 字符串转大写
substring() 截取字符串
equals() 字符串比较
是一种比抽象类更抽象的数据类型
接口也不能创建对象,必须通过实现(implements)类,创建对象
接口中只能包含抽象方法和静态常量
接口中的方法,默认就是 public abstract
接口中的变量,默认就是 public static final
注意:在JDK9中,允许在接口中定义静态方法,可以有方法体
不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类
抽象方法必须使用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。
因为抽象类中无具体实现的方法,所以不能用抽象类创建对象。
子类只能继承一个抽象类,但可以实现任意多个接口
抽象类中的成员变量可以是各种类型,接口中的成员变量只能是静态常量
抽象类中可以有静态方法和静态代码块和构造方法,而接口中没有
· 普通类不能包含抽象方法,抽象类可以包含抽象方法。
· 抽象类不能直接实例化,普通类可以直接实例化。
· 实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。
· 构造函数:抽象类可以有构造函数;接口不能有。
· 实现数量:类可以实现很多个接口;但是只能继承一个抽象类。
· 访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。
Java中的流分为两种,字节流,字符流,每种流都有输入和输出
InputStream,OutputStream,Reader,Writer
1.字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串;
2.节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
BIO是一个连接一个线程。
NIO是一个请求一个线程。
AIO是一个有效请求一个线程。
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。
NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。
AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。
Files.exists() 检测文件路径是否存在
Files.createFile()创建文件
Files.createDirectory()创建文件夹
Files.delete() 删除文件或者目录
Files.copy() 复制文件
Files.move() 移动文件
Files.size()查看文件个数
Files.read() 读取文件
Files.write()写入文件
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法。
catch和finally可以省略其中一个,但是不能都省略
会的,不管有没有异常,fianlly都会执行,在return之前执行。
throw:是真实抛出一个异常。
throws:是声明可能会抛出一个异常
· NullPointerException 空指针异常
· ClassNotFoundException 指定类不存在
· NumberFormatException 字符串转换为数字异常
· IndexOutOfBoundsException 数组下标越界异常
· ClassCastException 数据类型转换异常
· FileNotFoundException 文件未找到异常
· NoSuchMethodException 方法不存在异常
· IOException IO 异常
· SocketException Socket 异常
String就是Ioc和AOP结合的容器框架。
Ioc是控制反转,是指创建对象的控制权的反转,就是一个生产和管理bean的容器,简单来说就是不需要NEW一个对象了。
原来需要在调用类中new的东西,现在都是通过容器生成,同时,要是产生的是单例的bean,他还可以给管理bean的生命周期
aop只是一种切面编程思想在spring中主要用于事务控制
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术
在spring的bean结构中如< bean id=“PersonDaoBean” class="…P ersonDao"/>,
在一个Service类中可以这样写 private PersonDao personDao = new PersonDaoBean();
你看这样PersonDao对象就不用自己创建和维护了,交给了bean。也就是控制反转。
AOP设置拦截用户的业务方法,判断权限,有权限则可以执行调用的业务方法,没有权限则不可以。
在拦截的时候出现环绕通知 ,前置通知,后置通知,例外通知,最终通知。
ioc就spring的容器里面放的就是一些bean对象
spring容器中的bean可以分为5个范围:
(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。
(2)prototype:为每一个bean请求提供一个实例。
(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
(4)session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
(5)global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。
客户端发送请求到DispatcherServlet(前端控制器)
DispatcherServlet根据请求地址查询HandleMapping(处理器映射器),获取Handler
处理器映射器返回Handler给前端控制器
前端控制器请求HandlerAdatper(处理器适配器)执行Handler
HandlerAdatper执行相应的Controller方法,执行完毕返回ModelAndView给DispatcherServlet
通过ViewResolver(视图解析器)解析视图,返回View
DispatcherServlet根据View进行渲染视图
将渲染好的视图返回给客户端
Spring
Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。
Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new
一个对象,而是让Spring框架帮你来完成这一切。
SpringMVC
SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,
将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
mybatis
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。
mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。
在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。
map的优点:
1、灵活性强于javabean,易扩展,耦合度低。
2、写起来简单,代码量少。
3、mybatis 查询的返回结果本身就是MAP,可能会比返回javabean快
Javabean的优点:
1、面向对象的良好诠释、
2、数据结构清晰,便于团队开发 & 后期维护。
3、代码足够健壮,可以排除掉编译期错误。
map的缺点:
1、javabean在数据输入编译期就会对一些数据类型进行校验,如果出错会直接提示。而map的数据类型则需要到sql层,才会进行处理判断。
2、map的参数名称如果写错,也是需要到sql层,才能判断出是不是字段写错,不利于调试等。相对而言javabean会在编译期间发现错误
3、map的参数值如果多传、乱传,也是需要到sql层,才能判断出是不是字段写错,不利于调试等。相对而言javabean会在编译期间发现错误
4、仅仅看方法签名,你不清楚Map中所拥有的参数个数、类型、每个参数代表的含义。 后期人员去维护,例如需要加一个参数等,如果项目
层次较多,就需要把每一层的代码都了解清楚才能知道传递了哪些参数。
javabean的缺点:
1、代码量增多,大量时间去封装用到的表对象。
2、可能会影响开发效率。
#{}是预编译处理,${}是字符替换。
在使用 #{}时,MyBatis 会将 SQL 中的 #{}替换成“?”,配合 PreparedStatement 的 set 方法赋值,
这样可以有效的防止 SQL 注入,保证程序的运行安全。
实例化对象模式,是用工厂方法代替new操作的一种模式
一个类只能有一个实例,避免频繁创建对象,节约内存。
饿汉式:在类加载时就完成了初始化,所以类加载比较慢,但获取对象的速度快。
懒汉式:在类加载时不初始化,等到第一次被使用时才初始化。
简单理解它是将后台返回的数据传递给View层,同时包含一个要访问的View层的URL地址
当控制器处理完请求后,通常控制器会将包含视图名称以及一些模型属性的ModelAndView对象返回给DispatcherServlet。
因此,在控制器中会构造一个ModelAndView对象, ModelAndView默认转发。
ModelAndView作用
设置转向地址
将底层获取的数据进行存储(或者封装)
最后将数据传递给View
创建 SqlSessionFactory 对象。
通过 SqlSessionFactory 获取 SqlSession 对象。
通过 SqlSession 获得 Mapper 代理对象。
通过 Mapper 代理对象,执行数据库操作。
执行成功,则使用 SqlSession 提交事务。
执行失败,则使用 SqlSession 回滚事务。
最终,关闭会话。
用@param注解
Q:什么是数据库的内连接、外连接?
A:其实这两个是最好区分的 我们在高中高一的时候学的数学的第一堂课学的是并集与交集 这里用他们来理解是最好的
内连接你可以看做是取两个表的交集 其中只有两条互相对应着的数据才能被存入结果表中
而外连接就是取并集 和内连接是相反的 如果一张表的数据在另一张表中没有找到 但是并不影响他在结果集出现
Q:什么是左连接、右连接?
A:左连接(left join)就是当你要对两张表进行联合查询的时候
是将left join语句左侧的表当做基准表去匹配left join右表的表
如果左侧表其中的数据在右表里面可以找到与之对应的一条数据那么就会出现在结果表中如果没有那么就会以null来代替
一般在使用这种查询的时候都会辅佐以对应的where条件去筛选出自己需要的数据 右连接(right join)和左连接是相反的
1.char的长度是固定的,varchar的长度是可变的
2.char的存取速度比varchar的快
3.char和varchar的存储方式不同
异步请求就当发出请求的同时,浏览器可以继续做任何事,Ajax发送请求并不会影响页面的加载与用户的操作
同步请求即是当前发出请求后,浏览器什么都不能做,必须得等到请求完成返回数据之后,才会执行后续的代码,相当于是排队,
sync默认是true:即为异步方式, . a j a x 执 行 后 , 会 继 续 执 行 a j a x 后 面 的 脚 本 , 直 到 服 务 器 端 返 回 数 据 后 , 触 发 .ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发 .ajax执行后,会继续执行ajax后面的脚本,直到服务器端返回数据后,触发.ajax里的success方法
若要将其设置为false,则所有的请求均为同步请求,在没有返回值之前,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以
GET在浏览器回退是无害的,而POST会再次提交请求
GET请求会被浏览器主动cache,而POST不会,除非手动设置
GET请求只能进行URL编码,而POST支持多种编码
GET请求参数会被完整保留在浏览器历史记录中,而POST中的参数不会被保留
GET请求在URL中传送参数是有大小限制的,不能大于2KB,而POST可以说没有
GET只接受ASCII字符,而POST没有限制
GET参数直接暴露在URL上,而POST将数据放在request body中
Get:在浏览器的地址栏中输入地址 超链接,Form表单默认的提交方式,Ajax
Post:Form表单POST提交,Ajax使用Post提交
Get Post
后退按钮/刷新 | 无害 | 数据会被重新提交(浏览器应该告知用户数据会被重新提交)
书签 | 可收藏为书签 | 不可收藏为书签
缓存 | 可能被缓存 | 不能缓存
历史 | 参数保留在浏览器历史中 | 参数不会保留在浏览器历史中
对数据长度的限制 | Get方法向URL添加数据时,URL长度受限制 | 理论上不受限制
安全性 | 与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。 | Post比Get更安全,因为参数不会被保存在浏览器历史或Web服务器历史中
可见性 | 数据在URL中,对所有人都是可见的 | 数据不会显示在URL中
拦截器是基于java反射机制,过滤器基于函数回调
拦截器不依赖于servlet容器,过滤器依赖于servlet容器。
拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
拦截器可以获取IOC容器中的各个bean,而过滤器就不行,在拦截器里注入一个service,可以调用业务逻辑。
过滤器的执行顺序跟xml中定义的先后有关
Request 对象用于接收客户端浏览器提交的数据
Response 对象的功能则是将服务器端的数据发送到客户端浏览器
转发:
request.getRequestDispatcher("success.html").forward(request,response);
重定向:
resp.sendRedirect("https://www.baidu.com/");
1.转发是在服务器端完成,重定向是在客户端完成。
2.转发是一次请求,重定向是两次请求
3.转发后,地址栏不会改变,重定向后,地址栏会改变。
4.转发只能在同一个WEB项目范围内进行,而重定向可以不在同一个项目进行
5.转发过程中可以携带参数,可以访问WEB-INF文件,重定向不可以。
session.removeAttribute(“sessionname”)是清除SESSION里的某个属性.
session.invalidate()是让SESSION失效
类是对某一类事物的描述,是抽象的;而对象是一个实实在在的个体,是类的一个实例。
对象是函数、变量的集合体;而类是一组函数和变量的集合体,即类是一组具有相同属性的对象集合体。
标签选择器
<style type="text/css">
span{
color: red;
}
</style>
ID选择器:规定用#来定义(名字自定义)
<style type="text/css">
#mytitle
{
border:3px dashed green;
}
</style>
类选择器:规定用圆点.来定义
<style type="text/css">
.oneclass/*定义类选择器*/{
width:800px;
}
</style>
</head>
伪类选择器:主要应用在<a>标签上
<style type="text/css">
a:link{
color:blue;
}
</style>
后代选择器: 定义的时候用空格隔开
<style type="text/css">
.div1 p{
color:red;
}
</style>
交集选择器
<style type="text/css">
h3.special{
color:red;
}
</style>
并集选择器:定义的时候用逗号隔开
p,h1,#mytitle,.one/*定义了一个并集选择器,带有p,h1,id="mytitle",class="one"的标签都内容会显示红色*/{
color:red;
}
序选择器
<style type="text/css">
ul li:first-child{
color:red;
}
ul li:last-child{
color:blue;
}
</style>
下一个兄弟选择器
<style type="text/css">
h3+p{
color:red; // +表示选择下一个兄弟
}
</style>
List和Set是继承自Collection接口,Set是无序的不允许重复的项目,List有序允许重复项目
Set接口派生的类有TreeSet。List接口派生的类有ArrayList,Vector等。
Map是独立的接口,不继承Collection接口。map会维护与key有关联的值。两个key可以引用相同的对象,但是key不能重复,
典型的key是string类型,但也可以是任何对像。
Collection接口
List接口
ArrayList 基于数组实现的,里面的数据保存在数组当中
LinkedList 基于链表实现的
Vector 线程安全,效率低
数据结构
线性:连续的[数组,队列(特点:先进先出),栈(特点:先进后出)],链表(不连续的)
树:二叉树
图:
Set接口(无序,元素不可重复)
HashSet
TreeSet(有序的)
Map接口(使用键值对保存数据)
HashMap键是不可重复的
HashSet:基于哈希表实现的
1.不允许重复
2.允许值为null,但是只允许有一个
3.无序
LinkedHashSet:跟HashSet一样都是基于哈希表实现。只不过linkedHashSet在hashSet的基础上多了一个链表,
这个链表就是用来维护容器中每个元素的顺序的
1.不允许重复
2.允许值为null,但是只允许有一个
3.有序
TreeSet:是基于二叉树实现的
1.不允许重复
2.不允许null值
ArrayList:基于数组实现的
1.查询快,增删慢
查询快是因为数组的空间是连续的,查询时只要通过首地址和下标很快就能找到元素。
增删慢是因为数组是不能扩容的,一旦增加或者删除元素,内部操作就是新开辟一个数组把元素copy到新的数组,老的数组等待被垃圾回收。
LinkedList:基于链表实现的
1.查询慢,增删快
Vector:基于数组实现的
1.线程安全
java.util.Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法。其直接继承接口有List与Set。
Collections是一个工具类,其中的方法都是用于操作Collection
HashMap 允许 key 和 value 为 null,而 Hashtable 不允许
HashMap是不同步的,HashTable是同步的。因此,HashMap更适合于单线程环境,而Hashtable适合于多线程环境。
HashMap 是非线程安全的,Hashtable 是线程安全的。
两者都是非线程安全的
如果你需要得到一个有序的结果时就应该使用TreeMap(因为HashMap中元素的排列顺序是不固定的)。
除此之外,由于HashMap有更好的性能,所以大多不需要排序的时候我们会使用HashMap
查询的时候使用HashMap,增加、快速创建的时候使用TreeMap。
set无序集合,元素不可重复
List有序集合,元素可以重复
Map键值对集合,key不能重复
ArrayList采用数组实现的,查找速度快,插入和删除的效率低。
LinkedList采用双向链表实现的,查找效率低,插入和删除的效率高。
一直在list的尾部添加元素,LinkedList效率要高。
Array 可以存储基本数据类型和对象,ArrayList 只能存储对象。
Array 是指定固定大小的,而 ArrayList 大小是自动扩展的。
Array 内置方法没有 ArrayList 多,比如 addAll、removeAll等方法只有 ArrayList 有。
Set里的元素是不能重复的,可以用iterator()方法来区分重复与否。
存:List调用add方法,有序,可重复
Set调用add方法,无序,不可重复
Map调用put方法,通过键值对,键无序不可重复,值可重复
取:List可以调用get方法,通过for循环;或通过Iterator迭代器逐一遍历
Set通过Iterator迭代器逐一遍历
Map可以调用get方法根据key获得相应value;或转换为Entry对象使用Iterator迭代器迭代
Vector:就比Arraylist多了个同步化机制(线程安全)。
Hashtable:就比Hashmap多了个线程安全。
ConcurrentHashMap:是一种高效但是线程安全的集合。
Stack:栈,也是线程安全的,继承于Vector。
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是单向遍历,ListIterator可以双向遍历
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。
相同点:都是返回第一个元素,并在队列中删除返回的对象。
不同点:如果没有元素 poll()会返回 null,而 remove()会直接抛出异常
Iterator提供了统一遍历操作集合元素的统一接口, Collection接口实现Iterable接口,
每个集合都通过实现Iterable接口中iterator()方法返回Iterator接口的实例, 然后对集合的元素进行迭代操作.
采用ArrayList对随机访问比较快,而for循环中的get()方法,采用的即是随机访问的方法,因此在ArrayList里,for循环较快
采用LinkedList则是顺序访问比较快,iterator中的next()方法,采用的即是顺序访问的方法,因此在LinkedList里,使用iterator较快
从数据结构角度分析,for循环适合访问顺序结构,可以根据下标快速获取指定元素.而Iterator 适合访问链式结构,因为迭代器是通过next()和Pre()来定位的.可以访问没有顺序的集合.
而使用 Iterator 的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口),
如果使用 Iterator 来遍历集合中元素,一旦不再使用 List 转而使用 Set 来组织数据,
那遍历元素的代码不用做任何修改,如果使用 for 来遍历,那所有遍历此集合的算法都得做相应调整,
因为List有序,Set无序,结构不同,他们的访问算法也不一样.
List转数组:toArray(arraylist.size())方法
数组转List:Arrays的 asList(a)方法
我们可以采用Collections包下的unmodifiableMap方法,通过这个方法返回的map,是不可以修改的。
他会报 java.lang.UnsupportedOperationException错。
同理:Collections包也提供了对list和set集合的方法。
Collections.unmodifiableList(List)
Collections.unmodifiableSet(Set)
主动调用 sleep 方法。时间到了会进入就绪状态
主动调用 suspend 方法。主动调用 resume 方法,会进入就绪状态
调用了阻塞式 IO 方法。调用完成后,会进入就绪状态。
试图获取锁。成功的获取锁之后,会进入就绪状态。
线程在等待某个通知。其它线程发出通知后,会进入就绪状态
这两个方法来自不同的类分别是Thread和Object
最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep的作用是让线程休眠制定的时间,在时间到达时恢复,wait只能用notify后者notifyAll方法
start() 方法用于启动线程,run() 方法用于执行线程的运行时代码。而 start() 只能调用一次,run() 可以重复调用。
继承Thread类不适合资源共享,实现Runnbale接口很容易实现资源共享
Thread是类,而Runnable是接口,这就是类和接口区别,类只能继承一次,而接口可以实现多个接口。
实现Runnable接口比继承Thread类多具有的优势
1.适合多个相同的程序代码去处理同一个资源
2.可以避免Java中的单继承
3.增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4.线程池只能放入实现Runnable或Callable类线程,不能直接放入继承Thread的类
sleep(); 让正在执行的线程休眠(暂停执行)
join(); 阻塞当前调用它的线程,等待join执行完毕,当前线程继续执行。
yield(); 暂停当前正在执行的对象,并执行其他线程
· 方法一:使用安全类,比如 Java. util. concurrent 下的类。
· 方法二:使用自动锁 synchronized。
· 方法三:使用手动锁 Lock。
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,
若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock),设置超时时间,超时可以退出防止死锁。
尽量使用 Java. util. concurrent 并发类代替自己手写锁。
尽量降低锁的使用粒度,尽量不要几个功能用同一把锁。
尽量减少同步的代码块
synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁。
synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;
而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。
通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
动态获取类中的信息,就是java反射机制。
动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理。比如说加日志,加事务等。
可以给这个类创建一个代理,故名思议就是创建一个新的类,这个类不仅包含原来类方法的功能,
而且还在原来的基础上添加了额外处理的新类。这个代理类并不是定义好的,是动态生成的。具有解耦意义,灵活,扩展性强。
动态代理实现:首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。
再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。
利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。
动态代理的应用:Spring的AOP,加事务,加权限,加日志。
想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了。
克隆分浅克隆和深克隆,浅克隆后的对象中非基本对象和原对象指向同一块内存,
因此对这些非基本对象的修改会同时更改克隆前后的对象。深克隆可以实现完全的克隆,
可以用反射的方式或序列化的方式实现
实现Cloneable接口并重写Object类中的clone()方法;
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆
id选择器 $("#test")
类选择器 $(".test")
标签选择器 $("test")
Undefined,Null,String,Boolean,Number
· float 最多可以存储 8 位的十进制数,并在内存中占 4 字节。
· double 最可可以存储 16 位的十进制数,并在内存中占 8 字节。
final 修饰的类叫最终类,该类不能被继承。
final 修饰的方法不能被重写。
final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。
垂直水平居中
方式一:使用绝对布局
让left和top都是50%,这在水平方向上让div的最左与屏幕的最左相距50%,垂直方向上一样,所以再用transform向左(上)平移它自己宽度(高度)的50%,也就达到居中效果了
.father{
width: 1000px;
height: 600px;
position: relative;
background-color: red;
}
.son {
background-color: #fff;
width: 300px;
height: 300px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
方法二:使用弹性布局flex
//这种方式比较通用:只需要给父元素设置了三个样式
.father {
width: 500px;
height: 500px;
display: flex; /*弹性布局*/
justify-content: center; /*内容水平居中*/
align-items: center; /*内容垂直居中*/
background-color: red;
}
.son {
width: 200px;
height: 200px;
background-color: black;
}
方法三:使用绝对布局
//使用这种方式的要领是:子绝父相
.father {
width: 500px;
height: 500px;
position: relative;
background-color: red;
}
.son {
width: 200px;
height: 200px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background-color: black;
}
@RequestMapping处理请求地址映射的注解
@RequestParam用于将请求参数区数据映射到功能处理方法的参数上
@Controller标记的类是一个controller
@Autowired依赖注入bean
@ResponseBody返回json格式使用
@Controller --控制层
@Service --业务层
@Repository --数据访问层
@Component --工具层/其他的业务类之上
将指定的类交由spring去管理–创建的对象交给spring容器管理
@ControllerAdvice
生命全局的异常处理器
@ExceptionHandler(Exception.class)
声明此方法时异常处理器
@Aspect
aspectj提供的注解,表示一个类去定义通知(通知容器)
@Scope
指定该类的对象的作用域
1.单例模式
single
2.原型模式
3.request
4.session
在Mybatis-config.xml中
mybatis自定义的SQL语句中,如select语句,如果数据库表的字段为驼峰命名,
即如img_address这样的形式,那么select语句执行的结果会变成null
我的解决方式就是在传递的数据前面加上@param
1.单例模式
2.原型模式
3.request
4.session