一.hashMap与hashTable与ConcurrentHashMap:
1.HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。<Dictionary类是一个已经被废弃的类>
2.Hashtable既不支持Null key也不支持Null value。HashMap中,null可以作为键,这样的键只有一个,可以有一个或多个键所对应的值为null。
3.Hashtable是线程安全的,它的每个方法中都加入了Synchronize方法。在多线程并发的环境下,可以直接使用Hashtable,不需要自己为它的方法实现 同步,HashMap不是线程安全的,在多线程并发的环境下,可能会产生死锁等问题。如果想要线程安全的 HashMap,可以通过Collections类的静态方法synchronize dMap获得线程安全的HashMap。 <Map map = Collections.synchronizedMap(new HashMap())>;
4.hashMap的数据结构:HashMap的底层主要是基于数组和链表来实现的,它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。
5.ConcurrentHashMap:底层采用分段的数组+链表实现,线程安全ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术。它使用了多个锁来控制对hash表的不同部分进行的修改。ConcurrentHashMap内部使用段(Segment)来表示这些不同的部分,每个段其实就是一个小的Hashtable,它们有自己的锁。只要多个修改操作发生在不同的段上,它们就可以并发进行。
JDK1.8的实现已经摒弃了Segment的概念,而是直接用Node数组+链表+红黑树的数据结构来实现,此时锁加在key上,并发控制使用Synchronized和CAS来操作,整个看起来就像是优化过且线程安全的HashMap,虽然在JDK1.8中还能看到Segment的数据结构,但是已经简化了属性,只是为了兼容旧版本。二.(String)、toString、String.valueOf的区别1.(String):使用这种方法时,需要注意的是类型必须能转成String类型。因此最好用instanceof做个类型检查,以判断是否可以转换。instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例,
父类parent,子类son, 此时 flag= son instanceof parent,flag=true。2.toString:String s = Object.toString(),在使用时要注意,必须保证object不是null值,否则将抛出NullPointerException异常。3.String.valueOf:内部实现:public static String valueOf(Object obj){return (obj==null) ? "null" : obj.toString()};当Object不为空时,调用toString()方法,当Object为null时,则返回一个字符串"null"!!!!三.字节流与字符流的区别
字节流:InputStream,OutputStream,程序→文件
字符流:BufferedRead,BufferedWrite,程序→缓存区→文件
字符流需要关闭字符流,缓存区的数据才会被写入文件,否则会一直堆在缓存区。或者可以用flush()方法,将数据强行写入文件。
利用BufferedRead读取文件:
public static void main(String[] args) throws Exception {
String s= "F:/456.txt";
File f =new File(s);
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
String temp="";
while((temp=br.readLine())!=null) {
System.out.println(temp);
}
}四.Integer
源代码:
private static class IntegerCache {//静态缓存类
static final int low = -128;
static final int high;
static final Integer cache[];
static { //静态代码块
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}}这个类就是在Integer类装入内存中时,会执行其内部类中静态代码块进行其初始化工作,做的主要工作就是把一字节的整型数据(-128,127)装包成Integer类并把其对应的引用存入cache数组中,这样在方法区中开辟空间存放这些静态Integer变量,同时静态cache数组也存放在这里,供线程享用,这也称静态缓存。所以当用Integer声明初始化变量时,会先判断所赋值的大小是否在-128到127之间,若在,则利用静态缓存中的空间并且返回对应cache数组中对应引用,存放到运行栈中,而不再重新开辟内存。若不在则new 一个新的对象放入堆中。五.类的初始化过程
/*父类*/
public class Person {
public Person() {
System.out.println("im person_1");
}
{
System.out.println("im person_2");
}
static {
System.out.println("im person_3");
}
}
/*子类*/
public class test extends Person {
public test() {
System.out.println("im test_1");
}
{
System.out.println("im test_2");
}
static {
System.out.println("im test_3");
}
public static void main(String[] args) throws Exception {
new test();
}
}
输出:
im person_3
im test_3
im person_2
im person_1
im test_2
im test_1
解释:在类中变量初始化时,顺序为 static→变量→构造方法。六.值传递,引用传递
public class test {
String s="hello";
char[] ch={'a','b','c'};
Character ck='k';
public static void main(String[] args) throws Exception {
test tt = new test();
tt.change(tt.s,tt.ch,tt.ck);
System.out.println("--------");
System.out.println("s+"+tt.s.hashCode());
System.out.println("ch+"+tt.ch.hashCode());
System.out.println("ck+"+tt.ck.hashCode());
System.out.println("--------");
System.out.println(tt.s);
System.out.println(tt.ch);
System.out.println(tt.ck);
}
public void change(String str,char[] ch,Character ck){
str="world";
ch[0]='d';
ck='c';
System.out.println("str+"+str.hashCode());
System.out.println("ch+"+ch.hashCode());
System.out.println("ckl+"+ck.hashCode());
}
}
输出:
str+113318802
ch+1828682968
ckl+99
--------
s+99162322
ch+1828682968
ck+107
--------
hello
dbc
k
可见,String类型是不会被修改的,在编译时,方法栈里有world,如果是输入赋值给String应该会变,char数组传递的是数组的引用,Character传递的是值
传值不会修改原来的,传引用会修改原来的。七.i++与++i
public static void main(String[] args) throws Exception {
int a=1;
int b=a++; //先执行b=a,再执行a++
System.out.println(b++); //先执行print(b),再执行b++
}
输出:1八.==与equals的区别
==:
1.在==中,如果比较的是int,long,short这种基本数据类型,那么==比较的是它们的值
2.若比较的引用数据类型,如类,String,那么比较的是它们的内存地址,除非是同一个new一个出来的对象,此时地址相同,返回ture,否则返回false
如:
String a= new String("abc");
String b=a;
sout(a==b); //ture
若:
String c= new String("c");
String c1= "c";
sout(c==c1);//false
equals:
1.所有类都继承自Object,若不重写equals()方法,那么调用Object类中的equals()方法,源代码:
public boolean equals(Object obj) {
return (this == obj);
}
也就是仍然是比较其地址。
2.若重写其方法:
在String中:
源代码:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
可以看出equals()是会先用==方法,然后比较两个String的值是否相等。九.final,static关键字
final:
当用final修饰一个类时,表明这个类不能被继承,比如出于安全的考虑,可修饰为final。
如果只有在想明确禁止该方法在子类中被覆盖的情况下才将方法设置为final的。
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
static:
修饰类的成员变量时,每个类只有一个这个成员,而不是每个类的实例化对象都有一个这个变量。
用static修饰后,类名.方法名,类名.属性名,可直接调用,不用实例化对象,避免了先要new出对象的繁琐和资源消耗。
在创建对象时,static修饰的成员会首先被初始化。十.sleep() 和 wait() 有什么区别?
sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。十一.得到文件下的文件
public static void FileRead(String path)throws Exception{
File f= new File(path);
if(!f.exists())
System.out.println("file not exist");
if (f.isDirectory()) {
File[] ss = f.listFiles();
for (File s : ss) {
System.out.println(s.getPath()); // F:xt.txt
}
}else{
System.out.println(f.getName());
}
}十二.实现多线程的三种方法
1.继承thread类创建线程
public class MyThread extends Thread {
public void run() {
System.out.println("MyThread.run()");
}
}
MyThread myThread1 = new MyThread();
myThread1.start();
2.实现runnable接口创建线程
public class MyThread extends OtherClass implements Runnable {
public void run() {
System.out.println("MyThread.run()");
}
}
3.实现Callable接口通过FutureTask包装器来创建Thread线程
PS:别说四种,第四种无法理解十三.抽象类与接口的区别 
主要是:单继承(抽象类),多实现(接口)。
抽象类不能直接实例化对象,需要继承抽象类才能实例化其子类。
从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。
接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。
接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。十四.String Pool
String pool 指字符串常量池,保存着所有在编译时就已经确定的String变量。调用String.intern()方法,可以将此String变量加入常量池中。
String pool在堆中。
String a= new String("a");
String a1= new String("a");
sout(a==a1);//false
String b="b";
String b1="b";
sout(b==b1);//true
String c= new String("c");
String c1= "c";
sout(c==c1);//false
sout(c.equals(c1));//true
详情见 八. ==与equals的区别十五.ArrayList和Vector的区别
这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的数据是允许重复的。
(1)同步性:
Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最 好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。
(2)数据增长:
ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。
总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。十六.Java 中Collections类里的reverse (反转方法)
public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
此方法可反转数组的值.写在最后:为大家准备了一些适合于1-5年以上开发经验的java程序员面试涉及到的绝大部分面试题及答案做成了文档和学习笔记文件以及架构视频资料免费分享给大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术资料),希望可以帮助到大家。

