Java 基础知识

类加载器的工作原理

http://www.importnew.com/6581.html


[java] Java中的关键字 transient

Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,也可用于网络传输。transient关键字的作用就是让某些被修饰的成员属性变量不被序列化


[java] java-泛型(T)和Object的区别?

Object: 所有类的基类,需要进行强制转
换。但如果转换错误,只有在运行时才会抛出异常。
泛型T: 可以限定任何类型,在编译时就可以检查。
不需要进行强制转化。

?: 可以接收不确定的类型,和Object类似,但可以缩小范围:? extends A,这样就只能接收A类的子类。
对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率


[java] 深入理解Java中的final关键字

什么是final变量?

凡是对成员变量或者本地变量声明为final的都叫作final变量。final变量经常和static关键字一起使用,作为常量。final变量是只读的。只能在声明变量时初始化和构造函数内或者代码块中初始化。
作用在非基本数据类型:非基本对象使用了final不能再指向其他空间,单对象内部的属性值可以更改。

	class User{
		String id;
		String name;
	}
	@Test
	public void mainTest() {
		final User u=new User();
		u.id="123";//可以改变应用对象内部的值
		u=new User();//非法操作,不能指向其他空间
	}

作用在基本数据类型和string:属性A使用了final,就不能再引用其他值。但是对于初始化引用了一个变量B里面值是‘123’。则变量B内部的值可以更改‘abc’。但是A的值始终都是123。

final String a="0";
//		a="123";//非法操作
		
		
		
		String b="0";
		final String  c=b;
		b="12";//可以改变b里面的值
		System.out.println(b);//输出12
		System.out.println(c);//输出0。c始终存储最开始存储的数据

什么是final方法?

方法不可以被子类的方法重写。如果你认为一个方法的功能已经足够完整了,子类中不需要改变的话,你可以声明此方法为final。final方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。


什么是final类?

类不能被继承。如String, Interger以及其他包装类


关于final的重要知识点

final关键字可以用于成员变量、本地变量、方法以及类。
final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
你不能够对final变量再次赋值。
本地变量必须在声明时赋值。
在匿名类中所有变量都必须是final变量。
final方法不能被重写。
final类不能被继承。
final关键字不同于finally关键字,后者用于异常处理。
final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。
接口中声明的所有变量本身是final的。
final和abstract这两个关键字是反相关的,final类就不可能是abstract的。
final方法在编译阶段绑定,称为静态绑定(static binding)。
没有在声明时初始化final变量的称为空白final变量(blank final variable),它们必须在构造器中初始化,或者调用this()初始化。不这么做的话,编译器会报错“final变量(变量名)需要进行初始化”。
将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。
按照Java代码惯例,final变量就是常量,而且通常常量名要大写:

http://www.importnew.com/7553.html


[java] 函数参数的传递方式说明(string、 引用类型、基本类型)

public class TimerTest_main {
    String obj="Object";
    public static void main(String[] agrs){
        TimerTest_main obj_demo = new TimerTest_main();
        String str =new String( "string");
        int intType=0;
        obj_demo.getTest(obj_demo,str,intType);
        System.out.println("obj="+obj_demo.obj);
        System.out.println("str="+str);
        System.out.println("intType="+ intType);
 
    }
    public void  getTest(TimerTest_main obj,String str,Integer intType){
        obj.obj="ObjectChange";
         str="stringChange";
        intType=90;
 
    }
}

运行结果:

obj=ObjectChange
str=string
intType=0

基本数据类型是按值传递,所以intType值没有被修改。(形参是原型变量的一个值的拷贝)
自定义类型是按照引用传递,所以对象obj里的值被更改。(即方法操作参数变量时是拷贝了变量的引用)
String比较特殊,str的值没有被更改。原因是string是通过一个final char[]数组进行保存的 由于final类型的数组值不能够改变,所以在外部调用函数时将string地址的引用进行传递给函数的参数,函数内部再修改这个引用时,由于final char[] 不可修改,所以在再给变量赋值新值时都会重新创建一个string实例(这个新创建的string实例所指向的地址和外部string变量所指向的地址是不同的所以改变不了外部的变量)另外一个点说明因为final String 对象是不可变的,所以可以共享 也就是说 String op=“abc” 和 String op1=“abc” 指向的是同一个引用对象(字符串是常量;它们的值在创建之后不能更改—jdk Api)


