Java概念性问题4

以下内容来自学习整理:

Java实现多线程有两种方式

第一是实现Thread类。步骤:
1 继承Thread 类
2 重写run方法
3 创建多个实例(即线程)
4 启动 调用start方法
补充:run()只是一个普通的方法,没有启动线程的作用,重写这个方法的原因run()方法用来包含那些被线程执行的代码,一般来说被线程执行的代码都是比较耗时的,start():首先启动线程,然后再由jmv去调用该线程的run()方法,同一个线程不能被调用多次
B:实现Runnable接口
实现步骤:
a 创建一个新类并实现Runnable接口
b 重写run()方法
c 创建新类的一个实例
d 创建多个Thread实例,其参数为c中创建的实例对象
e 启动线程
补充:为什么要有这个方法来实现多线程:
1因为如果一个类已经有了一个父类,那么该类就不可能在继承Thread的类,而接口可以继承多个。
2 这个接口定义的成员属性是共享的(相当于static修饰)

int i=0;i=i++

i=0
http://www.cnblogs.com/nailperry/p/4780354.html
http://blog.csdn.net/brooksychen/article/details/1624753

下面程序的输出结果是?3423
package algorithms.com.guan.javajicu;  
public class TestDemo {  
    public static String output ="";  
    public static void foo(int i){  
       try{  
           if(i == 1){  
              throw new Exception();  
           }  
       }catch(Exception e){  
           output += "2";  
           return ;  
       }finally{  
           output += "3";  
       }  
       output += "4";  
    }  
    
    public static void main(String[] args) {  
       foo(0);  
       foo(1);  
       System.out.println(output); 
    }  
}
package algorithms.com.guan.javajicu;   
    public class TestDemo {   
        public static String output ="";   
        public static String foo(int i){   
           try{   
               if(i == 1){   
                  thrownewException();   
               }   
           }catch(Exception e){   
               output += "2";   
                return output; 
           }finally{   
               output += "3";   
           }   
           output += "4";   
          return output;
        }   
        public static void main(String[] args) {   
	        System.out.println(foo(0)); 
            System.out.println(foo(1)); 
		    System.out.println(output);
        }   
    }  
    输出结果就是:
  34 
  342 
  3423
考虑下面这个简单的例子,让我们看看reflection是如何工作的。
import java.lang.reflect.*;
public class DumpMethods{
    public static void main(String[] args) {
        try {
            Class c=Class.forName(args[0]);
            Method m[]=c.getDeclaredMethods();
            for (int i = 0; i < m.length; i++) {
                System.out.println(m[i].toString());
            }
        } catch (Throwable e) {
            System.err.println(e);
        }
    }
}

其中"c.getDeclaredMethods"的作用是:
A 取得类的公有方法对象
B 取得类的所有公有方法名称
C 取得类的所有方法对象
D 以上选项都不正确
  public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
  public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法, 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。

忽略内部接口的情况,不能用来修饰interface里的方法的有(AC )

A private
B public
C protected
D static
Jdk1.8支持接口内部实现静态方法,而且可以有方法体具体实现。

在Java语言中,下列关于字符集编码(Character set encoding)和国际化(i18n)的问题,哪些是正确的?CD

A 每个中文字符占用2个字节,每个英文字符占用1个字节
B 假设数据库中的字符是以GBK编码的,那么显示数据库数据的网页也必须是GBK编码的。
C Java的char类型,以下UTF-16 Big Endian的方式保存一个字符。
D 实现国际化应用常用的手段是利用ResourceBundle类

很多人都把Unicode编码挂在嘴边,其实咱们现实生活中遇到的编码基本都是Unicode的 因为Unicode兼容了大多数老版本的编码规范例如ASCII
  Unicode编码定义了这个世界上几乎所有字符(就是你眼睛看到的长那个样子的符号)的数字表示
  也就是说Unicode为每个字符发了一张身份证,这张身份证上有一串唯一的数字ID确定了这个字符
  在这个纷乱世界上存在的唯一性。Unicode给这串数字ID起了个名字叫[码点](Code Point)而很多人说的编码其实是想表达[Unicode转换格式](即UTF,Unicode Transformation Formats)
  有没有觉得眼前一亮豁然开朗?没错 这就是我们看到的UTF-8/UTF-16/UTF-32的前缀来源 这个[Unicode转换格式]的存在是为了解决[码点]在计算机中的二进制表现形式而设计的 毕竟我们的机内表示涉及存储位宽,兼容古老编码格式,码点是数值过大的罕见字符等问题 [码点]经过映射后得到的二进制串的转换格式单位称之为[码元](CodeUnit)。也就是说如果有一种UTF的码点二进制表示有n字节,其码元为8位(1个byte),那么其拥有码元n个。每种UTF的码元都不同,其宽度被作为区分写在了UTF的后缀——这就是UTF-8/UTF-16/UTF-32的由来。UTF-8的码元是8位的,UTF-16的码元是16位的。大部分的编程语言采用16位的码元作为机内表示。这就是我们在各种语言中调用获取一个字符串中character的数量时会出现这么多混乱的原因。事实上我们调用这些方法时取得的不是字符个数,而是码元个数!一旦我们的字符串中包含了位于基本平面之外的码点,那么就会需要更多的码元来表示,这个时候就会出现测试时常见的困惑——为何return的字符数比实际字符数要多?所以实际写代码时要特别注意这个问题。
  采取不同的映射方式可以得到不同格式的二进制串,但是他们背后所表示的[码点]永远是一致的就好像你换身份证但是身份证号不变一样。由于平时人们误把[转换格式]也称为[编码],所以造成今天Unicode/UTF傻傻分不清楚且遣词造句运用混乱的悲桑局面。
  Unicode 编码发展到今天扩展到了21 位(从U+0000 到 U+10FFFF)。这一点很重要:Unicode 不是16 位的编码,它是21 位的。这21 位提供了1,114,112 个码点,其中,只有大概10% 正在使用,所以还有相当大的扩充空间。
  编码空间被分成 17 个平面(plane),每个平面有 65,536个字符(正好填充2个字节,16位)。0 号平面叫做「基本多文种平面」(BMP, Basic Multilingual Plane),涵盖了几乎所有你能遇到的字符,除了 emoji(emoji位于1号平面 - -)。其它平面叫做补充平面,大多是空的。