获取方式:请大家关注并私信小编关键词:“资料”即可获取你需要的各类资料。(从入门到大牛全套哦)

java多线程nullpointerexception_温故而知新!越是基础越容易被忽略,java最全基础知识,附赠资料...相关推荐

  1. java多线程为啥一直用的一个线程_一个Java多线程的问题,颠覆了我多年的认知!...

    作者 | ithuangqing 来源 | 编码之外(ID:ithuangqing) 碰见个奇怪的多线程问题 小白们也不用怕,今天的文章你们都能看得懂,最近的学习中,碰到这样的一个问题: Java创建 ...

  2. python pexels_从零开始学习python爬虫方法,从安装到语法基础(附赠资料)

    01 Python与PyCharm安装 "工欲善其事,必先利其器",本节介绍Python环境的安装和Python的集成开发环境(IDE)PyCharm的安装. 1. Python安 ...

  3. 【Java进阶营】JAVA多线程基础学习二:synchronized

    本篇主要介绍Java多线程中的同步,也就是如何在Java语言中写出线程安全的程序,如何在Java语言中解决非线程安全的相关问题,没错就是使用synchronized. 一.如何解决线程安全问题? 一般 ...

  4. 【26天高效学习Java编程】Day19:60 多个实例讲解,彻底搞懂Java 多线程 【可查阅,可复习,可面试】

    本专栏将从基础开始,循序渐进,由浅入深讲解Java的基本使用,希望大家都能够从中有所收获,也请大家多多支持. 专栏地址:26天高效学习Java编程 相关软件地址:软件地址 所有代码地址:代码地址 如果 ...

  5. bat 等大厂常问的Java多线程面试题,3万字解析

    1 基本概括 2 文章详情 1.1 Java基础--Java多线程(进程与线程的介绍) 1.2 Java基础--Java多线程(线程的创建方式) 1.3 Java基础--Java多线程(什么是进程?) ...

  6. java线程内存模型_深度解析Java多线程的内存模型

    内部java内存模型 硬件层面的内存模型 Java内存模型和硬件内存模型的联系 共享对象的可见性 资源竞速 Java内存模型很好的说明了JVM是如何在内存里工作的,JVM可以理解为java执行的一个操 ...

  7. 面试姊妹篇4:常见的Java多线程面试题

    主要内容 本文主要记录多线程相关的操作问题,这些问题主要出现在一些面试中,当然学会了对本身的代码能力也有提升. 目录 1.交替多线程 2.发令枪问题 3.多线程顺序执行 4.关于饥饿死锁 5.线程数设 ...

  8. 入阿里P6?最少啃完这本阿里最新Java多线程编程手册,建议收藏

    前言 Java多线程与并发编程现在已经属于Java面试的重灾区,特别是第一轮面试经常被问到. 很多同学掌握不好主要就是两个点:对并发的体系化掌握不好,还有就是其中的技术深度点掌握不好. 为了方便大家更 ...

  9. Java多线程案例之阻塞队列

    ⭐️前面的话⭐️ 本篇文章将介绍Java多线程案例,阻塞队列,阻塞队列在普通队列的基础上多了两种情况,一是阻塞队列为空时,如果进行出队操作,会使当前线程阻塞,直到有新元素插入阻塞队列,该线程才被通知继 ...

