Java概念性问题1

以下内容来自学习整理

下列代码执行结果为()
public static void main(String argv[])throws InterruptedException{
	            Thread t=new Thread(new Runnable() {
	                public void run() {
	                    try {
	                        Thread.sleep(2000);
	                    } catch (InterruptedException e) {
	                        throw new RuntimeException(e);
	                    }
	                    System.out.print("2");
	                }
	            });
	            t.start();
           
	            t.join();
	            System.out.print("1");
	        }

thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

java 的字符类型采用的是 Unicode 编码方案,每个 Unicode 码占用(16)个比特位。

注意:区分编码和编码格式
  编码: 编码就是一个编号(数字)到字符的一种映射关系,就仅仅是一种一对一的映射而已,可以理解成一个很大的对应表格。java默认的字符集是Unicode(占两个字节byte,一个字节=8比特位bit,所以每个Unicode占用16比特位)
  编码格式:编码格式 是用来序列化或存储编码中提到的那个“编号(数字)”的一种“格式”,包括gbk和utf-8。
gbk: 是指中国的中文字符,其它它包含了简体中文与繁体中文字符
UTF-8: 它是一种全国家通过的一种编码

下面哪个不属于HttpServletResponse接口完成的功能?

A 设置HTTP头标
B 设置cookie
C 读取路径信息
D 输出返回数据
A:设置HTTP头标
response.setHeader("Refresh","3"); //三秒刷新页面一次
B:设置cookie

Cookie c1 = new Cookie("username","only");
response.addCookie(c1);

C(错误):读取路径信息,request读取路径信息
从request获取各种路径总结

request.getRealPath("url"); // 虚拟目录映射为实际目录
request.getRealPath("./");    // 网页所在的目录
request.getRealPath("../"); // 网页所在目录的上一层目录
request.getContextPath();    // 应用的web目录的名称

D:输出返回数据

HttpServleteResponse.getOutputStream().write();
关于依赖注入,下列选项中说法错误的是()

A 依赖注入能够独立开发各组件,然后根据组件间关系进行组装
B 依赖注入使组件之间相互依赖,相互制约
C 依赖注入提供使用接口编程
D 依赖注入指对象在使用时动态注入
  依赖注入的动机就是减少组件之间的耦合度,使开发更为简洁
  依赖注入(Dependency Injection,简称DI)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。依赖注入应用比较广泛。可以使应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。因此依赖注入降低了组件之间的耦合性,而不是使组件之间相互依赖。
  依赖注入和控制反转是同一概念:
  依赖注入和控制反转是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
http://baitai.iteye.com/blog/792980

Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为(A)

A “.?(?=\()"
B ".
?(?=()”
C “.(?=\()"
D ".
(?=()”
前面的.*?是非贪婪匹配的意思, 表示找到最小的就可以了 (?=Expression) 顺序环视,(?=\()就是匹配正括号

 String text = "北京市(海淀区)(朝阳区)(西城区)"; 
 Pattern pattern = Pattern.compile(".*?(?=\\()"
);
 Matcher matcher = pattern.matcher(text);
 if (matcher.find()) {
 System.out.println(matcher.group(0));

选A, 知识点是正则表达式中的贪婪匹配。
1、正则表达式中元字符:
“.”:匹配除去\n换行符的任意字符
"":匹配前面子表达式任意次
“?”:匹配前面子表达式的0次或1次,如果前面也是元字符,那么它就是非贪婪匹配了(默认是贪婪匹配的)。
2、B中 ".
?(?=\()"中后面的(?=\()它是(?=assert)的形式,叫做顺序环视,也就是前面.*?匹配到的字符后面必须要紧接着有assrt中声明的值,也就是左括号(其中\都是转义字符),但是匹配的到的串是不包含assrt中声明的内容的。
3、题中,原串 “北京市(海淀区)(朝阳区)(西城区)”,首先匹配到北京市(前部分),然后北京市后面有左括号( ,这是后面顺序环视部分,但是不包括左括号,这样整个串就匹配完了,截取到的串为“北京市”。
http://www.cnblogs.com/xudong-bupt/p/3586889.html

下面有关java hashmap的说法错误的是?C

A HashMap 的实例有两个参数影响其性能:“初始容量” 和 “加载因子”。
B HashMap 的实现不是同步的,意味着它不是线程安全的
C HashMap通过开放地址法解决哈希冲突
D HashMap中的key-value都是存储在Entry数组中的
  源码程序中用到了一个重要的内部接口:Map.Entry,每个 Map.Entry 其实就是一个 key-value 对。当系统决定存储 HashMap 中的 key-value 对时,完全没有考虑 Entry 中的 value,仅仅只是根据 key 来计算并决定每个 Entry 的存储位置。Entry是数组,数组中的每个元素上挂这个一条链表。
  链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位。很显然我们使用的不是开放地址法。


hashMap和hashtable方面的知识点:

  1. 关于HashMap的一些说法:
    a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。
    b) HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。
    c) HashMap实现不同步,线程不安全。 HashTable线程安全
    d) HashMap中的key-value都是存储在Entry中的。
    e) HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
    f) 解决冲突主要有三种方法:定址法,拉链法,再散列法。HashMap是采用拉链法解决哈希冲突的。
    注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;
      用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。 拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。
  2. Hashtable和HashMap的区别:
    a) 继承不同。 public class Hashtable extends Dictionary implements Map public class HashMap extends AbstractMap implements Map
    b) Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。
    c) Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。
    d) 两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。
    e) 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。
    f) Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。
    注: HashSet子类依靠hashCode()和equal()方法来区分重复元素。
    HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。