[java] string 两种实例化方式解析

String str= “abc” 创建方式

      创建对象的过程

      1 首先在常量池中查找是否存在内容为"abc"字符串对象

      2 如果不存在则在常量池中创建"abc",并让str引用该对象

      3 如果存在则直接让str引用该对象

String str= new String(“abc”)创建方式
创建对象的过程

     1 首先在堆中(不是常量池)创建一个指定的对象,并让str引用指向该对象。

     2 在字符串常量池中查看,是否存在内容为"abc"字符串对象

     3 若存在,则将new出来的字符串对象与字符串常量池中的对象联系起来(即让那个特殊的成员变量value的指针指向它)

     4 若不存在,则在字符串常量池中创建一个内容为"abc"的字符串对象,并将堆中的对象与之联系起来。(有可能此时常量池中的"abc"已经被回收,所以要先创建一个内容       为"abc"的字符串对象)

[java] servlet执行流程?

https://blog.csdn.net/u010452388/article/details/80395679


[java] java线程池

https://blog.csdn.net/qq_31441667/article/details/78830395


[java] JVM内存分类及分类具体功能?


[java] 如何在多线程下使用集合?

1.使用同步集合

2.同步类来进行包装:
包装类Collections.synchronizedMap()和Collections.synchronizedList()提供了一个基本的有条件的线程安全的Map和List实现。

3.使用并发集合
ConcurrentHashMap采用了非常精妙的"分段锁"策略,ConcurrentHashMap的主干是个Segment数组。HashEntry是目前我们提到的最小的逻辑处理单元了。一个ConcurrentHashMap维护一个Segment数组,一个Segment维护一个HashEntry数组。
在JDK的并发包中,常见的非阻塞队列有以下几个:

  • ConcurrentHashMap
  • ConcurrentSkipListMap
  • ConcurrentSkipListSet
  • ConcurrentLinkedQueue
  • ConcurrentLinkedDeque
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet

https://www.cnblogs.com/chengxiao/p/6842045.html
https://blog.csdn.net/q1512451239/article/details/65448412
https://blog.csdn.net/u011389474/article/details/54602812


[java] HashMap为什么不支持多线程?


[java] JDK1. 8新特性有哪些?

1.Lambda表达式

2.Stream函数式操作流元素集合

3.接口新增:默认方法与静态方法

4.方法引用,与Lambda表达式联合使用

5.引入重复注解

6.类型注解

7.最新的Date/Time API (JSR 310)

8.新增base64加解密API

9.数组并行(parallel)操作

10.JVM的PermGen空间被移除:取代它的是Metaspace(JEP 122)元空间


[java] HashMap底层数据结构及原理?

结构:
HashMap中的数据结构是数组+单链表的组合,以键值对(key-value)的形式存储元素的,通过put()和get()方法储存和获取对象。默认长度是16,扩容因子是0.75。
原理:
当我们给put()方法传递键和值时,HashMap会由key来调用hash()方法,返回键的hash值,计算Index后用于找到bucket(哈希桶)的位置来储存Entry对象。
如果两个对象key的hash值相同,那么它们的bucket位置也相同,但equals()不相同,添加元素时会发生hash碰撞,也叫hash冲突,HashMap使用链表来解决碰撞问题。
分析源码可知,put()时,HashMap会先遍历table数组,用hash值和equals()判断数组中是否存在完全相同的key对象, 如果这个key对象在table数组中已经存在,就用新的value代替老的value。如果不存在,就创建一个新的Entry对象添加到table[ i ]处。

如果该table[ i ]已经存在其他元素,那么新Entry对象将会储存在bucket链表的表头,通过next指向原有的Entry对象,形成链表结构(hash碰撞解决方案)。

https://www.cnblogs.com/dijia478/p/8006713.html


HashMap和Hashtable的区别

