本文共 12778 字,大约阅读时间需要 42 分钟。
ArrayList
1)ArrayList底层数组结构,原理:数组复制
2)底层自动扩容数组,初始为10,每次扩容上次的1/2
3)善于查询
4)利用index按顺序存储
LinkedList
1)底层链表结构(双链表)
2)善于插入删除数据
3)特殊方法:addLast(),addFirst(),removeFirst(),remove()删除第一个;removeLast()
总结:ArrayList更适合读取数据,linkedList更多的时候添加或删除数据。
ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。
LinkedList是使用双链表实现的,所以get会非常消耗资源,除非位置离头部很近。但是插入和删除元素花费常数时间。重写:不同类中,方法体结构相同,逻辑代码可以不同,方法被定义为final不能被重写。
重载:同一类中,方法体结构相同参数列表类型和个数不能相同。
&和&&都可以作逻辑与,&它的左边无论是true还是false,右边的条件都要进行判断,&&它的左边如果是false,右边则不用进行判断。
&可以用作位运算符,将左边和右边两个数转换成二进制数然后进行与运算。
这也是为什么两者都实现的一个功能,然而最后我们平时使用的是|| &&,因为短路高效啊,快啊
抽象类特点:
1)不能被实例化(子类继承后可实例化子类)
2)充当父类
3)有属性,方法,构造方法,抽象方法
4)抽象类中抽象方法必须被重写
5)子类有且只有一个父类
接口特点:
1)不能被实例化
2)充当父接口
3)有属性,抽象方法(属性必须初始化,且不能更改)
4)子类可以实现多个接口
抽象类(abstract class):
1:abstract 关键字修饰,并且没有方法体 2:抽象类不能直接创建实例 3:抽象类只能被继承,一个具体类继承一个抽象类,必须实现所有抽象方法 接口(interface): 1:实现接口的一定要实现接口里定义的所有方法 2:接口可以实现多重继承 区别: 1:抽象类和接口都不能够实例化,但可以定义抽象类和接口类型的引用 2:一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类 3:接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法 4:抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的 5:抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法6.接口可以继承接口,甚至可以继承多个接口;类可以实现多个接口,只能继承一个类。
5:写出JDBC操作数据库的步骤?
1:加载驱动 Class.forName("com.mysql.jdbc.Driver"); 2:创建连接 Connection con = DriverManager.getConnection ("url", "1111", "1111"); 3:创建语句 PreparedStatement ps = con.prepareStatement("select * from user"); 4:执行语句 ResultSet rs = ps.executeQuery(); 5:处理结果 while(rs.next()) { rs.get.....(“”); } 6:关闭资源 finally { if(con != null) { try { con.close(); } catch (SQLException e) { e.printStackTrace(); } } }加载驱动-创建连接-创建语句-执行语句-处理结果-关闭资源
1. HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口
2.主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高Hashtable 3.HashMap允许将null作为一个entry的key或者value,而Hashtable不允许 4.最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是HashMap线程不安全。HashMap是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许包含空键和空值,而HashTable不允许空键值。
HashTable线程安全。HashMap是HashTable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空键值,由于非线程安全,所以效率上可能高于HashTable。
方式:继承Thread、实现 Runnable 接口
产生: - 一个资源每次只能被一个进程使用 - 一个进程因请求发生阻塞时,依然对已获得的资源保持不放 - 进程已经获得资源使用权,但是一直未使用 - 同一个进程,频繁的获取资源的优先使用权,一直未释放 防止: 加锁顺序(线程按照一定的顺序加锁) 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
死锁检测(一般是将所有的锁存放于map对象中,检测map中的锁)
1.运行速度快慢为:StringBuilder > StringBuffer > String
- (String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的) 2.StringBuilder是线程不安全的,而String、StringBuffer是线程安全的
TCP稳定性较高,但效率低。TCP三次握手协议。
UDP通讯相反,效率较高,但稳定性较差Cookie和session做状态管理
Cookie存在客户端、session数据放在服务器上,cookie放在客户端不安全,session在服务器上影响性能
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行修改 session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能大于3K
GET:
1:从服务器上获取数据,一般不能使用在写操作接口 2:由URL所限制,GET方式传输的数据大小有所限制,传送的数据量不超过2KB 3:请求的数据会附加在URL之后,以?分隔URL和传输数据,多个参数用&连接 4:安全性差 POST: 1:向服务器提交数据,一般处理写业务 2:POST方式传送的数据量比较大,一般被默认为没有限制 3:安全性高 4:请的求的数据内容放置在body中
端口:server.xml
项目缓存:删除work文件夹下的文件 并发:150-200
final—修饰符(关键字)
如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。 一个类不能既被声明为 abstract的,又被声明为final的,被声明为final的方法也同样只能使用,不能重载 finally—异常处理时提供 finally 块来执行操作 finally块则是无论异常是否发生,都会执行finally块的内容 finalize—方法名 finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的,它是在object类中定义的,所有的类都继承了它
两个字节,可以存储,前提是汉字必须是Unicode编码
、
静态变量前面要加static,实例变量不用。实例变量属于对象的属性,必须创建了实例对象,才可以被使用,静态变量不属于某个实例对象,而是属于类,也叫类变量,不用创建任何实例对象就会被使用。
json、file、xml、jsonp等
字节流:按字节读写
字符流:按字符 通常在处理文本时优先使用字符流,其他的用字节流字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符
流在操作时使用了缓冲区,通过缓冲区再操作文件
string、list、set、zset、hash
key-value---Redis
文档存储-----MongoDB
Redis:数据量较小的更性能操作和运算上
MongoDB:主要解决海量数据的访问效率问题
==:比较两个数据内存地址是否相同
equals:比较两个数据值是否一样
list:
- 链表 - 有序 - 继承Collection(set也是) - 可以有重复的对象值,但是对象下标不能重复 Map: - key-value - 无序 - 键不能有重复的 值可以用
int 是基本数据类型,初值为0。Integer是int的包装类,初值为null
Integer缓存:注意拆箱和装箱(-128-127之间) 原始类型:boolean,char,byte,short,int,long,float,double 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
- 进程是资源的分配和调度的一个独立单元,而线程是CPU调度的基本单元
- 同一个进程中可以包括多个线程 - 进程结束后它拥有的所有线程都将销毁,而线程的结束不会影响同个进程中的其他线程的结束 - 线程共享整个进程的资源(寄存器、堆栈、上下文),一个进行至少包括一个线程 - 进程的创建调用fork或者vfork,而线程的创建调用pthread_create - 线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源
就绪状态:
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态。 运行状态: 当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为运行状态。 阻塞状态: 正在运行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等。 状态转换: 就绪→运行:处于就绪状态的进程,当进程调度程序为之分配了处理机后,该进程便由就绪状态转变成运行状态。 运行→就绪:处于运行状态的进程在其运行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从运行状态转变成就绪状态。 运行→阻塞:正在运行的进程因等待某种事件发生而无法继续运行时,便从运行状态变成阻塞状态。 阻塞→就绪:处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态。
1:域名解析
2:TCP三次握手 3:浏览器向服务器发送http请求 4:浏览器发送请求头信息 5:服务器处理请求 6:服务器做出应答 7:服务器发送应答头信息 8:服务器发送数据 9:TCP连接关闭
1**:信息性状态码
2**:成功状态码 200:请求正常成功 204:指示请求成功但没有返回新信息 206:指示服务器已完成对资源的部分 GET 请求 3**:重定向状态码 301:永久性重定向 302:临时性重定向 304:服务器端允许请求访问资源,但未满足条件 4**:客户端错误状态码 400:请求报文中存在语法错误 401:发送的请求需要有通过HTTP认证的认证信息 403:对请求资源的访问被服务器拒绝了forbidden 404:服务器上无法找到请求的资源 5**:服务器错误状态码 500:服务器端在执行请求时发生了错误 503:服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
sleep:
1:属于Thread类,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态 2:sleep方法没有释放锁 3:sleep必须捕获异常 wait: 1:属于Object,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程 2:wait方法释放了锁 3:wait不需要捕获异常
1:Error表示系统级的错误和程序不必处理的异常,有可能恢复,但是恢复比较困难的严重问题。
2:Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况 异常处理的原则: 1:System.out.println是高代价的。调用System.out.println会降低系统吞吐量 2:在生产环境中别用异常的printStackTrace()方法。 3:如果你不能处理异常,不要捕获该异常 4:如果要捕获,应在离异常源近的地方捕获它 5:捕获的异常一定要做处理 6:可以自定义异常 7:就近原则
NIO:是一种new IO,其目的是为了实现高速IO的代码,将IO操作并转换为操作系统,属于非阻塞型,java.nio.*,是以块(缓冲区)的形式就行数据的传输。
IO:是以流的方式就行数据的传输,属于阻塞型,影响程序的性能 传统阻塞IO,如果你要read/write( byte[10M])一个10M的文件,一旦调用了read/write( byte[10M])这个方法,就得等10M全部read/write,方法底层才会返回。 非阻塞线程,调用read/write( byte[10M])方法立即返回,当然这并不能代表10M已经read/write完成,你需要检测这个byte[10M]的缓冲区。
单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。
单例模式只允许创建一个对象,因此节省内存,加快对象访问速度 单例模式要素: a.私有构造方法 b.私有静态引用指向自己实例 c.以自己实例为返回值的公有静态方法 饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法) 优点 1.线程安全 2.在类加载的同时已经创建好一个静态对象,调用时反应速度快缺点 资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化 懒汉式:单例实例在第一次被使用时构建,延迟初始化。 应用场景: - 需要频繁实例化然后销毁的对象 - 创建对象时耗时过多或者耗资源过多,但又经常用到的对象 - 有状态的工具类对象 - 频繁访问数据库或文件的对象 - 网站计数器,一般是采用单例模式实现 - 由于配置文件一般都是共享资源,即web应用的配置对象的读取,一般采用单例模式来实现。如:spring的配置文件的读取等 - 多线程的线程池的设计一般也是采用单例模式 - 数据库连接池的设计
public、final、abstract
8种基本数据类型:
byte 8位 取值范围 -2^7 ~ 2^7 -1 short 16位 取值范围 -2^15 ~ 2^15 - 1 char 16位 取值范围 0 ~ 2 ^16 - 1 boolean 位数不明确 取值范围 true false int 32位 取值范围 -2^31 ~ 2^31 - 1 long 64位 取值范围 -2^63 ~ 2^ 63 - 1 float 32位 取值范围 1.4e-45 ~ 3.40e38 double 64位 取值范围 4.9e-324 ~ 1.79e308 注意: 需要注意的是,String不是基本数据类型,而是引用类型 在jdk1.5中引入了自动拆装箱的新特性,自动拆装箱,是指基本数据类型和引用数据类型之间的自动转换 基本类型转换成包装类型,称为装箱 Integer intObjct = new Integer(2); //装箱 //Integer intObjct = 2 //自动装箱 //自动装箱,如果一个基本类型值出现在需要对象的环境中,会自动装箱 如Integer 和 int 可以自动转换; Float和float可以自动转换
饿汉式单例:
public class Singleton { private Singleton(){} private static Singleton instance = new Singleton(); public static Singleton getInstance(){ return instance; } } 懒汉式单例: public class Singleton { private static Singleton instance = null; private Singleton() {} public static synchronized Singleton getInstance(){ if (instance == null) instance = new Singleton(); return instance; } }
构造器不能被继承,因此不能重写Override,但可以被重载Overload
- Lock能完成几乎所有synchronized的功能,并有一些后者不具备的功能,如锁投票、定时锁等候、可中断锁等候等
- synchronized 是Java内置的关键字,Lock 则是JDK 5中出现的一个包 - synchronized 同步的代码块可以由JVM自动释放;Lock 需要程序员在finally块中手工释放synchronized由硬件支持,cpu锁指令完成
概念:
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化(将对象转换成二进制)。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题 序列化:把Java对象转换为字节序列的过程。 反序列化:把字节序列恢复为Java对象的过程。 实现: 将需要被序列化的类实现Serializable接口 注意: 被关键字static、transient修饰的变量不能被序列化。在被序列化后,transient修饰的变量会被设为初始值。如int型的是0、对象型的是null.
- 抽象:
抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。 - 继承: 继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。 - 封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 - 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,
Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。 notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。 Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
List 以特定次序来持有元素,可有重复元素。
Set 无法拥有重复元素,内部排序。 Map 保存key-value值,value可多值。
cookie和Session
状态管理:
web应用程序是基于HTTP协议的,而HTTP协议是无状态的协议,无状态也就是说一次请求,一次响应之后即断开连接,而同一个用户的下一次请求需要重新建立连接,但在有时候服务器需要判断是否为同一个用户的多次操作,所以这些时候需要将用户的多次请求当做说一个整体来看待,并且将多次交互涉及到的数据进行保存下来
状态:交互产生的数据
管理:多次交互对数据的修改
实现状态常见的有两种方式
cookie:浏览器客户端状态管理,将状态保存在浏览器客户端
session:服务器状态(数据)管理,将状态保存在服务器
Cookie:实现原理
1、浏览器客户端第一次访问服务器端返回响应数据时,响应数据包中以Set-Cookie消息头方式给浏览器返回cookie信息
Set-Cookie:name=张三
Set-Cookie:count =10;
2、浏览器接受服务器端的响应数据包之后,解析响应数据包,获取cookie信息,保存在客户端
3、客户端在后续每一次访问时,需要携带保存cookie,以cookie请求消息头方式发给服务器
cookie:name=张三,count=10
4、服务器接受请求之后,获取请求数据包中cookie信息进行操作,完成HTTP状态管理
Session
1、客户端发送第一次请求,服务器端会创建一个session对象,把相关的数据存储到session中,并给该对象分配一个32位的唯一id,一般称之为JSESSIONID
2、在服务器第一次给客户端返回响应时,把JESSIONID以Set-Cookie消息头方式带回给浏览器客户端
Set-Cookie:JESSIONID=xxxx
3、在客户端接受到响应数据包之后,解析出JESSIONID以cookie形式存储在浏览器客户端
4、在后续浏览器客户端每一次发送请求时,以Cookie消息头方式把JESSIONID发送给服务器
Cookie:JESSIONID=xxxx
5、服务器获取JESSIONID后,根据JESSION去找相应的session 对象,完成状态管理
事务的特性:
1、 原子性(Atomicity)2、一致性(Consistency)3、隔离性(Isolation)4、持久性(Durability)
事务的隔离级别:事务的隔离级别也分为四种,由低到高依次分别为:read uncommited(读未提交)、read commited(读提交)、read repeatable(读重复)、serializable(序列化),这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。
1.read uncommited:是最低的事务隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
2.read commited:保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。
3.repeatable read:这种事务隔离级别可以防止脏读,不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生(不可重复读)。
4.serializable:这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读之外,还避免了幻象读。
脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作是不正确的。
幻读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)
不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读
1.建立适当的索引
2.避免在索引上使用计算
3.避免在索引列上使用NOT
4.避免在索引上使用IS NULL 和 IS NOT NULL
5.避免不必要的行和列
6.Select 子句中避免使用 *
7.在IN后面值的列表中,将出现最频繁的值放在最前面,出现最少的放在最后,减少判断次数。
8.使用batch处理
9.注意Union和Union all的区别
10.Where子句中的连接顺序
11.DISTINCT的使用:注意,在数据量大的时候,尽量不要使用,它同UNION一样会使查询变慢。因为Oracle需要对后面的所有字段进行排序,消耗性能。
一 开源数据连接池
1 dbcp dbcp可能是使用最多的开源连接池,原因大概是因为配置方便,而且很多开源和tomcat应用例子都是使用的这个连接池吧。 这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。这个连接池的配置参见附件压缩包中的:dbcp.xml 使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性还是可以,不过速度稍慢,在大并发量的压力下稳定性 有所下降,此外不提供连接池监控 2 c3p0 c3p0是另外一个开源的连接池,在业界也是比较有名的,这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。 这个连接池的配置参见附件压缩包中的:c3p0.xml。 使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性相当不错,在大并发量的压力下稳定性也有一定保证, 此外不提供连接池监控。转载地址:http://urms.baihongyu.com/