下面有关java的一些细节问题,描述错误的是?D

A 构造方法不需要同步化
B 一个子类不可以覆盖掉父类的同步方法
C 定义在接口中的方法默认是public的
D 容器保存的是对象的引用
  构造方法每次都是构造出新的对象,不存在多个线程同时读写同一对象中的属性的问题,所以不需要同步 。
  如果父类中的某个方法使用了 synchronized关键字,而子类中也覆盖了这个方法,默认情况下子类中的这个方法并不是同步的,必须显示的在子类的这个方法中加上 synchronized关键字才可。当然,也可以在子类中调用父类中相应的方法,这样虽然子类中的方法并不是同步的,但子类调用了父类中的同步方法,也就相当子类方法也同步了。
  详见:http://blog.csdn.net/welcome000yy/article/details/8941644
  接口里面的变量为常量,其实际是 public static final ;接口里面的方法为抽象方法,其实际是public abstract。

下列关于Java并发的说法中正确的是(B)

A CopyOnWriteArrayList适用于写多读少的并发场景
B ReadWriteLock适用于读多写少的并发场景
C ConcurrentHashMap的写操作不需要加锁,读操作需要加锁
D 只要在定义int类型的成员变量i的时候加上volatile关键字,那么多线程并发执行i++这样的操作的时候就是线程安全的了

A CopyOnWriteArrayList的实现原理
  在使用CopyOnWriteArrayList之前,我们先阅读其源码了解下它是如何实现的。以下代码是向ArrayList里添加元素,可以发现在添加的时候是需要加锁的,否则多线程写的时候会Copy出N个副本出来。

public boolean add(T e) {
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {

        Object[] elements = getArray();

        int len = elements.length;
        // 复制出新数组

        Object[] newElements = Arrays.copyOf(elements, len + 1);
        // 把新元素添加到新数组里

        newElements[len] = e;
        // 把原数组引用指向新数组

        setArray(newElements);

        return true;

    } finally {

        lock.unlock();

    }

}

final void setArray(Object[] a) {
    array = a;
}

读的时候不需要加锁,如果读的时候有多个线程正在向ArrayList添加数据,读还是会读到旧的数据,因为写的时候不会锁住旧的ArrayList。CopyOnWriteArrayList适用于读多写少的并发场景

public E get(int index) {
    return get(getArray(), index);
} 

B ReadWriteLock即为读写锁,他要求写与写之间互斥,读与写之间互斥,
读与读之间可以并发执行。在读多写少的情况下可以提高效率
C ConcurrentHashMap是同步的HashMap,读写都加锁
D volatite只保证线程在“加载数据阶段”加载的数据是最新的,并不能保证线程安全。
一个线程执行的过程有三个阶段:
加载(复制)主存数据到操作栈 --> 对操作栈数据进行修改 --> 将操作栈数据写回主存
volatite关键字,让编译器不去优化代码使用缓存等,以保证线程在“加载数据阶段”加载的数据都是最新的 ,比如:
某一时刻i=6是最新的值,volatile保证线程A,B都同时加载了这个最新的值,
然后A执行i(A)+1=7,然后将7写回主存,
B也执行i(B)+1=7,然后也将7写回内存,
这样,执行两次加法,i却只增加了1

Consider the following code:AC

String s=null;
Which code fragments cause an object of type NullPointerException to be thrown?
A if((s!=null)&(s.length()>0))
B if((s!=null)&&(s.length()>0))
C if((s==null)|(s.length()==0))
D if((s==null)||(s.length()==0))
  String为引用类型,如果对象为null,也就是说这个对象都不存在了,再去调用对象的相关方法,肯定会报空指针异常。这里调用了String类的length()方法
  &&和||具有短路的效果,在进行&&时,如果&&前的是false,那么&&后的不再执行,直接返回false,同理||也一样。所以BD的s.length()不会被执行,AC会抛出空指针异常.

java中下面哪些是Object类的方法(ABD)

A notify()
B notifyAll()
C sleep
D wait()
在根类Object中包含一下方法:
clone();
equals();
finalize();
getClass();[align=left][/align]
notify(),notifyAll();
hashCode();
toString();
wait();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值