最新文章

  1. Java并发学习一:CPU缓存导致的可见性问题带来的并发Bug
  2. 我的VIM配置及说明【K-VIM】
  3. python报错:ValueError: The truth value of an array with more than one element is ambiguous. Use a.any(
  4. [Python]no encoding declared 错误解决方法
  5. Hadoop企业优化
  6. ADO.NET笔记——基本概念
  7. xx学OD -- 内存断点(上)
  8. 【EMNLP2020】一种多层对多层的BERT蒸馏方法
  9. 第7章 XSL高级应用
  10. pe服务器注册表,注册表修复方法
  11. mysql上机心得体会_数据库原理上机心得体会
  12. Android kotlin上传头像实现
  13. 戴尔710服务器硬盘灯,DELL R710服务器,做RAID5,更换一个硬盘后硬盘灯,黄灯和绿灯交替不断亮??急急求助...
  14. python为什么叫大蟒蛇_Python(大蟒蛇)与云计算
  15. 【bzoj1502】 NOI2005—月下柠檬树
  16. 【自学编程】自己写小例子的经验
  17. 计算机网络--验证性实验
  18. 人大金仓与新疆大学开启产学研合作,助力数据库产业人才建设
  19. [Atcoder SoundHound Contest 2018]E.+ Graph
  20. String的底层结构(使用频率较高的)(java.lang.invoke.MethodHandleImpl.MAX_ARITY)

热门文章

  1. 【flink】flink 消费组死掉 Lag不变 kafka不提交 重启恢复 非常诡异
  2. 【Elasticsearch】Curator 从入门到实战
  3. 【Elasticsearch】 6 种 能使 es 挂掉的方法
  4. 【Elasticsearch】ES Elasticsearch查询优化
  5. 【kafka】kafka 报错 no brokers found when trying to rebalance
  6. 【Elasticsearch】es 增加 删除 节点
  7. 【Kafka】 kafka 启动 Connection to node 1 could not be established. Broker may not be available
  8. Maven : mvn dependency:copy-dependencies
  9. 【Java SE】记录一次Java实验(多态,集合,泛型)
  10. MySQL表的操作(一)