String&异常Exception&线程&总结

本文回顾了String与StringBuffer/StringBuilder的区别,详细讲解了异常处理中的try-finally与finally的执行顺序,梳理了线程概念与死锁案例,同时介绍了List集合的去重技巧。

目录

一、String&StringBuffer&StringBuilder复习

二.异常Exception复习

三、线程复习

四、List集合复习



一、String&StringBuffer&StringBuilder复习

1.String s "Hello";s = s + " world!";这两行代码执行后,原始的 String 对象中的内容到底变了没有?

提示:没有。因为 String 被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。

例如:下面图案可供参考。


 答案:

s 原先指向一个 String 对 象,内容是 "Hello" ,然后我们对 s 进行了 + 操作,那么 s 所指向的那个对象是否发生了改变呢?答案是没有。这时, s 不指向原来那个
对象了,而指向了另一个 String 对象,内容为 "Hello world!" ,原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。

2.String s = new String("xyz");创建了几个 String Object? 二者之间有什么区别? xyz 是字面量

两个,一个放在常量区,不管写多少遍,都是同一个。New String 每写一遍,就创建一个新。

以下图文即可表达:

 New String 每次每写一遍的值都是放在常量区的,无论写多少遍。

3、String 和 StringBuffer 的区别

String StringBuffer ,它们可以储存和操作字符串,即包含多个字符的字符数据。这个 String 类提供了 数值不可改变的字符串。而这个StringBuffer 类提供的字符串进行修改。

String代码演示:

String s = "a";
for(int a = 0;a<100;a++){
	s+=a;
}

String代码效率很低,因为创建了 101 个对象

StringBuffer代码演示:

StringBuffer s = new StringBuffer("a");
for(int a = 0;a<100;a++){
	s.append(a);
}
StringBuffer代码效率很高,因为只创建了一个 StringBuffer 对象

二.异常Exception复习

1.try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?

package com.wangdongsheng.demo;

public class demo {
	
	public static void main(String[] args) {
		System.out.println(test1());
	}

	private static int test1() {
		int i =1;
		//try catch结构,finally的代码必然会执行,try先执行
		//里面有返回值teturn,那么中断,执行完finally中代码
		//再唤醒中断代码
		try {
//			i++;
//			int a = i/0;
//			System.out.println("当前1="+i);
			return i;
		} catch (Exception e) {
			
		}finally {
			System.out.println("finally"+(++i));
		}
		return 0;
	}
	
}

输出为:

 2.final, finally, finalize 的区别

final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成 final 类型。
finally 是异常处理语句结构的一部分,表示总是执行。
finalize Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回
收,例如关闭文件等。 JVM 不保证此方法总被调用。
3.运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。
普通异常代码演示:
    //普通异常
	public static void test2() throws Exception {
		throw new Exception();
	}

运行时异常代码演示:

//运行时异常
	public static void test3(){
		throw new RuntimeException();
	}

3.error 和 exception 有什么区别?

error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示 一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

三、线程复习

线程是什么?
    答案:程序运行的最小单元

   线程如何实现?
    答案:extends Thread
          implement Runnable
    
    线程的状态?
    答案:
         准备、运行、休眠、等待、阻塞、停止

    线程常用的方法?
    thread t1 = new Thread();
    t1.start();
    t1.sleep(1000);
    t1.wait(),进入等待状态,t2.notifyall();唤醒等待的线程

    线程的死锁?

        1.什么是死锁?

        死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去。

2.死锁的案例:
     ab两个线程,a线程要抢占A锁,b线程要抢占b
    锁,锁都得不到释放,线程呈现僵持状态 。

如例:

   