1.两者最主要的区别在于Hashtable是线程安全,而HashMap则非线程安全
Hashtable的实现方法里面都添加了synchronized关键字来确保线程同步,因此相对而言HashMap性能会高一些,我们平时使用时若无特殊需求建议使用HashMap,在多线程环境下若使用HashMap需要使用Collections.synchronizedMap()方法来获取一个线程安全的集合(Collections.synchronizedMap()实现原理是Collections定义了一个SynchronizedMap的内部类,这个类实现了Map接口,在调用方法时使用synchronized来保证线程同步,当然了实际上操作的还是我们传入的HashMap实例,简单的说就是Collections.synchronizedMap()方法帮我们在操作HashMap时自动添加了synchronized来实现线程同步,类似的其它Collections.synchronizedXX方法也是类似原理)

2.HashMap可以使用null作为key,而Hashtable则不允许null作为key
虽说HashMap支持null值作为key,不过建议还是尽量避免这样使用,因为一旦不小心使用了,若因此引发一些问题,排查起来很是费事
HashMap以null作为key时,总是存储在table数组的第一个节点上

3.HashMap是对Map接口的实现,HashTable实现了Map接口和Dictionary抽象类
4.HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75
HashMap扩容时是当前容量翻倍即:capacity2,Hashtable扩容时是容量翻倍+1即:capacity2+1
5.HashMap和Hashtable的底层实现都是数组+链表结构实现


HashSet和HashMap、Hashtable的区别

有所区别的是HashSet不是key value结构,仅仅是存储不重复的元素,相当于简化版的HashMap,只是包含HashMap中的key而已
通过查看源码也证实了这一点,HashSet内部就是使用HashMap实现,只不过HashSet里面的HashMap所有的value都是同一个Object而已,因此HashSet也是非线程安全的,至于HashSet和Hashtable的区别,HashSet就是个简化的HashMap的


[java] 遍历HashMap集合?

注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。
** 方式一:**
1.获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键

2.遍历键的Set集合,得到每一个键

3.根据键,获取键所对应的值

HashMap map=new HashMap<String,Integer>();
		
		//获取所有key集合
		Set<Integer> set=map.keySet();
		//获取key集合迭代器
		Iterator it =set.iterator();
		while(it.hasNext()){
			String key=(String)it.next();
			System.out.println(map.get(key));
		}

方式二:
键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。
操作步骤与图解:
1.获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。
2.遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象
3.通过键值对(Entry)对象,获取Entry对象中的键与值。

HashMap map=new HashMap<String,Integer>();
   	//获取entry实体对象
   	Set<Map.Entry<String, String >> entrySet=map.entrySet();
   	//获取迭代器
   	Iterator<Map.Entry<String, String>> it=entrySet.iterator();	
   	//开始迭代
   	while(it.hasNext()){
   		Map.Entry<String, String> mapEntry=it.next();
   		mapEntry.getValue();
   		mapEntry.getKey();
   	}

[java] list集合自定义排序?

使用Collections类的sort(list,Comparator(比较器))方法。
jdk1.7匿名类写法

	ArrayList<String> list=new ArrayList<String>();
		list.add("1");
		list.add("9");
		list.add("7");
		Collections.sort(list,new Comparator<String>() {
			public int compare(String o1, String o2) {
				return o1.compareTo(o2);
			};
		});
		Collections.sort(list);
		System.out.println(list);

jdk1.8 Lambda 写法

ArrayList<String> list=new ArrayList<String>();
		list.add("1");
		list.add("9");
		list.add("7");
		
		Collections.sort(list,(e1,e2)->{
			return e1.compareTo(e2);
		});
		System.out.println(list);	

[java] java抽象类与接口区别?

在这里插入图片描述


[java] 生产环境java内存移溢出,怎么排查与解决?


[java] JVM虚拟机

https://blog.csdn.net/qq_34337272/article/details/80294328

https://mp.weixin.qq.com/s?__biz=MzU4NDQ4MzU5OA==&mid=2247483910&idx=1&sn=246f39051a85fc312577499691fba89f&chksm=fd985467caefdd71f9a7c275952be34484b14f9e092723c19bd4ef557c324169ed084f868bdb#rd


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值