每日一题总结 2020.01.26-2020.02.04

谁说胖子不能爱 提交于 2020-01-26 18:12:56
  • “>>”(有符号)右移,如果为正,高位补”0“;
    ----------------------------- 如果为负,高位补”1“。
    ”>>>“无符号右移/逻辑右移,无论正负都补"0"。(不管原数的符号位,就是把32位数右移,最后高位补"0")
    没有无符号左移。Java中int类型是4字节,32位,所以左移时要注意。(不是看当前数字有几位)。负数是以补码形式存储的,所以负数的左移和右移要先看补码左右移的结果,
    然后根据”补码的补码是原码“求得最终结果。 (要注意求反码时:符号位不变,其他位取反。)
    比如:-10<<2:(加粗的"1"是符号位) -10的原码是000…0(27个0)11010 ,
    ------------------------------------------------------ 反码是111…1(27个1)10101,
    ----------------------------- ------------------------ 补码是111…1(27个1)10110,
    将补码左移2位的结果是:
    --------------------------------------------------------------- 111…1(25个1)1011000 接下来需要对补码求补码得到最终结果:
    ----------------------------- 反码是000…0(25个0)1100111,
    ----------------------------- 补码是000…0(25个0)1101000,即-4
    接下来求-10>>2,有符号右移,补码是111…1(27个1)10110,
    将补码有符号移2位(本身是负数,高位补"1")的结果是:
    ----------------------------- 111…1(27个1)11101 接下来根据补码的补码为源码,先除符号位外按位取反得反码:
    ----------------------------- 000…0(27个0)10010
    -------------加1得补码:000…0(27个0)10011,即-3
    最后求-10>>>2,无符号右移,补码是111…1(27个1)10110,
    由于无符号位右移的规定结果必须是正数,所以原符号位的“1”被自动转换为对应的数值,不再代表符号。且,正数的补码是本身,所以不变。 将补码无符号右移2位(高位补"0")的结果是:
    ----------------------------------------------- 00111…1(28个1)01
    即‭1073741821。
  • Java语言的下面几种数组复制方法中,哪个效率最高:

A…for循环逐一复制
其他3个都是浅拷贝,只复制引用;for循环用的是深拷贝,复制值,效率最低。

B.System.arraycopy

 public static native void arraycopy
 (Object src,  int  srcPos,Object dest, int destPos,int length);

是本地方法。
这篇https://blog.csdn.net/qq_34834846/article/details/97174521说:
arraycopy方法上有@HotSpotIntrinsicCandidate(然鹅我没找到不知道为什么 qaq)为了提升性能,在JVM里对@HotSpotIntrinsicCandidate注解的方法进行了手写,这里要提一个叫*JNI(Java Native Interface)*的东西,普通的native方法( 比如C选项Array.copyOf方法 )编译后还要通过JNI再次编译成.cpp文件才能执行。
而有 @HotSpotIntrinsicCandidate这个注解的方法在JVM里就是用.cpp文件写好的,所以就跳过了JNI阶段,所以速度就能提升,这也是System.arraycopy()速度冠绝群雄的原因。

C,Arrays.copyOf

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)? (T[]) new Object[newLength]:(T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
        return copy;
    }

该方法还是调用的System.arraycopy,效率不如B高 。

D.使用clone方法

 protected native Object clone() throws 
 CloneNotSupportedException;
  • 关于泛型的说法错误的是:
    A.虚拟机中没有泛型,只有普通类和普通方法 。 √
    B.所有泛型类的类型参数在编译时都会被擦除。 √
    C.创建泛型对象时指明类型,让编译器尽早地做参数检查。 √
    D.泛型的类型擦除机制意味着不能在运行时动态获取List<T>T的实际类型。 × 可以通过反射机制获取 。

下列说法正确的是:
A.ConcurrentHashMap使用synchronized关键字保证线程安全 ×
ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEntry 用来封装映射表的键/值对;Segment(继承自 ReentrantLock )用来充当锁的角色,每个 Segment 对象守护整个散列映射表的若干个桶。每个桶是由若干个 HashEntry 对象链接起来的链表。一个 ConcurrentHashMap 实例中包含由若干个 Segment 对象组成的数组。
使用synchronized关键字来保证同步的是HashTable。

B.HashMap实现了Collection接口 ×
HashMap implements Map而非Collection。

C.Array.asList方法返回java.util.ArrayList对象 ×

 public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

返回的是ArrayList对象,但是不是java.util包中的ArrayList,而是Arrays的一个内部类:

 private static class ArrayList<E> extends AbstractList<E>implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;

        ArrayList(E[] array) {
a = Objects.requireNonNull(array);
        }

D.SimpleDateFormat是线程不安全的 √

 private StringBuffer format(Date date, StringBuffer toAppendTo,
                                FieldDelegate delegate) {
// Convert input date to time field list 
calendar.setTime(date);                

calendar.setTime(date); 可知:多个线程共享SimpleDateFormat实例时,对Calendar对象的更改会相互影响,因此产生了线程安全问题。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!