1. sleep() 和 wait() 有什么区别?
sleep 线程类(Thread) 的方法,导致此线程 暂停执行指定时间 ,给执行机会给其他线程,但是 监控状态依然保持 ,到时后会 自动恢复。调用 sleep 不会释放对象锁。 wait Object 类 的方法,对此对象调用 wait 方法导致本线程放弃对象锁,进入等待此对象的 等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll )后本线程才进入对象锁定池准备获得对象锁进入运行状态。
2. 同步和异步有何异同,在什么情况下分别使用他们?
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那 么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
3. 当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对
象的其它方法?
分几种情况:
1. 其他方法前是否加了 synchronized 关键字,如果没加,则能。
2. 如果这个方法内部调用了 wait ,则可以进入其他 synchronized 方法。
3. 如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait ,则不能。

4.多线程有几种实现方法?同步有几种实现方法?

多线程有两种实现方法,分别是继承 Thread 类与实现 Runnable 接口
同步的实现方面有两种,分别是 synchronized,wait notify 。
5.启动一个线程是用 run()还是 start()?
启动一个线程是调用 start() 方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码, run() 方法
是该线程所关联的执行代码。
6.简述 synchronized 和 java.util.concurrent.locks.Lock 的异同 ?
主要相同点: Lock 能完成 synchronized 所实现的所有功能
主要不同点: Lock 有比 synchronized 更精确的线程语义和更好的性能。 synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,
并且必须在 finally 从句中释放。 Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁。
7. 设计 4 个线程,其中两个线程每次对 j 增加 1,另外两个线程对 j 每次减少 1。写
出程序。

四、List集合复习

list集合
    集合与集合之间的区别:List、set、Map
    集合子类之间的区别:数据结构
        ArrayList与Linkedlist区别:
        hashSet与treeset的区别:
        hashMap与hashtabel的区别:
    某集合子类的特点
        如何对set集合/List集合去重

代码演示:
        

package com.wangdongsheng.demo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class demo2 {
	
	public static void main(String[] args) {
//		Set<Person> set = new HashSet<>();
//		set.add(new Person(12, "zs"));
//		set.add(new Person(12, "zs"));
//		System.out.println(set.size());
		
//		Set<String> set = new HashSet<>();
//		set.add("zs");
//		set.add("zs");
//		System.out.println(set.size());
		
		List<Person> list = new ArrayList<>();
		list.add(new Person(12, "zs"));
		list.add(new Person(12, "zs"));
		List<Person> listnew = new ArrayList<>();
		for (Person p : list) {
			if (!listnew.contains(p)) {
				listnew.add(p);
			}
		}
		System.out.println(listnew.size());
	} 
	
}

class Person{
	private int age;
	private String name;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Person(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	@Override
	public int hashCode() {
		System.out.println("======hashCode=====");
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		System.out.println("=====equals====");
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
}

1. ArrayList 和 LinkedList 的区别
1 .对 ArrayList LinkedList 而言,在列表末尾增加一个元素所花的开销都是固定的。对 ArrayList 而言,主要是在内部数组中增加一项,
指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对 LinkedList 而言,这个开销是统一的,分配一个内部 Entry 对象。
2 .在 ArrayList 的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在 LinkedList 的中间插入或删除一个元素的开销是固定的。
3.LinkedList 不支持高效的随机元素访问。
2.HashMap 和 Hashtable 的区别
        2.1.HashMap 是 Hashtable 的轻量级实现( 非线程安全的实现),他们都完成了 Map 接口,主要区别在于 HashMap 允许空(null)键值(key),由于非线程安全,在只有一个线程访问的情况下,效率要高于 Hashtable。
        2.2. Hashtable 继承自 Dictionary 类,而 HashMap Java1.2 引进的 Map interface 的一个实现。
        2.3HashMap 与 HashTable 主要从三方面来说。
        一. 历史原因 :Hashtable 是基于陈旧的 Dictionary 类的, HashMap Java 1.2 引进的 Map 接口的一个实现
        二. 同步性 :Hashtable 是线程安全的,也就是说是同步的,而 HashMap 是线程序不安全的,不是同步的
        三. 值:只有 HashMap 可以让你将空值作为一个表的条目的 key value
3. List, Set, Map 是否继承自 Collection 接口?
        List, Set 是, Map 不是

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值