String,StringBuffer与StringBuilder的区别?
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 是不可变的对象, 如果对 String 类型进行改变的时候其实都等同于生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,那速度是一定会相当慢的。
如果是使用 StringBuffer 类,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,而是改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
绝大部分情况下速度StringBuilder>StringBuffer>String
=======================================================
java内存溢出
内存溢出的原因:
程序设计的不严谨;
内存中加载数据量过于庞大,
启动参数内存制设定过小。
内存溢出解决:
修改JVM启动参数。-Xms256m -Xmx256m
==============================================
String s = “123”;这个语句有几个对象产生
类似于你题目中的形式定义一个字符串,java语言中有一个常量池,如果在你的代码的其它地方已经定义过这么这个’123’的变量,在定义string s=’123’的时候,直接把s指向常量池中的字符串123,就不会新生成一个字符串123,但假如没有的话,就会新生成一个字符串123,指向s,并放入常量池!
==============================================
Error、Exception和RuntimeException的区别,作用又是什么?
异常的分类:
① 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException。
② Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。
Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。
如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。
Exception体系包括RuntimeException体系和其他非RuntimeException的体系:
① RuntimeException:RuntimeException体系包括错误的类型转换、数组越界访问、类加载失败和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
②其他非RuntimeException(IOException等等):这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
=======================================================
InputStream和Reader
java.io下面有两个抽象类:InputStream和Reader
InputStream是表示字节输入流的所有类的超类
Reader是用于读取字符流的抽象类
InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根本区别。
即用Reader读取出来的是char数组或者String ,使用InputStream读取出来的是byte数组。
=======================================================
hashCode的作用
哈希码是按照某种规则生成的int类型的数值,哈希码并不是完全唯一的。
HashCode的存在主要是为了查找的快捷性
=======================================================
Object类中有哪些方法,列举3个以上(可以引导)
protected Object clone()创建并返回此对象的一个副本。
boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。
protected void finalize()当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
Class<?> getClass()
返回此 Object 的运行时类。
int hashCode()返回该对象的哈希码值。
void notify()唤醒在此对象监视器上等待的单个线程。
void notifyAll()唤醒在此对象监视器上等待的所有线程。
String toString()返回该对象的字符串表示。
void wait()在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void wait(long timeout)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
void wait(long timeout, int nanos)在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
=======================================================
char型变量中能不能存贮一个中文汉字?为什么?
char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。
=============================================
列举几个Java Collection类库中的常用类
Collection中由于List和Set
List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。
ArrayList ArrayList 底层是维护了一个Object数组实现的。 特点: 查询速度快,增删慢。
LinkedList LinkedList 底层是使用了链表数据结构实现的, 特点: 查询速度慢,增删快。
Vector(了解即可) 底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。
Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
HashSet 底层是使用了哈希表来支持的,特点: 存取速度快.
TreeSet 如果元素具备自然顺序 的特性,那么就按照元素自然顺序的特性进行排序存储。
=======================================================
List、Set、Map是否都继承自Collection接口?
List,Set是,Map不是。 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java JDK不能提供直接继承自Collection的类,Java JDK提供的类都是继承自Collection的”子接口”,如:List和Set。
注意:Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当做一组key集合,一组value集合,或者一组key-value映射。
=======================================================
HashMap中是否任何对象都可以做为key,用户自定义对象做为key有没有什么要求?
在HashMap中使用不可变对象。在HashMap中,使用String、Integer等不可变类型用作Key是非常明智的.我们也能定义属于自己的不可变类。
如果可变对象在HashMap中被用作键,那就要小心在改变对象状态的时候,不要改变它的哈希值了。我们只需要保证成员变量的改变能保证该对象的哈希值不变即可。
=======================================================
启动一个线程是用run()还是start()?
启动线程肯定要用start()方法。当用start()开始一个线程后,线程就进入就绪状态,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。
这并不意味着线程就会立即运行。当cpu分配给它时间时,才开始执行run()方法(如果有的话)。start()是方法,它调用run()方法.而run()方法是你必须重写的. run()方法中包含的是线程的主体。
==============================================
JAVA多线程实现的四种方式
Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。
其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。
1、继承Thread类创建线程
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。
这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
2、实现Runnable接口创建线程
如果自己的类已经extends另一个类,就无法直接extends Thread,此时,可以实现一个Runnable接口
3、实现Callable接口通过FutureTask包装器来创建Thread线程
4、使用ExecutorService、Callable、Future实现有返回结果的线程
ExecutorService、Callable、Future三个接口实际上都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,有了这种特征就不需要再为了得到返回值而大费周折了。而且自己实现了也可能漏洞百出。
可返回值的任务必须实现Callable接口。类似的,无返回值的任务必须实现Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。
注意:get方法是阻塞的,即:线程无返回结果,get方法会一直等待。再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。
==============================================
同步和并发是如何解决的
同步 synchronized修饰
并发 java.util.concurrent实现并发
==============================================
什么叫守护线程,用什么方法实现守护线程(Thread.setDeamon()的含义)
所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。
因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。
==============================================
如何停止一个线程?
停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。
在java中有以下3种方法可以终止正在运行的线程:
使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。
使用interrupt方法中断线程。
try {
Thread.sleep(2000);
thread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止事件得以传播
==============================================
解释是一下什么是线程安全?举例说明一个线程不安全的例子。
加锁的就是安全的,不加锁的就是不安全的
线程安全 就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
线程不安全 就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据
安全性:
比如一个 ArrayList 类,在添加一个元素的时候,它可能会有两步来完成:1. 在 Items[Size] 的位置存放此元素;2. 增大 Size 的值。
在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
那好,我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了
=======================================================
解释Synchronized关键字的作用。 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
Synchronized关键字的作用 同步
分几种情况:
1.其他方法前是否加了synchronized关键字,如果没加,则能。
2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
=============================================
对sql进行优化的原则有哪些?
避免全表扫描,比如用!=,<>
要建立索引,比如where,order by
=======================================================
StringBuffer有什么优势?为什么快?
1. String 类
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。
String a = “a”; //假设a指向地址0x0001
a = “b”;//重新赋值后a指向地址0x0002,但0x0001地址中保存的”a”依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。
因此String的操作都是改变赋值地址而不是改变值操作。
2. StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区
StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区
StringBuffer buf=new StringBuffer(“this is a test”)//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。
3.StringBuffer
StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。
4.线程安全
StringBuffer 线程安全
StringBuilder 线程不安全
5.速度
一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。
6.总结
(1).如果要操作少量的数据用 = String
(2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
(3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
=====================================
熟悉IO么?与NIO的区别,阻塞与非阻塞的区别
IO 面向Stream 阻塞IO
NIO 面向Buffer 阻塞IO和非阻塞IO Selectors
面向Stream和面向Buffer
Java NIO和IO之间最大的区别是IO是面向流(Stream)的,NIO是面向块(buffer)的,所以,这意味着什么?
面向流意味着从流中一次可以读取一个或多个字节,拿到读取的这些做什么你说了算,这里没有任何缓存(这里指的是使用流没有任何缓存,接收或者发送的数据是缓存到操作系统中的,流就像一根水管从操作系统的缓存中读取数据)而且只能顺序从流中读取数据,如果需要跳过一些字节或者再读取已经读过的字节,你必须将从流中读取的数据先缓存起来。
面向块的处理方式有些不同,数据是先被 读/写到buffer中的,根据需要你可以控制读取什么位置的数据。这在处理的过程中给用户多了一些灵活性,然而,你需要额外做的工作是检查你需要的数据是否已经全部到了buffer中,你还需要保证当有更多的数据进入buffer中时,buffer中未处理的数据不会被覆盖
阻塞IO和非阻塞IO
所有的Java IO流都是阻塞的,这意味着,当一条线程执行read()或者write()方法时,这条线程会一直阻塞知道读取到了一些数据或者要写出去的数据已经全部写出,在这期间这条线程不能做任何其他的事情
java NIO的非阻塞模式(Java NIO有阻塞模式和非阻塞模式,阻塞模式的NIO除了使用Buffer存储数据外和IO基本没有区别)允许一条线程从channel中读取数据,通过返回值来判断buffer中是否有数据,如果没有数据,NIO不会阻塞,因为不阻塞这条线程就可以去做其他的事情,过一段时间再回来判断一下有没有数据
NIO的写也是一样的,一条线程将buffer中的数据写入channel,它不会等待数据全部写完才会返回,而是调用完write()方法就会继续向下执行
=====================================================
数据库 乐观锁和悲观锁的机制:
1. 乐观锁是一种思想,具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。
之所以叫乐观,因为这个模式没有从数据库加锁。
2. 悲观锁是读取的时候为后面的更新加锁,之后再来的读操作都会等待。这种是数据库锁乐观锁优点程序实现,不会存在死锁等问题。他的适用场景也相对乐观。
阻止不了除了程序之外的数据库操作。悲观锁是数据库实现,他阻止一切数据库操作。再来说更新数据丢失,所有的读锁都是为了保持数据一致性。乐观锁如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户从新操作。
悲观锁则会等待前一个更新完成。这也是区别。具体业务具体分析
===================================
hashmap和hashtable的区别;
1.Hashtable是Dictionary的子类,HashMap是Map的接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的;
3.HashMap允许键值可以为空,但是只允许一个key值为空,Hashtbale不允许键值为空;
allow(允许)
===================================
final 关键字
1. final类不能被继承,没有子类,final类中的方法默认是final的;
2.final 方法不能被子类的方法覆盖,但可以被继承;
3. final成员变量表示变量,只能被赋值一次,赋值后值不能再改变;
4. final不能用于修饰构造方法;
常量 constant 赋值 assign
===================================
什么时候需要用static ?
当一个方法或者变量需要初始化加载,或者经常被调用的时候,可以考虑加上static
when a method or variavle needs to be initiatized or frequently called, we can add keyword ‘static’.
===================================
static的用法;
1.static是一个修饰符,用于修饰成员变量,和成员方法;
2.static修饰的成员变量称之围静态变量或类变量,static修饰的成员被所有的对象共享;
3.static优先于对象存在,因为static的成员随着类的加载就已经存在;
4.static修饰的成员度偶了一种调用方式,可以直接被类名所调用(类名.静态成员)
全局可见性 global visibility
它属于类,不属于具体的对象
it belongs to the class, not an specific object.
===================================
abstract class和interface的区别;
抽象类abstract class里面可以定义方法,也可以实现方法,interface只能定义方法;
abstract class的方法在子类中可以不实现,也可以重写父类的方法。而接口中的所有方法一定要实现,不可以遗漏
定义方法 define method
===================================
Java.lang.OutOfMemoryError的内存泄漏?
1.启动参数内存值设定的过小;
2.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
3.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
4.程序不严谨,代码中存在死循环或者循环产生过多重复的对象实体;
启动参数 startup parameters
程序 procedure
严谨的 rigorous
死循环 endless loop
对象的引用 object reference
重复的 duplicated
===================================
什么时候会发生Stack Overflow
线程请求的栈深度大于虚拟机允许的最大深度
the stack depth of thread requests is greater than the maximum depth allowed by JVM.
===================================
什么是泛型?
泛型是Java SE 1.5 的新特性, 泛型规定了此集合中元素的类型
泛型 genericity
规定 stipulate
Genericity is a new feature of Java SE 1.5. Genericity stipulates the type of element in the collection.
===================================
throw 和 throws有什么关系?
1.throws 出现在函数头;而throw出现在函数体中。
2. throws表示出现异常的一种可能性(possibility),并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定会抛出某种异常;
3. 两者都不会处理异常,而是由函数的上层调用处理该异常;
上层调用 the upper level call
‘throws’ appears in the funciton head, and ‘throw’ appears in the funciton body;
‘throws’ represents the possibility of an Excepiton, not generates an Exceptions; ‘throw’ throws an Exception, It must throw an Exception object
===================================
Collection 和 Collections 的关系?
1. Java.util.Collection 是一个集合接口,提供了集合对象进行基本操作的通用接口方法。如Set,List集合接口; 意思是 提供了可让集合进行各种操作的方法;
2. Java.util.Collections是一个包装类,包含各种集合有关操作的静态方法。此类不能被实例化,就像一个工具类,服务于java中Collection框架; 意思是提供方法去操作各种集合;
包装类 wrapper class
实例化 instantiation
工具类 utility class
Java.util.Collection is a collection interface .It provides a common interface method for collection object to perform basic operation.
Java.util.Collections is a wrapper class. It contains static methods to operate the collection ojbect. It can’t to be instantiated. It likes a tools class.
===================================
重载和过载的区别?
重载,指一个类里面的方法名相同,但是参数列表不同;
过载,指一个类中拥有多个同名但参数列表不同的方法,这样编译器就可以根据不同的参数来调用不同的方法实现过载。
重载 overriding
过载 overloading
编译器 compiler
===================================
Java 中内联类 ,编译后会生成几个文件?
Java文件编译后,生成的class文件根据你的Java文件中的class个数决定。即Java文件中有几个关键字class就会生成几个class文件
===================================
Oracle的隔离级别有哪些?
Oracle中事务使用了两种SQL标准的隔离层次,已提交读取和串行读取。已提交都去是Oracle事务的默认隔离层次,即之前提到的read commit级别。串行读取则是serializable 级别
Transactions in oracle use two isolation layers of SQL standards-read commited and serializable. Read commit is a default isolation level in Oracle Transaction
===================================
线程和进程的区别;
进程: 一个程序中至少有一个进程,进程是系统进行资源分配和调度的一个独立单位;
线程:进程的一个实体。线程是CPU调度和分派的基本单位。它是比进程更小的能独立运行的基本单位。
线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但它可以同属于一个进程的其他的线程共享进程所拥有的全部资源。
资源分配和调度 resource allocation and scheduling
权限 privilege
必不可少的资源 essential resources
=====================================================
JDk1.8新特性;数据库调优;数据库分区;数据库为什么要强调原子性?spring bean的作用域;Hashmap的put方法底层实现 jvm堆栈常量池的位置;画出堆栈图;
数据库调优,数据库分区分表,数据库的B树实现,jvm调优,多继承的问题
冒泡排序和快速排序等算法;生成随机密码;如何读取文件;网络协议和TCPUDP;常见的内存溢出;数据库为什么要强调原子性?一个原子的service调用了一个非原子的service的方法,请问它是原子的吗?
解决hash碰撞冲突的方法?
https://blog.youkuaiyun.com/zeb_perfect/article/details/52574915
一个事务的service的方法A调用了一个非事务的service的方法B,请问方法B是事务的吗?
各文章之间论调不一,估计要自行测试得出结果
https://blog.youkuaiyun.com/zmx729618/article/details/77976793
https://blog.youkuaiyun.com/H12KJGJ/article/details/53870458
spring AOP切点方法为class a的method1,其中class a中method 2中调用method1 会触发切点吗?回答是不会。
https://blog.youkuaiyun.com/hotdust/article/details/76521458