总结一下各种编码格式的特质:
UTF-32
最清楚明了的一个 UTF 就是UTF-32:它在每个码点上使用整 32 位。32 大于21,因此每一个 UTF-32值都可以直接表示对应的码点。尽管简单,UTF-32却几乎从来不在实际中使用,因为每个字符占用4 字节太浪费空间了。
UTF-16
以及「代理对」(Surrogate Pairs)的概念UTF-16要常见得多,它是根据有16 位固定长度的码元(code units)定义的。UTF-16本身是一种长度可变的编码。基本多文种平面(BMP)中的每一个码点都直接与一个码元相映射。鉴于BMP 几乎囊括了所有常见字符,UTF-16 一般只需要 UTF-32一半的空间。其它平面里很少使用的码点都是用两个 16 位的码元来编码的,这两个合起来表示一个码点的码元就叫做代理对(surrogate pair)。
UTF-8
UTF-8 使用一到四个字节来编码一个码点。从 0 到 127的这些码点直接映射成 1 个字节(对于只包含这个范围字符的文本来说,这一点使得UTF-8 和 ASCII 完全相同)。接下来的 1,920个码点映射成 2 个字节,在 BMP里所有剩下的码点需要 3 个字节。Unicode的其他平面里的码点则需要 4 个字节。UTF-8是基于 8 位的码元的,因此它并不需要关心字节顺序(不过仍有一些程序会在UTF-8 文件里加上多余的 BOM)。
  有效率的空间使用(仅就西方语言来讲),以及不需要操心字节顺序问题使得 UTF-8成为存储和交流 Unicode文本方面的最佳编码。它也已经是文件格式、网络协议以及 Web API 领域里事实上的标准了。
  我们的JVM中保存码点是UTF16的转换格式,从char的位宽为16位也可以看得出来。由于绝大部分编码的码点位于基本平面,所以使用16位可以几乎表示所有常用字符。这就是许多语言编译器或运行时都使用UTF16的原因。英文在使用UTF16时也是2字节表示的。当我们想要使用其他平面的字符时,码元超过2个字节,就需要使用代理对在语言中的特定表示方式,譬如‘\U112233’之类的。
  使用UTF8时,常用的Alphabet和Numeric都在前127字节,被有效率地用一个字节表示。而我们的中文由于排在1920个码点之后,所以使用3个字节表示,这方面就比UTF16转换格式耗费更多空间。
  最后,不论使用哪种UTF转换格式,都是程序员自己可以选择的一种表达方式而已。我们可以通过Java方便的API进行自如转换。

Java默认使用Unioncode编码,即不论什么语言都是一个字符占两个字节
Java的class文件编码为UTF-8,而虚拟机JVM编码为UTF-16
UTF-8编码下,一个中文占3个字节,一个英文占1个字节
Java中的char默认采用Unicode编码,所以Java中char占2个字节,1(byte)字节=8(bit)位

截止JDK1.8版本,java并发框架支持锁包括?ABD

A 读写锁
B 自旋锁
C X锁
D 乐观锁
E 排他锁

Java锁的种类以及辨析 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及。
截止JDK1.8版本,java并发框架支持锁包括:
读写锁,
自旋锁,
乐观锁。
锁的分类:
1、自旋锁,自旋,jvm默认是10次吧,有jvm自己控制。for去争取锁
2、阻塞锁 被阻塞的线程,不会争夺锁。
3、可重入锁 多次进入改锁的域
4、读写锁
5、互斥锁 锁本身就是互斥的
6、悲观锁 不相信,这里会是安全的,必须全部上锁
7、乐观锁 相信,这里是安全的。
8、公平锁 有优先级的锁
9、非公平锁 无优先级的锁
10、偏向锁 无竞争不锁,有竞争挂起,转为轻量锁
11、对象锁 锁住对象
12、线程锁
13、锁粗化 多锁变成一个,自己处理
14、轻量级锁 CAS 实现
15、锁消除 偏向锁就是锁消除的一种
16、锁膨胀 jvm实现,锁粗化
17、信号量 使用阻塞锁 实现的一种策略
18、排它锁:X锁,若事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值