java练习题

举报
huahua.Dr 发表于 2023/10/27 19:20:37 2023/10/27
【摘要】 1、(单选题)针对不同的堆空间,Java提供了不同的回收器,下面哪个垃圾回收器作用在老年代(D)A、  SerialB、  Parallel ScavengeC、  ParNewD、  CMS解析:Minor GC(新生代):特点:发生次数多,采用时间短,回收掉大量对象收集器:serial, Parallel Scavenge, Parallel New.均采用复制算法.----Serial...

1、(单选题)针对不同的堆空间,Java提供了不同的回收器,下面哪个垃圾回收器作用在老年代(D)

A  Serial

B  Parallel Scavenge

C  ParNew

D  CMS

解析:


Minor GC(新生代):
  • 特点:发生次数多,采用时间短,回收掉大量对象
  • 收集器:serial, Parallel Scavenge, Parallel New.均采用复制算法.----Serial是单线程,Parallel New可以看成Serial多线程版本. Parallel Scanvenge和Parallel New类似,但更注重吞吐率,且不能与CMS一起使用
Full GC(老年代):
  • 特点:发生次数少,耗时长
  • 收集器:Serial Old(整理), Parallel Old(整理), CMS(清除)-----Serial Old是单线程的,Parallel Old可以看成Serial Old的多线程版本.  CMS是并发收集器,除了初始标记和重新标记操作需要Stop the world,其它时间可以与应用程序一起并发执行


2、(单选题)执行以下代码,将会打印(B)

public static void main(String[] args) {
    consume((Function<Object, String>) Object::toString);
    consume((MyFunction) Object::toString);
    consume(Object::toString);
    consume(null);
}
private static void consume(Function<Object, String> mapping) {
    System.out.println("jdk mapping");
}
private static void consume(MyFunction mapping) {
    System.out.println("my mapping");
}
public interface MyFunction extends Function<Object, String> {
}

A

jdk mapping

my mapping

jdk mapping

jdk mapping

B

jdk mapping

my mapping

my mapping

my mapping

C

jdk mapping

my mapping

jdk mapping

my mapping

 D 编译错误

3、(多选题)在将集合List<string> names (集合不为空)转换为数组时,在节省空间和效率方面,Java语言编程规范推荐的方式有(AD )

A 

String[] nameArray = names.toArray(String[]::new);

B

String[] nameArray = names.toArray(new String[names.size() - 1]);

C

String[] nameArray = names.toArray(new String[names.size()]);

D

String[] nameArray = names.toArray(new String[0]);
解析:
Java 11引入了Collection<T>.toArray(IntFunction<T[]> generator),它更好的原因是不需要创建临时数组,一方面节省空间,另一方面这样就不用去考虑toArray(T[])里的参数长度对方法行为以及结果的影响。
【正例】(Java 11+)
List<String> xs = ...;
String[] sa = xs.toArray(String[]::new);
另外,java.util.stream中各Stream的toArray()、toArray(IntFunction<A[]>)也是常用的。

Java 11前toArray(T[] a)的参数应采用零长度的数组,这样可保证有更好的性能。数组容量大小产生的影响如下:

  • 等于0,动态创建与size相同的数组,性能最好;
  • 大于0但小于size,重新创建大小等于size的数组,增加GC负担;
  • 等于size,在高并发情况下,数组创建完成之后,size正在变大的情况下,负面影响与上相同;
  • 大于size,空间浪费,且在size处插入null值,存在NullPointerException隐患。

【正例】(Java 11-)

List<String> list = new ArrayList<>(DEFAULT_CAPACITY); list.add(getElm()); String[] array = list.toArray(new String[0]);

4、(单选题)以下代码运行结果是(A)

// Parent.java
public class Parent {
    static int firstVar = 1;
    static {
        System.out.println("Class Parent:static blocks" + firstVar);
        firstVar++;
    }
    int secondVar = 1;
    static {
        System.out.println("Class Parent:static blocks" + firstVar);
        firstVar++;
    }
    public Parent() {
        System.out.println("constructor Parent: firstVar=" + firstVar + ",secondVar=" + secondVar);
        firstVar++; 
        secondVar++;
    }
    {
        System.out.println("Class Parent:common blocks firstVar=" + firstVar + ",secondVar=" + secondVar);
        firstVar++;
        secondVar++;
    }
    // 非静态方法
    public void bDisplay() {
        System.out.println("Class Parent:static void bDisplay(): " + "firstVar=" + firstVar + ",secondVar=" + secondVar);
        secondVar++;
        firstVar++;
    }
    // 静态方法
    public static void bTest() {
        System.out.println("Class Parent:static void bTest(): firstVar=" + firstVar);
        firstVar++;
    }
}
// Child.java
public class Child extends Parent {
    static int firstVar = 1;
    static {
        System.out.println("Class child:static blocks" + firstVar);
        firstVar++;
    }
    static {
        System.out.println("Class child:static blocks" + firstVar);
        firstVar++;
    }
    int secondVar = 1;
    {
        System.out.println("Class child:common blocks firstVar=" + firstVar + ",secondVar=" + secondVar);
        firstVar++;
        secondVar++;
    }
    public Child() {
        super();
        System.out.println("constructor child: firstVar=" + firstVar + ",secondVar=" + secondVar);
        firstVar++;
        secondVar++;
    }
    public static void aTest() {
        System.out.println("Class child:static void aTest(): firstVar=" + firstVar);
        firstVar++;
    }
    public void aDisplay() {
        System.out.println("Class child:static void aDisplay():  firstVar=" + firstVar + ",secondVar=" + secondVar);
        firstVar++;
    }
    public static void main(String[] args) {
        Child child = new Child();
        child.aDisplay();
    }
}


A

Class Parent:static blocks1

Class Parent:static blocks2

Class child:static blocks1

Class child:static blocks2

Class Parent:common blocks firstVar=3,secondVar=1

constructor Parent: firstVar=4,secondVar=2

Class child:common blocks firstVar=3,secondVar=1

constructor child: firstVar=4,secondVar=2

Class child:static void aDisplay():  firstVar=5,secondVar=3


B

Class Parent:static blocks1

Class child:static blocks1

Class Parent:static blocks2

Class child:static blocks2

Class Parent:common blocks firstVar=3,secondVar=1

constructor Parent: firstVar=4,secondVar=2

Class child:common blocks firstVar=3,secondVar=1

constructor child: firstVar=4,secondVar=2

Class child:static void aDisplay():  firstVar=5,secondVar=3


C

Class Parent:static blocks1

Class Parent:static blocks2

Class Parent:common blocks firstVar=3,secondVar=1

constructor Parent: firstVar=4,secondVar=2

Class child:static blocks1

Class child:static blocks2

Class child:common blocks firstVar=3,secondVar=1

constructor child: firstVar=4,secondVar=2

Class child:static void aDisplay():  firstVar=5,secondVar=3


D

Class Parent:static blocks1

Class Parent:static blocks2

Class child:static blocks1

Class child:static blocks2

constructor Parent: firstVar=4,secondVar=2

Class Parent:common blocks firstVar=3,secondVar=1

constructor child: firstVar=4,secondVar=2

Class child:common blocks firstVar=3,secondVar=1

Class child:static void aDisplay():  firstVar=5,secondVar=3

解析:

对象初始化顺序,子类无法继承父类的static变量
代码执行顺序:
  • 父类静态代码块
  • 子类静态代码块
  • 父类代码块
  • 父类构造函数
  • 子类代码块
  • 子类构造函数

5、(多选题)关于下面代码,下列选项中说法正确的有哪些(AD)

public class Main {
    private static class Container<T> {
        private T t;
        public T get() {
            return t;
        }
        public void set(T t) {
            this.t = t;
        }
    }
    private static class StringContainer extends Container<String> {
        public String get() {
            return super.get();
        }
        public void set(String str) {
            super.set(str);
        }
    }
    private static void test1() {
        Object obj = "testString";
        Container container = new StringContainer();
        container.set(obj);// Container为泛型类,运行时会被统一转成Object
        System.out.println(container.get());
    }
    private static void test2() {
        Object obj = "testString";
        StringContainer stringContainer = new StringContainer();
        stringContainer.set(obj); //StringContainer为具体化类,编译报错,泛型参数已经确认,只能是String类型
        System.out.println(stringContainer.get());
    }
}

Atest1方法能正常运行,并且输出testString

B test2方法能正常运行,并且输出testString

C test1方法无法编译通过

D test2方法无法编译通过

解析:泛型参数在运行时会类型擦除全部转成Object类型,已经类型推断出来具体化参数时,只能匹配对应参数类型

6.(多选题)关于Java 8 类加载器说法正确的是( ABC)

 A、

BootstrapClassLoader(启动类加载器) 负责加载 %JRE_HOME%/lib目录下的jar包和类或被 -Xbootclasspath参数指定的路径中的所有类

 B、

ExtensionClassLoader(扩展类加载器) 负责加载 %JRE_HOME%/lib/ext 目录下的jar包和类或被 java.ext.dirs 系统变量所指定的路径下的jar包

 C、

AppClassLoader(应用程序类加载器) 负责加载当前应用classpath下的所有jar包和类

 D、

BootstrapClassLoader\ExtensionClassLoader\AppClassLoader都继承自java.lang.ClassLoader

解析:


1,ExtentionClassLoader对应的java类是ExtClassLoader,他的父类是java.net.URLClassLoader。URLClassLoader继承java.lang.ClassLoader
2,AppclassLoader对应的java类是AppClassLoader,他的父类也是java.net.URLClassLoader,没错,和ExtClassLoader一样。
3,BootstrapClassLoader是C++编写的,压根没有对应的java类,当然也成不了别人的父类。

7.(单选题)如下代码的输出是(B)

class Base {
    public int id = 100;
    public void doSomething() {
        System.out.println("Base");
    }
}
public class Child extends Base {
    public int id = 101;
    @Override
    public void doSomething() {
        System.out.println("Child");
    }
    public static void main(String[] args) {
        Base base = new Child();
        System.out.println(base.id);
        base.doSomething();
    }
}

A、

100

Base

B、

100

Child

C、

101

Base

D、

101

Child

8.(单选题)关于java.io.BufferedOutputStream类的close方法描述错误的是(D)

A、如果不调用close方法,可能会导致数据丢失

B、调用后会flush缓存中的内容

C、调用后会自动调用底层流的close方法

D、不能重复调用close方法,否则会出错

9.(单选题)JVM调优的常见命令工具描述正确的有( ACD)

 A、jstat可以实时显示本地或远程JVM进程中类装载、内存、垃圾收集、JIT编译等数据

 B、jmap用于查询当前运行的JVM属性和参数的值 --应该是jinfo命令,jmap是查看jvm内存情况

 C、jstack用于生成当前JVM的所有线程快照

 D、jps命令用于查询正在运行的JVM进程

10.(单选题)假设所有类均已经包含在类路径中,以下对Class.forName("com.example.Test")说法正确的是(C)

A、若com.example.Test类没有加载到JVM中,则返回null 

B、若com.example.Test类没有加载到JVM中,则抛出ClassNotFoundException

C、若com.example.Test类没有加载到JVM中,则加载该类到JVM中并进行初始化

D、若com.example.Test类没有加载到JVM中,则加载该类到JVM中不会进行初始化

11.(单选题)下面这段代码的输出结果是(B)

public static void main(String[] args) {
testSwitch(null);
}
private static void testSwitch(String str) {
switch (str) {
case "null":
System.out.println("null");
break;
default:
System.out.println("default");
}
}

A. 编译错误

B. 抛出异常

C. null

D. default

switch case 语句有如下规则:
  • switch 语句中的变量类型可以是: byte、short、int 或者 char及其包装类和Enum。从 Java SE 7 开始,switch 支持字符串 String ,同时 case 标签必须为字符串常量或字面量。
  • switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
  • case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
  • 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
  • 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
  • switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。

12.(多选题)存在两个类分别是Egg和BigEgg,其中BigEgg继承Egg,代码片段如下:


public class Egg {

class Yolk {

public Yolk() {

System.out.println("Egg.Yolk");

}

}

public Egg() {

new Yolk();

}

}

public class BigEgg extends Egg {

class Yolk {

public Yolk() {

System.out.println("BigEgg.Yolk");

}

}

}

下面选项中说法正确的是(BD)

A.执行new BigEgg()创建BigEgg对象则控制台打印BigEgg.Yolk

B.执行new BigEgg()创建BigEgg对象则控制台打印Egg.Yolk

C.BigEgg.Yolk类将会自动继承Egg.Yolk类

D.BigEgg.Yolk和Egg.Yolk在不同的命名空间,两者没有直接关系


13.(多选题)根据编程规范,如下哪些选项是推荐的数组复制方式(BD )

A

int[] src = { 1, 2, 3, 4, 5 };
int[] dest = new int[5];
for (int i = 0; i < src.length; i++) {
dest[i] = src[i];
}

B

int[] src = { 1, 2, 3, 4, 5 };
int[] dest = new int[5];
dest = Arrays.copyOf(src, 5);

C

int[] src = { 1, 2, 3, 4, 5 };
int[] dest = new int[5];
dest = (int[]) src.clone();

D

int[] src = { 1, 2, 3, 4, 5 };
int[] dest = new int[5];
System.arraycopy(src, 0, dest, 0, 5); 
解析:



在将一个数组对象复制成另外一个数组对象时,不要自己使用循环复制,可以使用Java提供的System.arraycopy()功能来复制数据对象,这样做可以避免出错,而且效率会更高。java.util.Arrays.copyOf()是对System.arraycopy()便利化封装。数组复制有如下特性:

  • 对于一维数组,且数组元素为基本类型或String类型时,数组复制属于深复制,即复制后的数组与原始数组的元素互不影响;
  • 对于多维数组,或一维数组中的元素是引用类型时,数组复制属于浅复制,即复制后的数组与原始数组的元素引用指向的是同一个对象。

14.(单选题)以下字节码代码输出结果是(D)

class Main
Minor version: 0
Major version: 52
Flags: PUBLIC, SUPER


public void <init>();
Flags: PUBLIC
Code:
linenumber 1
0: aload_0 /* this */
1: invokespecial java/lang/Object.<init>:()V
4: return 


public static void main(java.lang.String[] args);
Flags: PUBLIC, STATIC
Code:
linenumber 3
0: getstatic java/lang/System.out:Ljava/io/PrintStream;
3: ldc "start"
5: invokevirtual java/io/PrintStream.println:(Ljava/lang/String;)V
linenumber 4
8: invokestatic Main.test:()V
linenumber 5
11: getstatic java/lang/System.out:Ljava/io/PrintStream;
14: ldc "end"
16: invokevirtual java/io/PrintStream.println:(Ljava/lang/String;)V
linenumber 6
19: return 


private static void test();
Flags: PRIVATE, STATIC
Code:
linenumber 9
0: new Ljava/lang/IllegalArgumentException;
3: dup 
4: ldc "exception"
6: invokespecial java/lang/IllegalArgumentException.<init>:(Ljava/lang/String;)V
9: athrow 

A.

start

end

B.

start

C.

start

exception

end

D.

start

抛出IllegalArgumentException

15.(单选题)根据Java编程规范,Java类加载表述正确的是( A )

A.URLClassLoader的默认签名检查依赖jar包中的公钥,因此不能仅依赖该机制对jar包进行合法性检查

B.开发者不可以自定义类加载器

C.来自同一个class文件的类,被不同ClassLoader加载,视为同一个类

D.当自定义一个类加载器时,为了保证赋予权限的完整,应该直接覆写getPermissions()方法,无需调用基类的getPermissions()方法

解析:


1. 自定义类加载器,如果需要覆写 getPermissions() 方法时,在给其他代码设置权限之前,必须要先调 用父类的 getPermissions() 方法来应用默认的安全策略。自定义类加载器如果忽略调用父类的 getPermissions() 方法,该类加载器可以加载提升权限的不可信类。

2. 即使这两个类来源于同一个 Class文件,被同一个Java虚拟机加载,但只要加载它们的类加载器不同,那这两个类就必定不相等。



16.(多选题)如下代码哪些写法可以正确实现删除"2"?(BCD)

List<String> list = new ArrayList<>(DEFAULT_CAPACITY);
list.add("1");
list.add("2");

A.

for (String item : list) {
if ("2".equals(item)) {
list.remove(item);
}
}

B.

list.removeIf(item -> "2".equals(item));

C.

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (item.equals("2")) {
iterator.remove();
}
}

D.

list.remove(1);
解析:


java.util.concurrent包之外的(非concurrent)集合在foreach循环中不要更改,否则可能会导致ConcurrentModificationException。当需要遍历集合并删除部分元素时,可采用removeIf()方法或Iterator的remove()方法。个别集合(例如CopyOnWriteArrayList)的Iterator中remove()方法会抛出UnsupportedOperationException。


17.(单选题)根据Java IO 流的分类,下面属于字符流的是(B)

A.ByteArrayInputStream

B.InputStreamReader

C.FileInputStream

D.PipedInputStream


18.(单选题)以下容器实现的代码,可能存在什么问题?(C)

public synchronized T pop() {
if (size == 0) {
throw new EmptyStackException();
}
return elements[--size];
}

A.数组越界

B.内存溢出

C.内存泄漏

D.没有问题


19.(单选题)以下哪个对象作为同步锁是正确的(C)

A.

private final String lock = "LOCK"; 
public void doSomething() {
synchronized (lock) { 
// ... 
}
}

B.

private final Boolean lock = Boolean.FALSE; 
public void doSomething() {
synchronized (lock) { 
// ... 
}
}

C.

private final Integer lock = new Integer(count); 
public void doSomething() {
synchronized (lock) { 
// ... 
}
}

D.

private final String lock = new String("LOCK").intern(); 
public void doSomething() {
synchronized (lock) { 
// ... 
}
}
解析:不能使用可被重用的对象进行同步


基础数据类型当作为锁对象使用时,这些锁对象可被其他线程或功能重用,进而会导致死锁或不正确线程同步行为

正确使用方式:

20.(多选题)子类不可以覆写(override)父类哪些方法?(ABC)

A.final方法

B.static方法

C.private方法

D.void方法


21.(多选题)根据java编程规范,以下哪些场景建议使用UTF-8编码(ACD )

A.java源文件

B.与外界的数据交互

C.资源文件

D.配置文件


22.(单选题)下面打印结果是(B)

public class TreeSetMain {
public static void main(String[] args) {
Set<People> treeSet = new TreeSet<People>((t1, t2) -> t1.age - t2.age);
treeSet.add(new People("zhangsan", 2));
treeSet.add(new People("lisi", 1));
treeSet.add(new People("wangwu", 3));
treeSet.add(new People("mazi", 3));

Iterator itTSet = treeSet.iterator();//遍历输出
while (itTSet.hasNext()) {
System.out.print(itTSet.next() + "\t");
}
System.out.println();
}
static class People {
int age;
String name;
People(String name, int age) {
this.age = age;
this.name = name;
}
public String toString() {
return name;
}

A.lisi zhangsan wangwu mazi

B.lisi zhangsan wangwu

C.wangwu mazi lisi zhangsan

D.wangwu mazi zhangsan lisi

解析:


TreeSet的底层是TreeMap的keySet(),而TreeMap是基于红黑树实现的,红黑树是一种平衡二叉查找树,它能保证任何一个节点的左右子树的高度差不会超过较矮的那棵的一倍。

TreeMap是按key排序的,所以TreeSet中的元素也是排好序的。显然元素在插入TreeSet时compareTo()方法要被调用,所以TreeSet中的元素要实现Comparable接口。TreeSet作为一种Set,它不允许出现重复元素。TreeSet是用compareTo()来判断重复元素的,而非equals()。


23.(单选题)以下关于线程池的说法错误的是(B)

A.线程池构造参数包括:核心线程数,最大线程数,工作队列,线程工厂及丢弃策略等参数

B.为避免不加控制地创建新线程,应通过Executors来创建线程池,对资源进行管控

C.线程池中核心线程和非核心线程均可被回收

D.对线程池(包括ScheduledThreadPoolExecutor)中的线程进行setUncaughtExceptionHandler是无效的

解析:

Java虚拟机能够管理的线程数量有限,不加控制的创建新线程可能会导致Java虚拟机崩 溃。建议用Java 1.5之后提供的线程池ThreadPoolExecutor来管理线程资源。 线程池不应该使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式 更加明确线程池的运行规则,规避资源耗尽的风险。 1) newFixedThreadPool 和 newSingleThreadExecutor : 允许的请求队列长度为 Integer.MAX_VALUE ,可能会堆积大量的请求,从而导致 OOM 。

 2) newCachedThreadPool : 允许的创建线程数量为 Integer.MAX_VALUE ,可能会创建大量的 线程,从而导致 OOM 。 newScheduledThreadPool会自动增长工作队列大小。 newWorkStealingPool实际的线程数量可能动态地增减。 不好的例子:

 public void processEntity1(List items) {

 for (Entity entity : items) {

 new Thread(new EntityProcessor(entity)).start(); 

}

 } 

推荐例子:由线程池来管理线程资源,对线程池指定核心线程数,最大线程数,工作队列大小,线 程工厂及丢弃策略等参数 



24.(多选题)Java语言中,基于已定义接口B和C,下列继承或实现用法正确的有(AD)

A.public interface A extends B, C

B.public interface A implements B, C

C.public class A extends B, C 

D.public class A implements B, C

解析:接口可以多继承,类只能单继承;接口不可以实现接口,类可以实现多个接口


25.(单选题)下面哪段代码不存在安全风险?(C)

A. 

public class Exec {
public static void main(String args[]) throws IOException,InterruptedException {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
int exitVal = proc.waitFor();
//...
}
}

B.

try {
FileInputStream fis = new FileInputStream(System.getenv("APPDATA") + args[0]);
} catch (FileNotFoundException e) {
// Log the exception
throw new IOException("Unable to retrieve file", e);
}

C.

public class MyClassLoader extends URLClassLoader {
@Override
protected PermissionCollection getPermissions(CodeSource cs) {
PermissionCollection pc = super.getPermissions(cs);
// allow exit from the VM anytime
pc.add(new RuntimePermission("exitVM"));
return pc;
}
// Other code…
}

26(多选题)关于java.util.PriorityQueue,以下说法正确的有( ABCD)

A.PriorityQueue 实现了优先队列,能保证每次取出的元素都是队列中权值最小的。元素大小的评判可通过元素本身的自然顺序(natural ordering),也可通过传入的比较器(Comparator)

B.PriorityQueue 不允许空值,而且不支持 non-comparable(不可比较)的对象

C.PriorityQueue 在创建时可以指定初始大小

D.PriorityQueue 是非线程安全的

27(单选题)以下哪个选项可以停止线程( C )

A.调用Thread.currentThread().isInterrupted()方法停止线程

B.调用Thread.interrupted()方法来停止线程

C.调用Thread.interrupt()方法来停止线程

D.调用Thread.notify()方法来停止线程

28(多选题)根据Java编程规范,用括号明确表达式的操作顺序,避免过分依赖默认优先级。以下代码写法正确的有哪些( CD )

A.

int x = (-a); 

B.

if ((a && b) && c) …

C.

return list == null || list.isEmpty();

D.

if ((a && b) || c) …
解析:







使用括号强调所使用的运算符顺序,防止因默认的优先级与设计思想不符而导致程序出错。

然而过多的括号也会分散代码降低其可读性

  • 一元运算符,不需要使用括号
foo = ~a; // 一元运算符,不需要括号 foo = -a; // 一元运算符,不需要括号 if (var1 || !isSomeBool) // 一元运算符,不需要括号
  • 涉及位操作,推荐使用括号
foo = (a & 0xFF) + b; // 涉及位运算符,需要括号
  • 如果不涉及多种运算符,不需要括号

涉及多种操作符混合使用并且优先级容易混淆的场景,建议使用括号明确表达式操作顺序。

foo = a + b + c; // 运算符相同,不需要括号 if (a && b && c) // 运算符相同,不需要括号 foo = 1 << (2 + 3); // 运算符不同,优先级易混淆,需要括号
  • 对于极简的三元表达式或者条件表达式,不用加括号

极简规定为:单个值(变量或常量)、方法调用的结果,直接或类型转换后的布尔比较。只要包含额外的(例如算术)运算,即先执行其他运算再拿其结果作布尔比较的,则不算极简,建议加括号。布尔比较(boolOp)是指==!=>>=<<=等结果为boolean的表达式。

29(单选题)根据Java编程规范,下列说法正确的是( B )

A.可以使用浮点数作为循环计数器

B.禁止尝试与NaN进行比较运算,相等操作使用Double或Float的isNaN() 方法

C.需要精确计算时可以使用float和double

D.浮点型数据判断相等可以使用==

30(单选题)下列使用NIO对文件读写进行操作,哪个是错误的( C )

A.

读小文件的所有字节:

byte[] bytes = Files.readAllBytes(file.toPath());

B.

读小文本中所有的行:

List<String> lines = Files.readAllLines(file.toPath());

C.

将数据写入文件尾:

// file与lines为合法参数
Files.write(file.toPath(), lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE);

D.

读取大文本:

try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
String line = null;
while ((line = reader.readLine()) != null) {
// ...
}
} catch (IOException x) {
// ...
}

31(多选题)根据Java语言编程规范,对于sql中拼接的字段名、表名,可以使用的防注入方式有( BD)

A.参数化查询

B.白名单校验

C.对不可信数据进行转码

D.使用正则表达式校验

32(单选题)如下代码,编译执行结果是( C )

class Dog {
public static void bark() {
System.out.println("woof");
}
}
class Basenji extends Dog {
public static void bark() {
System.out.println("miao");
}
}
public class Bark {
public static void main(String[] args) {
Dog woofer = new Dog();
Dog nipper = new Basenji();
woofer.bark();
nipper.bark();
}
}

A.

编译错误

B.

miao

woof

C.

woof

woof

D.

miao

miao

35(多选题)以下关于继承或实现的描述,错误的有( ABC )

A.只能实现单个Interface

B.Class允许多重继承

C.子类override的函数的可见性Accessibility,相比父类,可以降低

D.子类override的函数的throws的异常类型的数量和范围,相比父类,不可以更多更宽泛


34(单选题)Java8中,break包含有标签形式(labeled)和无标签形式(unlabeled)。无标签形式的break常用于解决某些特殊场景以提升性能、简化代码。如下代码的打印结果是( B )

int[] arr = {100, 101, 102};
OUTER:
while (true) {
for (int i = 0; i < arr.length; ++i) {
if (i == 1) {
break OUTER;
} else {
System.out.println("A");
}
}
System.out.println("B");
}
System.out.println("C");

A.

3个A和无数个B

B.

1个A和1个C

C.

1个A和无数个B

D.

编译错误

解析:

java这种跳出循环的方式:

break:跳出本层for或者while循环继续执行以后代码

continue:提前结束本次循环,然后执行下一次循环,并未跳出本层循环

return:结束本次方法执行,如果有返回值则返回结果

lable:跳出所有循环到定义lable标签的位置

33(多选题)关于函数式接口定义,以下写法正确的有( ACE )

A.

public interface MyFunction extends Function<Object, String> {
}

B.

@FunctionalInterface
public interface MyFunction extends Function<Object, String> {
void test();
}

C.

public interface MyFunction extends Function<Object, String> {
private void test() {
}
default void test1() {
}
}

D.

@FunctionalInterface
public interface MyFunction {
private void test() {
}
default void test1() {
}
}

E.

@FunctionalInterface
public interface MyFunction {
static void test() {
}
void test1();
}

41(多选题)以下异常列表哪些属于敏感异常(AB)

A.java.io.FileNotFoundException

B.java.sql.SQLException

C.java.lang.NullPointerException

D.java.io.IOException


40(单选题)Java的安全管理器SecurityManager的policy文件配置如下:

grant {
... ...
permission java.util.PropertyPermission "java.version", "read";
... ...
};
public static void main(String... args) {
System.setSecurityManager(new SecurityManager());
System.setProperty("java.version", "1.7.0_45");
String javaNewVersion = System.getProperty("java.version");
System.err.println(javaNewVersion);
}

注:sdk的版本是1.8.0_45

程序输出的结果是哪一项?(C)

A.1.7.0_45

B.1.8.0_45

C.java.security.AccessControlException: access denied

D.不确定

解析:已经设置只读:

permission java.util.PropertyPermission "java.version", "read";


39(单选题)运行以下代码将会在控制台打印什么( C )

List<String> strList = new ArrayList<>();
List<Object> objList = new ArrayList<>();
System.out.println("START");
objList = strList;
System.out.println("END");

A.

START

B.

START

END

C.

编译错误

D.

END


38(多选题)以下代码中关于“this”关键字的用法,说法正确的有哪些( ABD )

import java.util.Optional;
import java.util.function.Predicate;
public class Salary {
private double salary;
public boolean modifySalary(double byPercent, Predicate<Double> predicateRaise) {
boolean valid = Optional.ofNullable(predicateRaise).map(
predicate -> predicate.test(this.salary * byPercent / 100)).orElse(false);
if (valid) {
this.salary += this.salary * byPercent / 100;
}
return valid;
}

A.this表示当前类的对象实例,在Lambda表达式中this的意义跟在表达式外部完全一样

B.变量名使用this前缀,可以区分实例域和局部变量

C.this是类的隐式成员变量

D.从生成的字节码层面来看,this是方法modifySalary的隐式参数


37(单选题)下面代码中有两处注释,分别是代码1代码2。为了使test方法功能正常,应该使用如下哪个选项的内容依次替换注释代码1代码2( B )

public static void test(String filePath) {
RandomAccessFile aFile = null;
try {
aFile = new RandomAccessFile(filePath,"rw");
FileChannel fileChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(1024);
int bytesRead = fileChannel.read(buf);
System.out.println(bytesRead);
while (bytesRead > 0) {
// 代码1 切换读取模式
while (buf.hasRemaining()) {
System.out.print((char)buf.get());
}
// 代码2,切换写入模式
bytesRead = fileChannel.read(buf);
}
} catch (IOException e) {
// log error
} finally {
try {
if (aFile != null) {
aFile.close();
}
} catch (IOException e) {
// log error
}
}
}

A.

buf.rewind();buf.flip();

B.

buf.flip();buf.compact();

C.

buf.flip();buf.rewind();

D.

buf.flip();buf.reset();


36(单选题)关于类的静态方法用法,如下代码将会输出什么( A )

public class NullTest {
static void register() {
System.out.println("register");
}

static void test(NullTest obj) {
obj.register();
}

public static void main(String[] args) {
try {
test(null);
} catch (NullPointerException e) {
System.out.println("NPE error");
} catch (Exception e) {
System.out.println("error");
}
}

A.register

B.NPE error

C.error

D.编译错误

49(多选题)在使用java中的套接字(socket)时,下列代码实现中,哪些选项可能会导致主线程长时间阻塞(ABD )

A.

Socket s = new Socket("10.116.123.112", 6526);
InputStream stream = s.getInputStream();
// use thread read data

B.

Socket s = new Socket("10.116.123.112", 6526);
s.setSoTimeout(2000);
InputStream stream = s.getInputStream();
// use thread read data

C.

Socket s = new Socket();
s.connect(new InetSocketAddress("10.116.123.112", 6526), 1000);
InputStream stream = s.getInputStream();
// use thread read data

D.

Socket s = new Socket();
s.connect(new InetSocketAddress("10.116.123.112", 6526));
InputStream stream = s.getInputStream();
// use thread read data

解析:设置了超时时间为10s:

socket.connect(new InetSocketAddress(ip, port), 10000);


48(多选题)如下代码会陷入死循环的有( AD)

A.

int end = Integer.MAX_VALUE;
int start = end - 50;
int count = 0;
for (int i = start; i <= end; i++) {
count++;
System.out.println("本次循环次数为:" + count);
}

B.

for(byte i, pre = i = -128; i < 128 && i >= pre; pre = i, i++) {
System.out.println(i);
}

C.

int i = 10;
for(; i >= 0; --i){
System.out.println(i);
i -= 3;
}


D.

for(byte i = -128; i < 128; i++) {
System.out.println(i);
}

解析:byte取值范围为-128~127


47(多选题)根据Java编程规范,以下哪些选项序列化实现有安全问题,其中x、y是敏感信息( AD )

A.

public class Data implements Serializable {
// 假设已显式声明serialVersionUID
private double x;
private double y
private String id;

B.

public class Data implements Serializable {
// 假设已显式声明serialVersionUID
private transient double x;
private transient double y;
private String id;

C.

public class Data implements Serializable {
// 假设已显式声明serialVersionUID
private double x;
private double y;
private String id;
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("id", String.class)
};

D.

public class Data implements Serializable {
// 假设已显式声明serialVersionUID
private volatile double x;
private volatile double y;
private String id;

解析:


在序列化时类的哪些字段会参与到序列化中呢?其实有两种方式决定哪些字段会被序列化,

  1. 默认方式,Java对象中的非静态和非transient的字段都会被定义为需要序列的字段。
  2. 另外一种方式是通过 ObjectStreamField 数组来声明类需要序列化的对象。


46(单选题)当micro.yaml文件不存在时,关于如下代码段的输出描述正确的是( A )

public class FileParse {
public static String MICROSERVICEFILE =
FileParse.class.getClassLoader().getResource("micro.yaml").getPath();
}

public class Main {
public static void main(String[] args) {
try {
System.out.println(FileParse.MICROSERVICEFILE);
} catch (Exception e) {
System.out.printf("exception stack");
e.printStackTrace();
}
System.out.println("finish");
}
}

A.

运行后控制台既不会输出exception stack字符串也不会输出finish字符串。

B.

运行后控制台会输出exception stack字符串和finish字符串。

C.

运行后控制台会输出finish字符串,但是不会输出exception stack字符串。

D.

无法确定。

解析:

运行出错:抛异常空指针

45(多选题)下列有关Lambda表达式的使用,说法正确的有( AC )

class LambdaTest {
static final int MAX_COUNT = 1;
static final int EXEC_COUNT = 2;
static void lambdaIncrease(List<Integer> list, int step) {
list.forEach((i) -> {
i = i + step;
// other handle
});
}
static void normalIncrease(List<Integer> list, int step) {
for (Integer i : list) {
Integer elem = i + step;
// other handle
}
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(MAX_COUNT);
for (int i = 0; i < MAX_COUNT; i++) {
list.add(i);
}
		for (int i = 0; i < EXEC_COUNT; i++) {
LambdaTest.lambdaIncrease(list, 1);
LambdaTest.normalIncrease(list, 1);
		}
}

A.

理论上,main函数中首次调用 LambdaTest.lambdaIncrease(list, 1) 比 LambdaTest.normalIncrease(list, 1) 耗时长

B.

理论上,main函数中首次调用 LambdaTest.lambdaIncrease(list, 1)比 LambdaTest.normalIncrease(list, 1) 耗时短

C.

理论上,第一次调用 LambdaTest.lambdaIncrease(list, 1) 比第二次LambdaTest.lambdaIncrease(list, 1)耗时长

D.

理论上,第一次调用 LambdaTest.lambdaIncrease(list, 1) 相比第二次LambdaTest.lambdaIncrease(list, 1)耗时无明显差别


44(多选题)以下关于Set的各种实现描述中,哪些是正确的(AB)

A.

HashSet、LinkedHashSet中可以存储null值,而TreeSet不可以

B.

在对Set做添加和删除时,TreeSet的时间复杂度比HashSet和LinkedHashSet都高

C.

TreeSet是线程安全的,LinkedHashSet和HashSet都不是线程安全的

D.

HashSet、LinkedHashSet和TreeSet的底层实现数据结构都包含哈希表


43(单选题)断两个浮点数是否相等,以下哪种方式正确( C )

A.

使用==

B.

使用Float或者Double类型的equals方法

C.

使用BigDecimal判断是否相等

D.

判断差值的绝对值是否小于极小值(必须为1e-4f)


42(多选题)以下关于Streams和集合的代码,哪些选项实现了注释中描述的功能( ACD )

A.

// int[] 转 String[]
int[] nums = {1, 2, 3};
String[] strs = Arrays.stream(nums).mapToObj(String::valueOf).toArray(String[]::new);

B.

// int[] 转 List<Integer>
int[] arr = {1, 2, 3};
List<Integer> list = Arrays.asList(arr);

C.

// int[] 追加到 Set<Integer>
int[] nums = {1, 1, 2};
Set<Integer> set = new TreeSet<>();
// ......
set = new HashSet<>();
Arrays.stream(nums).forEach(set::add);

D.

// String[] 转 Set<String>
String[] strs = {"a", "b", "c"};
Set<String> set = new HashSet<>(Arrays.asList(strs));

50(多选题)以下可能造成死锁的代码有(ABCD)

A.

public class LeftRightLock {
private final Object left = new Object();
private final Object right = new Object();
public void functionA() {
synchronized (left) {
synchronized (right) {
doSomething();
}
}
}
public void functionB() {
synchronized (right) {
synchronized (left) {
doSomething();
}
}
}
……

B.

public void transferMony(Account fromAccount, Account toAccount, int amount) {
synchronized (fromAccount) {
synchronized (toAccount) {
fromAccount.debit(amount);
toAccount.credit(amount);
}
}
}

C.

public class Taxi {
private Point location;
private Point destinztion;
private final Dispatcher dispatcher;
public Taxi(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
public synchronized Point getLocation() {
return location;
}
public synchronized void setLocation(Point location) {
this.location = location;
if (this.location.equals(destinztion)) {
dispatcher.notifyAvailable(this);
}
}
……
}
public class Dispatcher {
private final Set<Taxi> taxis = new HashSet<>();
private final Set<Taxi> availableTaxis = new HashSet<>();
public synchronized void notifyAvailable(Taxi taxi) {
availableTaxis.add(taxi);
}
public synchronized Image getImage() {
final Image image = new Image();
for (final Taxi taxi : taxis) {
image.drawMarket(taxi.getLocation());
}
return image;
}

D.

private final ExecutorService executor = Executors.newSingleThreadExecutor();
public void renderPage() throws InterruptedException, ExecutionException {
	Future<String> page = executor.submit(new RenderPageTask());
	frame.set(page.get());
}
public class RenderPageTask implements Callable<String> {
	@Override
	public String call() throws Exception {
		final Future<String> header = 
executor.submit(new LoadFileTask("head.html"));
		final Future<String> foot = 
executor.submit(new LoadFileTask("foot.html"));
		return header.get() + "page" + foot.get();
	}

51(多选题)根据Java语言编程规范,下面关于方法的描述哪些是错误的(AD)

A.避免方法过长,不超过30行 //50

B.不要把方法的入参当做工作变量/临时变量

C.使用类名调用静态方法,而不要使用实例或表达式来调用

D.避免方法的代码块嵌套过深,不要超过5层//不是方法

52(单选题)下列代码存在什么安全风险(A )

public static int cardinality(Object obj, final Collection<?> col) {
int count = 0;
if (col == null) {
return count;
}
Iterator<?> it = col.iterator();
while (it.hasNext()) {
Object elt = it.next();
if ((null == obj && null == elt) || obj.equals(elt)) {
count++;
}
}
return count;
}

A.空指针引用

B.内存泄露

C.内存溢出

D.无安全风险

53(多选题)以下哪些场景需要将对象进行密封和数字签名来保证数据安全(ABCD)

A.序列化敏感数据

B.传输敏感数据

C.非类似SSL通信传输通道

D.敏感数据持久化保存


54(多选题)如下哪些数据类型有常量NaN(Not-a-Number)(AB)

A.Float

B.Double

C.Integer

D.BigDecimal


55(多选题)下面的哪些语句存在编译错误?(BC)

A.

long l = 499;

B.

int i = 4L;

C.

float f = 1.1;

D.

double d = 34.4;


56
(多选题)在Java8默认配置情况下,针对以下两段程序的运行结果,正确的说法有(AB)

程序1:

public class Test {
    public static void main(String[] args) {
        test(1L);
    }
    private static void test(Long count) {
        Long next = count + 1;
        System.out.println(next);
        test(next);
    }
}

 程序2:

public class Test {
    public static void main(String[] args) {
        test(1L);
    }
    private static void test(long count) {
        long next = count + 1;
        System.out.println(next);
        test(next);
    }
}

A.程序1与程序2均将以抛出StackOverflowError异常结束

B.程序1最后一行打印出的数字较大

C.程序2最后一行打印的数字较大

D.程序1和程序2最后一行打印的数字一样大

E.程序1和程序2均不会打印出数字

 57(多选题)以下关于Full GC和Minor GC描述正确的有(CD)

A.Full GC不对MetaSpace进行GC。

B.GC调优是追求消除Major GC和Minor GC。

C.性能优化的三个指标:吞吐量、延迟、内存占用。

D.JVM垃圾收集三个基本原则:

Minor GC回收对象最多原则、GC内存最大化原则、GC调优(吞吐量、延迟、内存占用)的3选2原则。

59(单选题)关于java中调用外部进程的说法中,错误的是(B )

A.外部程序运行时由java.lang.Process对象描述。这个对象包含一个输入流,输出流,以及一个错误流。

B.外部进程的输出流是一个OutputStream对象,可以通过Process的静态方法getOutputStream获取。

C.一个外部进程如果试图从一个空的输入流中读取输入,则会一直阻塞,直到为其提供输入。

D.一个外部进程的输出可能会耗尽该进程输出流与错误流的缓冲区。当发生这种情况时,Java 程序可能会阻塞外部进程,同时阻碍Java程序与外部程序的继续运行。

 

58(单选题)根据Java语言编程规范,下面对创建的具有输出流和错误流的进程的处理,正确的是(D )

A

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
int exitVal = proc.exitValue();

  B 

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
int exitVal = proc.waitFor();

 C 

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), System.err);
errorGobbler.start();
int exitVal = proc.waitFor();

 D

Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("notemaker");
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), System.err);
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), System.out);
errorGobbler.start();
outputGobbler.start();
 
int exitVal = proc.waitFor();

65(单选题)以下不属于运行时异常的是哪个(D)

A.IllegalArgumentException
B.NullPointerException
C.IndexOutOfBoundsException
D.SQLException


64(多选题)关于JUnit4描述正确的有(CD)

A.@Test注解标注的测试方法只能是public void的,且不能有任何输入参数
B.AssertEquals、AssertNotEquals:判断两个对象是否为同一个
C.@BeforeClass方法必须为static void
D.@Before方法不能是private方法


63(单选题)以下代码执行结果是:(A)

  1. package com.huawei;
  1. public class Bean {
  2. private String id;
  3. private String name;
  4. public Bean(String id, String name) {
  5. this.id = id;
  6. this.name = name;
  7. }
  8. public String getId() {
  9. return id;
  10. }
  11. public void setId(String id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. @Override
  21. public String toString() {
  22. return "java Bean{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}';
  23. }
  24. }
  25. package com.huawei;
  26. public class TestReflect {
  27. private static TestReflect bf = new TestReflect();
  28. private TestReflect() {
  29. }
  30. public static TestReflect getFactory() {
  31. return bf;
  32. }
  33. public static void main(String[] args) throws Exception {
  34. try {
  35. Bean bean = TestReflect.getFactory().newInstance(Bean.class);
  36. bean.setId("888");
  37. bean.setName("Huawei");
  38. System.out.println(bean);
  39. } catch (ClassNotFoundException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. public <T> T newInstance(Class<T> clazz) throws ClassNotFoundException{
  44. String clmplName = "com.huawei.Bean";
  45. try {
  46. return (T) Class.forName(clmplName).newInstance();
  47. } catch (InstantiationException e) {
  48. throw new ClassNotFoundException("", e);
  49. } catch (IllegalAccessException e) {
  50. throw new ClassNotFoundException("", e);
  51. }
  52. }
  53. }
A.抛出ClassNotFoundException异常
B.编译报错
C.java Bean{id='888', name='Huawei'}
D.java Bean{id='null', name='null'}


62(单选题)对一个具有1000000个元素的整型数组,其中没有重复值,判断其中的元素有没有被访问过,我们可以怎么做更高效(A )

A.用一个等长的boolean[]数组来表示每一个元素是否被访问过
B.用HashMap<Integer, Boolean>来表示每一个元素是否被访问过
C.用Set 来存储被访问过的值,用set.contains(key) 来判断 key是不是被访问过
D.其它做法都可以,用时是相等的


61(单选题)以下关于Java原语wait、notify和 notifyAll, 正确的是(C )

A.在同步块外使用wait(timeout), 其效果和sleep(timeout)是一样的
B.notifyAll唤醒了所有因wait等待的线程,这些线程将并发执行
C.notifyAll消耗的CPU资源比notify多
D.进入wait状态的线程,只可能被notify或者notifyAll唤醒


60(单选题)根据Java编程规范,这段代码违反了哪个条目(C )

public static List<String> decorate(String[] personDescs) {
    if (personDescs == null || personDescs.length == 0) {
        return null;
    }
    List<String> personNames = new ArrayList<>(personDescs.length);
    for (String personDesc : personDescs) {
        String personName = getPersonName(personDesc);
        if (personName != null && personName.length() != 0) {
            personNames.add(personName);
        }
    }
    return personNames;
}


public static void main(String[] args) {
    // Do something here.
    List<String> personNames = decorate(personDescs);
    if (personNames == null) {
        return;
    }
    for (String personName : personNames) {
        // Do something here.
    }
}

A.使用类名调用静态方法,而不要使用实例或表达式来调用

B.方法的代码块不要嵌套过深,不能超过4层

C.当返回类型为数组或者容器时,应返回长度为0的数组或者容器

D.personName变量需要判断是否为null

67 在默认JVM配置下,如下代码1/2/3处分别输出什么

解析:
1. Integer取值在-128~127范围内时 , 可以用  "==" 比较是否相等 . 因为 "==" 比较的对象地址的引用 , 又因为在这个范围内, 是在常量池中取的值 , 并没有重新的new对象 , 所以是可以用 "==" 比较.
当大于这个范围后就会重新new对象 , 所以比较两个Integer是否相等就需要用compareTo .
2.如果两个int 类型的数值比较相等可以直接使用  "==" .
3. integer与int类型数据比较会自动将integer类型拆箱成int类型比较
68、关于Thread类提供的线程控制方法,下列说法错误的是(D)
A、通过调用interrupt()方法来中断线程的阻塞状态
B、currentThread()方法返回当前线程的引用
C、线程A中执行线程B的join()方法,则线程A等待知道B执行完成
D、若线程A调用方法isAtive()返回值为false,则说明A正在执行中,也可能是可运行状态
69、以下关于在foreach循环里删除元素的描述,正确的有(ABC)
A、使用Collection中的removeIf方法,更加简洁可靠
B、在foreach循环里进行元素的remove、add操作,易发生并发修改异常
C、通过Iterator删除是优选的
70 针对Thread.sleep、Object.wait和监视器锁,以下说法正确的是()B

A.Thread.sleep(long millis):线程进入计时等待状态,释放锁;Object.wait():线程进入阻塞状态,释放锁

B.Thread.sleep(long millis):线程进入计时等待状态,持有锁;Object.wait();线程进入等待状态,释放锁

C.Thread.sleep(long millis):线程进入等待状态,释放锁;Object.wait():线程进入阻塞状态,持有锁

D.Thread.sleep(long millis):线程进入阻塞状态,持有锁,Object.wait():线程进入等待状态,持有锁

71对一个数据集合进行遍历,下面说法错误的是: A

A.使用普通for循环遍历,ArrayList和LinkedList的性能是一样的

B.ArrayList是基于数组实现,使用下标循环遍历的性能最好

C.for-each最终是依赖迭代器iterator实现的,因此必须实现了iterable接口的集合实现类才能使用

D.在for循环里执行删除元素的操作可能会报ConcurrentModificationExeption异常,例如如下代码:

for(String obj:strList){
if("Apple".equals(obj)){
strList.remove(obj)
}
}
72  以下有关Arrays.asList(T...data)方法说法哪些是正确的?ABC

A.若调用该返回对象的add/remove方法则会抛出UnsupportedOperationException异常

B.可调用返回的ArrayList对象subList方法获得子列表

C.返回的ArrayList对象是不可变的

D.返回的是javautil.ArrayList对象

73 下列说法正确的有() AC

A.两个对象根据equals(Object)方法是相等的,那么调用两个对象的hashCode方法必须产生同样的整数

B.两个对象根据equals(Object)方法是相等的,那么调用两个对象的hashCode方法可以产生不同的整数

C.如果两个对象根据equals(Object)方法是不相等的,那么调用两个对象的hashCode方法,不要求必须产生不同的整数

D.如果两个对象根据equals(Object)方法是不相等的,那么调用两个对象的hashCode方法,必须产生不同的整数

74 关于JUnit4描述正确的有()BC

A.@Before方法不能是private方法

B.AssertEquals、AssertNotEquals:判断两个对象是否为同一个

C.@Test注解标注的测试方法只能是public void的,且不能有任何输入参数

D.@BeforeClass方法必须为static void

75、频繁主动GC可能导致如下那些问题 ABC



1、关于测试分层,下列说法错误的是()

答案:测试分层先测试上层,减少了遗漏到下层的问题数

 

 

2、针对以下代码 ```java ```

class BaseColor {
    
public void showMessage() {
        System.
out.println("I am BaseColor.");
    
}
}
class BaseBlue extends BaseColor {
    
public void showMessage() {
        System.
out.println("I am BaseBlue.");
    
}
}
public class BaseYellow {
    
private BaseColor objA;
    public 
BaseYellow(BaseColor obj) {
        
objA = obj;
    
}
    
public void showMessage() {
        
objA.showMessage();
    
}
    
public static void main(String[] args) {
        BaseColor objA = 
new BaseColor(); // 语句1        
        
BaseYellow objC = new BaseYellow(objA);        
        
objC.showMessage();     } }
       
    }
}

  以下说法错误的是( ",

答案:如果把语句1改成 BaseColor objA = new BaseBlue();输出结果也是 I am BaseColor."

 

 

3、下面的代码片段是把资金从一个账户转到另一个账户,多线程调用transferMoney方法转账。下面说法正确的是( 

public class AccountService {
    
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount amount) throws InsufficientFundsException {
        
synchronized (fromAccount) {
            
synchronized (toAccount) {
                
if (fromAccount.getBalance().compareTo(amount) < 0) {
                    
throw new InsufficientFundsException();
                
} else {
                    fromAccount.debit(amount)
;
                    
toAccount.credit(amount);
                
}
            }
        }
    }
}

 答案:传入Account参数顺序不固定,可能会发生死锁

 

 

4、执行下面代码后,控制台输出的是什么( ) 

public class Main {
    
private static class Fruit {
        
public void printName(String name) {
            System.
out.println("Fruit-" + name);
        
}
        
public void printName(Object name) {
            System.
out.println("Fruit-Object-" + name);
        
}
    }
    
private static class Apple extends Fruit {
        
public void printName(String name) {
            System.
out.println("Apple-" + name);
        
}
    }
    
public static void main(String[] args) {
        Fruit fruit = 
new Apple();
        
Object obj = "test";
        
fruit.printName(obj);
        
fruit.printName("test");
    
}
}

答案:Fruit-Object-test    Apple-test

 

 

5、关于JVM GC finalize() 方法说明,哪项是错误的( 

答案:finalize()方法在对象离开作用域的时候被调用。

 

6、下列程序的输出结果是( 

int num = 2;
switch
(num) {
    
case 1:
        System.
out.println("The input is 1");        
        
// $FALL-THROUGH$    
    
case 2:
        System.
out.println("The input is 2");        
        
// $FALL-THROUGH$    
    
case 3:
        System.
out.println("The input is 3");        
        
// $FALL-THROUGH$    
    
default:
        System.
out.println("Bad input");
}

 答案:The input is 2 The input is 3 Bad input

 

7、执行如下测试类,输出结果是()

public class SampleTest {
    @BeforeClass
    
public static void beforeClass() {
        System.
out.println("BeforeClass");
    
}
    
@Before
    
public void setUp() {
        System.
out.println("Before");
    
}
    
@After
    
public void tearDown() {
        System.
out.println("After");
    
}
    @AfterClass
    
public static void afterClass() {
        System.
out.println("AfterClass");
    
}
    @Test
    
public void firstCase() {
    }
    @Test
    
public void secondCase() {
    }
}

答案:BeforeClass Before After Before After AfterClass"

                  

8、JVM GC性能指标”吞吐量“是指:()

答案:吞吐量是CPU运行用户代码的时间 CPU总消耗时间的比值。

 

 

9、以下从ZipInputStream中解压文件时的做法可能会导致安全问题的是()

答案:仅调用ZipEntry.getSize()方法判断解压文件大小

 

10、下面的程序运行结果为(  

public class Foo {
    
public static void main(String[] args) {
        
try {
            
return;
        
} finally {
            System.
out.println("Finally");
        
}
    }
}

答案:打印出 Finally

 

11、根据以下字节码信息,下列哪个说法错误(  ```java   minor version: 0   major version: 52   flags: ACC_PUBLIC, ACC_SUPER Constant pool:    #1 = Methodref          #4.#18           #2 = Fieldref           #3.#19            #3 = Class              #20               #4 = Class              #21              #5 = Utf8               age    #6 = Utf8               I    #7 = Utf8               <init>    #8 = Utf8               ()V    #9 = Utf8               Code   #10 = Utf8               LineNumberTable   #11 = Utf8               LocalVariableTable   #12 = Utf8               this   #13 = Utf8               Lcom/huawei/exam/Person;   #14 = Utf8               getAge   #15 = Utf8               ()I   #16 = Utf8               SourceFile   #17 = Utf8               Person.java   #18 = NameAndType        #7:#8          // \"<init>\":()V   #19 = NameAndType        #5:#6          // age:I   #20 = Utf8               com/huawei/exam/Person   #21 = Utf8               java/lang/Object ```",

答案:该类有一个init方法

 

12、如下代码的输出结果是()

 public class AtomicDemo {
    
private static int[] value = new int[]{1, 2, 3};
    private static 
AtomicIntegerArray integerArray = new AtomicIntegerArray(value);
   
    public static void 
main(String[] args) {
        
int result = integerArray.getAndAdd(1, 5);
        
System.out.printf("%d %d", integerArray.get(1), result);
    
}
}

 答案:7 2

 

13、执行以下代码输出的结果是:

class Main {
    
public static void main(String[] args) {
        
int count = 0;
        for 
(int i = 0; i < 100; i++) {
            count = count++
;
        
}
        System.
out.println(count);
    
}
}

答案:0             

 

14、执行如下哪个选项,不可能触发JVMGC()

答案:java Runtime.getRuntime().freeMemory();

 

15、执行下面代码后,控制台输出的是什么( 

private interface Visitor {
    
void visit(BinaryTree binaryTree);
   
    void 
visit(MultiwayTree multiwayTree);
}
private static class BFSVisitor implements Visitor {
    
public void visit(BinaryTree binaryTree) {
        System.
out.println("BFSVisitor-BinaryTree visit");
    
}
   
    
public void visit(MultiwayTree multiwayTree) {
        System.
out.println("BFSVisitor-MultiwayTree visit");
    
}
}
private static class DFSVisitor implements Visitor {
    
public void visit(BinaryTree binaryTree) {
        System.
out.println("DFSVisitor-BinaryTree visit");
    
}
    
    
public void visit(MultiwayTree multiwayTree) {
        System.
out.println("DFSVisitor-MultiwayTree visit");
    
}
}
private interface Tree {
    
void invoke(Visitor visitor);
}
private static class BinaryTree implements Tree {
    
public void invoke(Visitor visitor) {
        visitor.visit(
this);
    
}
}
private static class MultiwayTree implements Tree {
    
public void invoke(Visitor visitor) {
        visitor.visit(
this);
    
}
}
public static void main(String[] args) {
    List<Tree> treeList = Arrays.asList(
new BinaryTree(), new MultiwayTree());
    
List<Visitor> visitorList = Arrays.asList(new BFSVisitor(), new DFSVisitor());
    
treeList.forEach(tree -> visitorList.forEach(tree::invoke));
} 

 答案:BFSVisitor-BinaryTree visit

DFSVisitor-BinaryTree visit

BFSVisitor-MultiwayTree visit

DFSVisitor-MultiwayTree visit

              

16、在默认JVM配置下,如下代码在1/2/3处分别输出什么( 

Integer value1 = 100;
Integer value2 = 100;
Integer value3 = 150;
Integer value4 = 150;
System.out.println(value1 == value2); // 1
System.out.println(value3 == value4); // 2
System.out.println(value3 == 150); // 3

答案:true/false/true

 

17、对于下面的代码片段,假设PasswordManager的实例可以被非信任代码所访问,且changePassword()方法调用属于敏感操作,则下列说法中不正确的是?

public class PasswordManager {
    
public final Object lock = new Object();
    public void 
changePassword() throws FileNotFoundException {
        
synchronized (lock) {             
            
// . . .  
        
}
    }
}

答案:这段代码没有安全风险

 

18、根据编程规范,如下对方法的描述,哪一项是错误的( 

答案:对于返回数组或者容器的方法,应返回null,再在上层调用代码里对返回值判空

 

19、以下程序运行结果是( 

class TestClass {
    
public TestClass() {
        
throw new IllegalArgumentException("illegalArgumentException!");
    
}
    
public void print() {
        System.
out.println("ABC");
    
}
}
public class Instance {
    
public static void main(String[] args) {
        
try {
            TestClass testClass = (TestClass) Class.forName(
"com.huawei.TestClass").newInstance();
            
testClass.print();
        
} catch (IllegalAccessException e) {
            e.printStackTrace()
;
        
} catch (ClassNotFoundException e) {
            e.printStackTrace()
;
        
} catch (InstantiationException e) {
            e.printStackTrace()
;
        
}
    }
}

答案:抛IllegalArgumentException异常,运行中止

 

20、关于下面代码,下列选项中说法正确的是?

final int limit = 5;
Map<Integer, String> map = new LinkedHashMap(16, 0.75f, true) {
    
protected boolean removeEldestEntry(Map.Entry eldest) {
        
return size() > limit;
    
}
}
;
for 
(int i = 0; i < 10; i++) {
    map.put(i
, String.valueOf(i));
}
String v = map.get(
6);
map.keySet().forEach(System.out::print);

答案:代码运行后,控制台打印57896

 

21、读下面的代码,请选择正确的输出(代码不考虑编程规范的约束)( ) 

public class Demo<T> {
    
public static int myConst = 10;
    public void 
increase(T param, int input) {
        System.
out.println(input + myConst);
    
}
    
public static void main(String[] args) {
        Demo<String> obj1 = 
new Demo<>();
        
obj1.myConst = 10;
        
obj1.increase("input", 10);
        
Demo<Integer> obj2 = new Demo<>();
        
obj2.myConst = 20;
        
obj2.increase(20, obj1.myConst);
        
Demo<HashMap<String, String>> obj3 = new Demo<>();
        
obj3.myConst = 30;
        
obj3.increase(new HashMap<>(), obj2.myConst);
    
}
}

答案:20\40\60

 

22、当线程调用start()后,其所处状态为( )。

答案:就绪状态

 

23、如下代码运行结果是( 

public class Test {
    
public static void main(String[] args) {
        List<String> list = 
new ArrayList<>();
        
list.add("str1");
        
list.add(2, "str2");
        
String str = list.get(1);
        
System.out.println(str);
    
}
}

答案:运行时出现异常

 

24、根据编程规范,为什么要求一个局部变量只表达一种含义?

答案:前后表达不同的含义,不利于代码理解

 

25、下列程序calc()方法的返回值是?

public class Test {
    
private static final int TENK = 10000;
    private static long 
count = 0;
    private void 
add10K() {
        
int idx = 0;
        while 
(idx++ < TENK) {
            
count += 1;
        
}
    }
    
public static long calc() throws InterruptedException {
        
final Test test = new Test();         // 创建两个线程,执行 add() 操作        
        
Thread th1 = new Thread(test::add10K);
        
Thread th2 = new Thread(test::add10K);         // 启动两个线程        
        
th1.start();
        
th2.start();         // 等待两个线程执行结束        
        
th1.join();
        
th2.join();
        return 
count;
    
}
}

答案:1000020000之间的任意数

 

26、运行下列代码,实际的输出结果是什么?

public class Animal {
    
public static void testClassMethod() {
        System.
out.println("The static method in Animal");
    
}
    
public void testInstanceMethod() {
        System.
out.println("The instance method in Animal");
    
}
}
public class Cat extends Animal {
    
public static void testClassMethod() {
        System.
out.println("The static method in Cat");
    
}
    
public void testInstanceMethod() {
        System.
out.println("The instance method in Cat");
    
}
    
public static void main(String[] args) {
        Animal myAnimal = 
new Cat();
        
myAnimal.testClassMethod();
        
myAnimal.testInstanceMethod();
    
}
}

答案:The static method in Animal The instance method in Cat"

                  

27、无论发生多少异常,“try”块的哪一部分总是会执行?

答案:finally

 

28、在使用UDP套接字通信时,常用( )类把要发送的信息打包。

答案:DatagramPacket

 

29、下列有关Map操作错误的是:

答案:cityMap是一个合法的Map Map<Integer, String> unmodifiableMap = Collections.unmodifiableMap(cityMap); unmodifiableMap.clear(); ```"

                   

30、以下代码的结果正确的是:

class Swan {
    
static String msg = "swan can fly ...";
    public static void 
fly() {
        String msg = 
"swan can not fly ...";
        
System.out.println(msg);
    
}
}
class UglyDuck extends Swan {
    
static String msg = "ugly duck can fly ...";
    public static void 
fly() {
        String msg = 
"ugly duck can't fly ...";
        
System.out.println(msg);
    
}
}
public class TestFly {
    
public static void main(String[] args) {
        Swan swan = 
new Swan();
        
Swan uglyDuck = new UglyDuck();
        
swan.fly();
        
uglyDuck.fly();
    
}
}

答案:swan can not fly … swan can not fly …

 

31、如下代码执行结果是:

public class Foo {
    
public static void main(String[] args) {
        
for (float flt = (float) 1000000000; flt < 1000000010; flt++) {
            System.
out.println(flt);
        
}
    }
}

答案:精度问题会导致循环出现不可预期的运行结果

 

32、有以下一段代码:

public class PrintCollection {
    
public void print(List<String> collection) {
        Collections.sort(collection
, (s1, s2) -> s1.compareTo(s2));
        
collection.stream().forEach(System.out::println);
    
}
    
public static void main(String[] args) {
        List<String> list1 = Arrays.asList(
"4", "3", "2", "1");
        
PrintCollection printer = new PrintCollection();
        
printer.print(list1);
    
}
}

 请问使用以下哪条命令编译无编译错误?",

答案:javac -source 8 -Xlint:all PrintCollection.java

 

 

33、如下Java程序的输出结果是( 

public class Main {
    
static String[] split(String s) {
        
return s.split("$");
    
}
    
public static void main(String[] args) {
        String[] r = split(
"a$b$c");
        
System.out.println(Arrays.toString(r));
    
}
}

答案:[a$b$c]

 

34、某产品生产环境出现请求响应慢、Java进程CPU占用过高的现象,如下定位措施说法错误的是(  )",

答案:通过`jmap`日志查看线程对应的内存使用情况,定位出哪个线程可能由于频繁读写内存问题(数据量小)进而导致CPU占用过高且消耗CPU时间短。

 

35、如下代码的输出是()

class Base {
    
public int id = 100;
    public void 
doSomething() {
        System.
out.println("Base");
    
}
}
public class Child extends Base {
    
public int id = 101;
    
@Override
    
public void doSomething() {
        System.
out.println("Child");
    
}
    
public static void main(String[] args) {
        Base base = 
new Child();
        
System.out.println(base.id);
        
base.doSomething();
    
}
}

答案:100 Child

 

36、针对Thread.sleepObject.wait和监视器锁,以下说法正确的是()",

答案:Thread.sleep(long millis):线程进入计时等待状态,持有锁;Object.wait():线程进入等待状态,释放锁"

 

37、以下不属于运行时异常的是哪个?()

答案:SQLException

 

38、JAVA堆内存分为年轻代、年老代和永久代,minor GC主要发生在哪里?",

答案:年轻代

 

39、执行如下代码片段,变量str2的结果是() ```Java String str = \"123\"; String str2 = str + 456; ```",

答案:123456

 

40、进程频繁GC,主要使用以下哪种工具进行问题定位和分析?",

答案:jstat

 

41、工程师小明在实现一个业务系统,系统需求为实现一个任务(单一任务,无依赖关系),此任务对输入的数据进行处理,处理后将结果写入数据库,任务的调度频率不确定,现在需要对这个任务创建一批线程进行调度,下面哪一项是最佳的实现方法( ",

答案:直接使用ThreadPoolExecutor来合理规划线程资源,用线程池来调度任务"

                 

42、下面程序的输出是:

int count1 = 0;
for 
(int rowNum = 0; rowNum < 3; rowNum++) {
    
for (int colNum = 0; colNum < 4; colNum++) {
        
if (colNum % 2 == 1) {
            
continue;
        
}
        count1++
;
    
}
}
int count2 = 0;
for 
(int rowNum = 0; rowNum < 3; rowNum++) {
    
for (int colNum = 0; colNum < 4; colNum++) {
        
if (colNum % 2 == 1) {
            
break;
        
}
        count2++
;
    
}
}
System.
out.println(count1 + "," + count2);

答案:63

 

43、如下代码输出结果为()

public class Email {
    
public String address;
    public 
Email(String address) {
        
this.address = address;
    
}
    
public int hashCode() {
        
return address.hashCode();
    
}
    
public static void main(String[] args) {
        HashSet<Email> set = 
new HashSet<>();
        
Email email = new Email("huawei.com");
        
set.add(email);
        
email.address = "silong.com";
        
System.out.println(set.contains(email));
    
}
}

答案:false

 

44、执行以下代码,将会打印() 

interface MyFunction extends Function<Object, String> {
}
public class Example {
    
public static void main(String[] args) {
        consume((Function<Object
, String>) Object::toString);
        
consume((MyFunction) Object::toString);
        
consume(Object::toString);
        
consume(null);
    
}
    
private static void consume(Function<Object, String> mapping) {
        System.
out.println("jdk mapping");
    
}
    
private static void consume(MyFunction mapping) {
        System.
out.println("my mapping");
    
}
}

答案:jdk mapping

my mapping

my mapping

my mapping ```"

                   

45、下列有关异常泄露敏感信息的描述正确的有(ABD

A抛出信任域外的异常的类型信息可能导致敏感信息泄露"

B将异常抛出信任域外时,若未对敏感信息进行过滤将导致信息泄露并有助于攻击者发起进一步的攻击"

C将一个包含敏感信息的异常包装在一个非敏感异常中再抛出可以防止敏感信息泄露"

D抛出信任域外的异常中包含的文本信息,可能导致敏感信息泄露"

                

46、关于JUnit4描述正确的有(BC

A @Test注解标注的测试方法只能是public void的,且不能有任何输入参数"

B @Before方法不能是private方法

C @BeforeClass方法必须为static void

D AssertEqualsAssertNotEquals:判断两个对象是否为同一个"

                  

47、线程安全的Map有哪些?BD

A java.util.WeakHashMap

B java.util.concurrent.ConcurrentSkipListMap"

C java.util.LinkedHashMap

D java.util.concurrent.ConcurrentHashMap

 

48、如下哪些数据类型有常量NaNNot-a-Number)(AB 

A Double

B Float

C Integer

D BigDecimal

 

49、对于如下`jstack`的操作,哪些选项说法正确  ```java \"Thread-1\" #13 prio=5 os_prio=0 tid=0x00000000290db800 nid=0x2f04 waiting for monitor entry [0x0000000029bee000]    java.lang.Thread.State: BLOCKED (on object monitor)         at com.huawei.main.lambda$main$1(main.java:38)         - waiting to lock <0x0000000716be30c8> (a java.lang.StringBuilder)         - locked <0x0000000716be3110> (a java.lang.StringBuilder)         at com.huawei.main$$Lambda$2/38997010.run(Unknown Source)         at java.lang.Thread.run(Thread.java:748)     Locked ownable synchronizers:         - None  \"Thread-2\" #12 prio=5 os_prio=0 tid=0x00000000290d6800 nid=0x354c waiting for monitor entry [0x0000000029aef000]    java.lang.Thread.State: BLOCKED (on object monitor)         at com.huawei.main.lambda$main$0(main.java:19)         - waiting to lock <0x0000000716be3110> (a java.lang.StringBuilder)         - locked <0x0000000716be30c8> (a java.lang.StringBuilder)         at com.huawei.main$$Lambda$1/897697267.run(Unknown Source)         at java.lang.Thread.run(Thread.java:748)     Locked ownable synchronizers:         - None ```",

ABCD

A线程`Thread-1`、线程`Thread-2`产生死锁的原因是:线程`Thread-1`等待线程`Thread-2`的锁对象,线程`Thread-2`等待线程`Thread-1`的锁对象,这两个线程都进入了阻塞态`BLOCKED`,从而产生了死锁。"

B死锁产生的四个条件:互斥使用,不可抢占,请求和保持,循环等待。通过`jstack`日志确认产生死锁的原因,修改代码达到破坏这四个条件之一,即可解决死锁问题。"

C `Thread-1``Thread-2`表示线程名,`prio`表示该线程在JVM中的线程优先级、`os_prio`表示该线程在操作系统中的线程优先级,`tid`表示该线程在JVM中的线程id`nid`表示该线程在操作系统中的线程id"

D JVM中线程状态包括`NEW``RUNNABLE``BLOCKED``WAITING``TIMED_WAITING``TERMINATED`,以上两个线程的状态为`BLOCKED`,表示这两个线程均在等待锁对象的监视锁(`monitor lock`)"

                 

50、给定以下代码,在TODO处的写法,选项中正确的有(BD 

public class TestLambda {
    
private int classValue = 1;
   
    private void 
testSetValue() {
        
final int localFinalValue = 2;
        int 
localValue = 3;
        
// TODO        
        
runnable.run();
    
}
}

A java Runnable runnable = () -> {     localFinalValue = 0; }; ```  执行上述代码,localFinalValue的值为0"

B Runnable runnable = () -> {     int classValue = 4;     this.classValue = 0; }; ```  执行上述代码,TestLambda.classValue的值为0"

C Runnable runnable = () -> {     localValue = 0; }; ```  执行上述代码,localValue的值为0"

D Runnable runnable = () -> {     classValue = 0; }; ```  执行上述代码,TestLambda.classValue的值为0"

                 

51、关于测试分层,如下描述正确的有(ABCD

A IT测试指将多个单元或多个组件/模块集成在一起进行测试。"

B UT/IT/ST是抽象的测试分层通用模型,具体测试分层怎么分、分几层与产品的规模、形态有关。比如对于规模非常小的系统,分1~2层就够了,对于规模很大的系统,可能需要分5~6层,甚至更多。"

C UT测试可以提升内部质量(软件架构质量),ST测试主要提升产品的外部质量(功能/DFX)。"

D ST可能是子系统内多个或所有组件/模块/微服务的集成测试(PCST/MST),也可能是更大粒度的全系统端到端测试(SDV/SIT/SVT)。"


 52、针对下面3个方法的输出,描述正确的有(BD )

public static void test1() {
    
int[] array = {1, 2, 3, 4};
    
System.out.println(array);
    
Arrays.stream(array).filter(item -> {
        System.
out.println(item);
        if 
(item % 2 == 0) {
            System.
out.println(item);
            return true;
        
}
        
return false;
    
});
}
public static void test2() {
    
int[] array = {1, 2, 3, 4};
    
Arrays.stream(array).filter(item -> {
        
if (item % 2 == 0) {
            System.
out.println(item);
            return true;
        
}
        
return false;
    
}).forEach(System.out::println);
}
public static void test3() {
    
int[] array = {1, 2, 3, 4};
    
Arrays.stream(array).filter(item -> {
        
if (item % 2 == 0) {
            System.
out.println(item);
            return true;
        
}
        
return false;
    
}).anyMatch(item -> {
        System.
out.println(item);
        return 
item / 2 == 2;
    
});
}

A test1()输出为: 2 4

B test3()输出为: 2 2 4 4

C test3()输出为: 4 4

D test2()输出为: 2 2 4 4

E test2()输出为: 2 4

 

53、存在两个类分别是EggBigEgg,其中BigEgg继承Egg,代码片段如下:

public class Egg {
    
class Yolk {
        
public Yolk() {
            System.
out.println("Egg.Yolk");
        
}
    }
    
public Egg() {
        
new Yolk();
    
}
}
public class BigEgg extends Egg {
    
class Yolk {
        
public Yolk() {
            System.
out.println("BigEgg.Yolk");
        
}
    }
}

 下面选项中说法正确的有( BC",

A执行new BigEgg()创建BigEgg对象则控制台打印BigEgg.Yolk"

B执行new BigEgg()创建BigEgg对象则控制台打印Egg.Yolk"

C BigEgg.YolkEgg.Yolk在不同的命名空间,两者没有直接关系"

D BigEgg.Yolk类将会自动继承Egg.Yolk

 

54、JVM中触发Full GC的条件有

正确答案为CD

A只有系统调用System.gc

B新生代Eden区满

C方法区空间不足

D老年代空间不足

 

 


====================================================================

 

 

55、于JDKJREJVM的描述,正确的是( 

答案:JDK中包含了JREJRE中包含了JVM

 

56、在\"//待插入代码\"处,插入( )的代码,可以保证Integer对象一定被垃圾收集器立即回收。

 

public class Rub {
    
private Integer i = new Integer(1);
    private 
Integer j = new Integer(2);
    private 
Integer k = new Integer(3);
   
    public static void 
main(String[] args) {
        Rub r = 
new Rub();
        
r.method();
        
// 待插入代码               
        // ……   
    
}
   
    
public void method() {
        System.
out.println(i);
        
System.out.println(j);
        
System.out.println(k);
    
}
}

答案:其他选项都不对。

 

57Java Stream在使用时,哪个操作是属于中间操作( 

答案:map()

 

58、下例程序的输出为:

 

static int calcIndex() {
    
int index = -1;
    try 
{
        index = 
10 / 0;
        
System.out.print("Calc the index.");
    
} catch (Exception e) {
        System.
out.print("Exception on calc.");
        return 
index;
    
} finally {
        index = 
0;
        
System.out.print("Recycle the resource.");
    
}
    System.
out.print("The end of test.");
    return 
index;
}

public static void main(String[] args) {
    System.
out.println("Result is " + calcIndex());
}

答案:Exception on calc.Recycle the resource.Result is -1

                   

59、以下代码片段中,GC执行时程序运行到“run at this line when GC”这一逻辑行,GC允许回收哪个对象?

 

class GcTest {
    
public static final String CONSTANT = "I am a string";
    private static 
Info staticInfo = new Info();
   
    public static void 
main(String[] args) {
        Info info = 
new Info();
        
info.doSomething();
        
info = null;
        
// run at this line when GC       
        
System.out.println("xxx");
    
}
}

class Info {
    
void doSomething() {
        System.
out.println(GcTest.CONSTANT);
    
}
}

答案:第7行分配的Info对象

 

60、以下哪个命令可以监控Java进程的gc情况

答案:jstat

 

61、根据Java语言编程规范,以下哪个选项属于可信数据( ",

答案:符合白名单校验规则的外部输入

 

62JDBC中用于调用存储过程的对象是:()

答案:CallableStatement

 

63、在Java的以下默认实现中,哪个具有同步功能( 

答案:ConcurrentHashMap

 

64、以下代码运行输出是

 

public class TestClass {
    
public static void main(String args[]) {
        
int x = 6;
        
System.out.println("value is " + ((x > 6) ? 99.9 : 9));
    
}
}

答案:value is 9.0

 

65、下面这段代码的输出结果为()

 

int fst = 5;
int 
snd = 2;
while 
(snd < fst--) {
    snd++
;
}
System.
out.print(snd);

答案:4

 

66、以下容器实现的代码,可能存在什么问题?

 

public synchronized T pop() {
    
if (size == 0) {
        
throw new EmptyStackException();
    
}
    
return elements[--size];
}

答案:内存泄漏

 

67、以下代码运行结果正确的是()

 

public static void main(String[] args) {
    List<String> tmpList = 
new ArrayList<>();
    
tmpList.add("Hello");
    
tmpList.add("My");
    
tmpList.add("Son");
    for 
(String curStr : tmpList) {
        
if ("Hello".equals(curStr)) {
            tmpList.remove(curStr)
;
        
}
        System.
out.printf("curStr = %s, tmpLIst = %s", curStr, tmpList.toString());
    
}
}

答案:运行出错抛出ConcurrentModificationException

 

68public static void tripleSalary(Employee x) {\tx.raiseSalary(200);}```

当调用以下代码时,说法正确的是

Employee harry = new Employee() ;tripleSalary(harry) ;```",

答案:harrysalary变化,虽然是按值调用(Call by value)的,但xharry引用了同一个对象。"

              

69、方法`resume()`负责恢复哪个选项涉及的线程的执行( 

答案:通过调用suspend()方法而挂起的线程。

 

70、以下代码执行结果是:

 

package com.huawei;
public class 
Bean {
    
private String id;
    private 
String name;
    public 
Bean(String id, String name) {
        
this.id = id;
        this
.name = name;
    
}
    
public String getId() {
        
return id;
    
}
    
public void setId(String id) {
        
this.id = id;
    
}
    
public String getName() {
        
return name;
    
}
    
public void setName(String name) {
        
this.name = name;
    
}
    
@Override
    
public String toString() {
        
return "java Bean{" + "id='" + id + "\'" + ", name="
                
+ name + "\'" + "}";
    
}
}
public class TestReflect {
    
private static TestReflect bf = new TestReflect();
    private 
TestReflect() {
    }
    
public static TestReflect getFactory() {
        
return bf;
    
}
    
public static void main(String[] args) throws Exception {
        
try {
            Bean bean = TestReflect.getFactory().newInstance(Bean.
class);
            
bean.setId("888");
            
bean.setName("Huawei");
            
System.out.println(bean);
        
} catch (ClassNotFoundException e) {
            e.printStackTrace()
;
        
}
    }
    
public <T> T newInstance(Class<T> clazz) throws ClassNotFoundException {
        String clmplName = 
"com.huawei.Bean";
        try 
{
            
return (T) Class.forName(clmplName).newInstance();
        
} catch (InstantiationException e) {
            
throw new ClassNotFoundException("", e);
        
} catch (IllegalAccessException e) {
            
throw new ClassNotFoundException("", e);
        
}
    }
}

答案:抛出ClassNotFoundException异常

 

71、对输入校验是良好的编程实践,可以有效降低各类安全风险。下列代码片段中,哪段代码片段可能存在风险( ",

答案:

 

public void deleteFile() {
    File someBizFile = 
new File("someFileName.txt");
    
// Do something with someFile   
    
someBizFile.delete();
}

                   

72、以下哪个函数在多线程并发条件下的实现正确并最优:

 

public class NeCache {
    
private final ConcurrentHashMap<String, Ne> neCacheMap = new ConcurrentHashMap<>();
    public 
Ne getNe1(String neId) {
        Ne rst = 
neCacheMap.get(neId);
        if 
(rst == null) {
            rst = queryNeFromDB(neId)
;
            if 
(rst != null) {
                
neCacheMap.put(neId, rst);
            
}
        }
        
return rst;
    
}
    
public Ne getNe2(String neId) {
        
final Ne rst = neCacheMap.computeIfAbsent(neId, t -> {
            
return queryNeFromDB(t);
        
});
        return 
rst;
    
}
    
public synchronized Ne getNe3(String neId) {
        Ne rst = 
neCacheMap.get(neId);
        if 
(rst == null) {
            rst = queryNeFromDB(neId)
;
            if 
(rst != null) {
                
neCacheMap.put(neId, rst);
            
}
        }
        
return rst;
    
}
    
public Ne getNe4(String neId) {
        
synchronized (neCacheMap) {
            Ne rst = 
neCacheMap.get(neId);
            if 
(rst == null) {
                rst = queryNeFromDB(neId)
;
                if 
(rst != null) {
                    
neCacheMap.put(neId, rst);
                
}
            }
            
return rst;
        
}
    }
    
private Ne queryNeFromDB(String neId) {
        
// do query form DB   
    
}
}

答案:getNe2

 

73、以下哪个选项中的对象作为同步锁是正确的( 

答案:

 

private final Object lock = new Object();
public void 
doSomething() {
    
synchronized (lock) {        // ...   
    
}
}

 

74、以下哪个方法的声明加入子类Child类中不会有编译问题( )

 

public class Parent {
    
public int calculate(int a, int b) {
        
return a + b;
    
}
}
class Child extends Parent {
}

答案:public void calculate() {...}

 

75、有以下一段代码:

 

public class Counter {
    
public static int total = 0;
    private int 
count = 0;
    public void 
incr() {
        
count += 1;
        
total += 1; // line 1   
    
}
    
public static void main(String[] args) {
        Counter counter = 
new Counter();
        
counter.incr();  // line 2       
        
System.out.println("count: " + counter.count + ", total: " + counter.total); // line 3   
    
}
}

使用如下命令进行编译时,javac -source 1.8 -Xlint:all Counter.java请问在编译时是否会产生编译告警?如果有编译告警,在哪一行产生编译告警?",

答案:在 line 3报告警

 

76、下面给出的JavaClassLoader中的描述,哪项描述是正确的( ",

ClassLoader 负责在运行时查找和装入类文件的类。"

                 

77、如下关于字符串校验的说法,哪个选项是错误的( ",

答案:

 

String str = request.getParameter("data");
Pattern pattern = Pattern.compile("[<>]");
Matcher matcher = pattern.matcher(str);
if
(matcher.find()) {
    
// Found black listed tag   
    
throw new IllegalStateException();
} else {
    
// ...
}
// Normalize
str = Normalizer.normalize(str,Form.NFKC);

以上代码可有效实现字符串的校验"

                 

78、以下代码哪个是基于NIO方式最推荐的文件读取方式?( 

答案:

 

try (FileInputStream fin = new FileInputStream("readandshow.txt");
 
FileChannel fc = fin.getChannel()) {
    ByteBuffer buffer = ByteBuffer.allocate(
1024);
    
fc.read(buffer);
} catch (FileNotFoundException e) {
    
// Exception handle
} catch (IOException e) {
    
// Exception handle
}

                 

79jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]`可显示指定Java进程的GC相关信息,如:```javajstat -gc -t -h5 9527 1000 5// 执行该命令可输出以下信息Timestamp      S0C      S1C    S0U      S1U         EC         EU        OC        OU        MC      MU    CCSC   CCSU   YGC     YGCT   FGC    FGCT     GCT    103.6  17920.0  21504.0    0.0   6257.5   245248.0   171443.2  188928.0   18126.0   38704.0 36283.4  5424.0 4845.0     5    0.027     2   0.074   0.101    104.6  17920.0  21504.0    0.0   6257.5   245248.0   171443.2  188928.0   18126.0   38704.0 36283.4  5424.0 4845.0     5    0.027     2   0.074   0.101    105.7  17920.0  21504.0   0.0    6257.5   245248.0   171443.2  188928.0   18126.0   38704.0 36283.4  5424.0 4845.0     5    0.027     2   0.074   0.101    106.7  17920.0  21504.0   0.0    6257.5   245248.0   171443.2  188928.0   18126.0   38704.0 36283.4  5424.0 4845.0     5    0.027     2   0.074   0.101    107.7  17920.0  21504.0   0.0    6257.5   245248.0   171443.2  188928.0   18126.0   38704.0 36283.4  5424.0 4845.0     5    0.027     2   0.074   0.101```以下与老年代相关的列,哪些说法正确(ABCD)

A `OC`表示老年代的大小(字节)

B `FGC``FGCT`分别表示从该Java进程启动到采样时,发生的FullGC次数、发生的FullGC的消耗时间()

C `GCT`表示从该Java进程启动到采样时,发生的所有GC消耗时间()"

D `OU`表示老年代的已使用大小(字节)

 

80、根据编程规范,以下关于equalshashCode说法正确的有(AD

A 如果两个对象调用equals方法结果相等,则这两个对象的hashCode方法返回值也必须相同"

如果两个对象调用equals方法结果不相等,则这两个对象的hashCode方法返回值必须不相同"

如果两个对象调用equals方法结果相等,则这两个对象的hashCode方法返回值可以不相同

D 如果两个对象调用equals方法结果不相等,则这两个对象的hashCode方法返回值可以不相同"

 

81"关于gradle 2.x中依赖类型示例,下列说法正确的是?ACD

A 依赖同一个project下的moduleA模块compile project(':moduleA')```"

依赖远程二进制包```javacompile group: 'org.apache.commons', module: 'commons-csv', version: '1.6'```"

C 依赖远程二进制包compile 'org.apache.commons:commons-csv:1.6'```"

D 依赖指定路径下的二进制jarcompile files('libs/foo.jar', 'libs/bar.jar')```"

 

82、如下关于性能的相关说法正确的有哪些(ABCD

A 禁止使用主动GC(除非在密码、RMI等方面),尤其是在频繁/周期性的逻辑中"        

B String s = new String(\"string\"); `存在对象重复创建,资源浪费情况"

C JavaIO操作中,尽量使用带缓冲的实现,可以降低存储介质的访问次数,从而提高数据读写的效率"

D 在将一个数组对象复制成另外一个数组对象时,可以使用Java提供的System.arraycopy()功能来复制数据对象。"

 

83、当一个自定义的类装载器要覆写getPermissions()方法的时候,如果没有调用父类的getPermissions方法来获取默认的系统规则,则(AC,

A 该自定义类加载器加载的类具有的权限,就会完全独立于系统全局策略文件规定的权限。"

除了自定义策略外,系统全局的默认安全策略也被应用。"

C 该类的权限覆盖了这些系统全局文件规定的权限。"

该类自定义的权限不会生效。

 

84minor gc运行的很频繁可能是什么原因引起的( CD

对象引用链较长,进行可达性分析时间较长

新生代空间设置过大

C 产生了太多朝生夕灭的对象导致需要频繁minor gc"

D 新生代空间设置的比较小

 

85、关于ThreadLocal,以下说法正确的有(BD

A ThreadLocal继承自Thread

B ThreadLocal保证各个线程间的数据安全,每个线程的数据不会被另外线程访问和破坏"

C ThreadLocal实现了Runnable接口

D ThreadLocal采用哈希表的方式为每个线程都提供一个变量副本"

 

86、如果输入条件规定了整型参数的范围及默认值,只用边界值分析方法,如下哪些可以作为测试数据(BCD

默认值

最小值减1

最大值和最小值

最大值加1

 

87、有关final关键字的描述,正确的有( ABCD

A 声明为final的变量在其它线程读取的时候,可以保证变量发布过程(构造函数)是原子性的"

B final作为变量的关键字,保证变量先赋值再被引用,遵循了Happens-Before原则"

C final List myList = new ArrayList(); myList.add(\"Hello\");`不会发生编译错误和运行错误"

D final方法在运行时会被JIT内联优化,这可以提高执行性能"

 

88、根据Java编程规范,在JDK8中,以下关于在foreach循环里删除元素的描述,正确的有( ABC

A 使用Collection中的removeIf方法,更加简洁可靠"

B foreach循环里进行元素的 remove/add 操作,易发生并发修改异常"

C 通过Iterator删除是优选的

50、在JUnit4中,如下Matchers#assertThat语句能执行通过的有()AC

A、assertThat("actual", not("expect"));

B、assertThat("actual", not("actual"));

C、assertThat("actual", is("actual"));

D、assertThat("actual","actual");

以下异常列表哪些属于敏感异常?(多选)
A. java.io.FileNotFoundException
B. java.net.BindException
C. java.util.ConcurrentModificationException
D. java.sql.SQLException
E. java.lang.NullPointerException
F. java.lang.IllegalArgumentException
答案解析 ABCD
以下关于异常的说法正确的是 (多选)
A. Throwable是所有Error或Exception的超类
B. 只有Exception或Exception的子类,才能被catch
C. Error是正常的应用程序已无能为力的不应该试图捕获的严重问题,如OutOfMemoryError
D. 编译器会强制要求使用者捕获RuntimeException或声明抛出
答案解析 AC
下面异常声明不推荐的是 ()
A. public Image loadImage(String path) throws FileNotFoundException, EOFException
B. public Image loadImage(String path) throws IOException
C. public void drawImage(int num) throws ArrayIndexOutOfBoundsException
答案解析
B: 抛出的异常和本身的抽象层次不对应

子线程异常
  1. 线程的问题应该线程自己本身来解决,而不要委托到外部,给某个thread设置一个UncaughtExceptionHandler,可以确保在该线程出现异常时能通过回调UncaughtExceptionHandler接口的public void uncaughtException(Thread t, Throwable e) 方法来处理异常,这样的好处或者说目的是可以在线程代码边界之外(Thread的run()方法之外),有一个地方能处理未捕获异常。但是要特别明确的是:虽然是在回调方法中处理异常,但这个回调方法在执行时依然还在抛出异常的这个线程中
  2. UncaughtExceptionHandler 不支持线程池
以下有关Thread异常处理说法正确的是 (多选)
A.子线程自身不必捕获异常,而是由主线程捕获即可
B.对于运行时异常可调用Thread.setUncaughtExceptionHandler()方法设置运行时异常处理器来进行处理
C.默认情况下,运行时异常从线程抛出时,会在控制台输出堆栈记录
D.子线程须自己捕获异常处理
答案解析 BCD
以下描述错误的是:()
A、   一般来说,如果使用锁,那么读和写都要加锁,而不是写线程需要加锁,而读的线程可以不加锁。
B、   创建新线程时需指定线程名
C、   对线程池(包括ScheduledThreadPoolExecutor)中的线程执行setUncaughtExceptionHandler是有效的
D、   用java.util.concurrent代替wait()和notify()
答案解析 C
下列哪些做法是正确的?()

A. 在finally语句块中关闭流操作,抛出异常时直接忽略该异常,不做任何处理或者仅仅是记录日志
B. 在打开文件流的catch语句块中忽略可能的异常,让程序继续往下运行。
C. 程序发生异常,抛出FileNotFoundException、SQLException等敏感异常时,要正确处理异常,防止造成敏感信息泄露风险
D. 使用捕获NullPointerException的方式替代引用是否为空的判断。
答案解析
答案:AC 说明: B、打开文件流如果有异常,必须要进行处理 D、《安全编码规范》建议4.2 不要直接捕获NullPointerException

多线程
实例化一个Thread实例:
从Thread派生一个自定义类,然后覆写run()方法
start() // 启动线程和运行其中的run方法
run() //  并不会执行新的线程而是使用当前线程执行任务
创建Thread实例时,传入一个Runnable实例(implements Runnable接口,并复写run方法)
使用lambda方法new Thread(() -> {})
可以对线程设定优先级,但是不能保证线程优先级高的一定先执行,取决系统调度Thread.setPriority(int n)

线程的状态
New:新创建的线程,尚未执行;
Runnable:运行中的线程,正在执行run()方法的Java代码;
Blocked:运行中的线程,因为某些操作被阻塞而挂起;
Waiting:运行中的线程,因为某些操作在等待中;
Timed Waiting:运行中的线程,因为执行sleep()方法正在计时等待;
Terminated:线程已终止,因为run()方法执行完毕。
join() 主线程等待线程结束。join(long) 设置最大等待时间

线程中断
人为中断处理的方式

stop()
暴力停止,会放弃线程异常处理

interrupt()
对目标线程调用interrupt()方法
目标线程检测isInterrupted()。并没有真正的停止线程。如果在此基础上进入堵塞状态(sleep(),wait(),join()),马上就会抛出一个InterruptedException,且中断标志被清除,重新设置为false,线程退出。
主要是通过用户自行检测性能是否处于中断,给阻塞的线程发送中断信号使线程退出。
this.interrupted(): 检测线程中断并清除中断标记
this.isInterrupted(): 检测线程中断但是不清除标记
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new MyThread();
        t.start();
        Thread.sleep(1000); // 主线程暂停让子线程跑一会
        t.interrupt(); // 中断t线程
        t.join(); // 等待t线程结束
        System.out.println("end");
    }
}
 
class MyThread extends Thread {
    public void run() {
        while (!isInterrupted()) { // 识别后停止
            System.out.println("hello!");
        }
    }
}
以下说法正确的是 ()
A. 调用Thread.interrupt() 用于请求另外一个线程中止执行,而不是直接中止
B. 推荐使用Thread.current().isInterrupted(),而不是Thread.interrupted()检查自己是否被interrupt
C. 检测到当前线程被interrupt后,应抛出InterruptedException,并在finally或try-with-resource中清理执行状态
D. 调用线程的interrupt方法,只有当线程走到了sleep, wait, join等阻塞这些方法的时候,才会抛出InterruptedException
答案解析
答案:ACD 注意,不可以使用Thread.current().isInterrupted() 检查自己是否被interrupt,因为 isInterrupted() 不会清除一个线程的interrupted status

线程同步标志位
  1. 使用volatitle标志变量共享
  2. volatile关键字解决的是可见性问题:当一个线程修改了某个共享变量的值,其他线程能够立刻看到修改后的值。
  3. 不能保证原子性:多个线程同时修改的情况。
下列哪种情况可以终止当前线程的运行? ()

A. 当一个优先级高的线程进入就绪状态时
B. 当该线程调用sleep()方法时
C. 当创建一个新线程时
D. 抛出一个异常时
E. 调用wait方法
答案解析
答案:DE 解析: A:并不会立即执行,等待时间片轮到的时候才会执行 B:阻塞当前线程,直到阻塞时间达到,重新进入就绪队列 不会释放锁资源 C:同A选项一样,进入就绪队列,等待时间片轮到 D对,抛出异常会终止当前线程的运行。 E对,调用wait方法会释放锁资源


守护线程
守护线程是指为其他线程服务的线程。在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出。
设置方式:
Thread t = new Thread(myRunnable);
t.setDaemon(true);
t.start();
守护线程不能持有任何需要关闭的资源,例如打开文件等,因为虚拟机退出时,守护线程没有任何机会来关闭文件,这会导致数据丢失。

线程同步
synchronize(lockObject())
线程临界区代码只允许一个线程执行
实现方案就是 synchronized 关键字对一个对象进行加锁
使用线程间的一个共享实例作为锁,由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
// 不可用 基础类型 或者封装类型 等可能被重用的对象作为锁对象
private int count = 0;
private final Integer lock = count; // Boxed primitive Lock is shared
synchronize锁的获取和释放都是由JVM控制的

如果使用对象自身作为线程锁(锁住synchronized(this)),等价于直接使用synchronized void声明整个方法。同步方法使用对象的内置锁做修饰方法。
对于静态数据,需要静态的锁对象
线程挂起
wait(): 在锁对象上调用的方法,线程直接释放锁。只有被唤醒后才会返回值。返回后线程重新视图获取锁。
notifyAll()唤醒所有等待中的线程。notify()唤醒一个线程。
关于synchronized和lock两者的比较,描述错误的是:()
A、   synchronized是Java语言内置的实现,使用简单,无须关注锁的释放与获取,都是JVM自动管理。
B、   Lock相关的锁,则需要手动获取与释放,稍有不慎,忘记释放锁或者程序处理异常导致锁没有释放,则会造成死锁。
C、   Lock相关接口可以非阻塞地获取锁。
D、   两者都不能响应中断,但Lock的tryLock(long time, TimeUnit unit)可以响应超时。
答案解析
D 解析: synchronized不响应中断,lock可以响应中断

ReentrantLock()
因为synchronized是Java语言层面提供的语法,所以我们不需要考虑异常,而ReentrantLock是Java代码实现的锁,我们就必须先获取锁,然后在finally中正确释放锁。
顾名思义,ReentrantLock是可重入锁,它和synchronized一样,一个线程可以多次获取同一个锁。

lock.lock():获取锁必须在异常捕获之外
lock.unlock():一般是在finally块中使用
线程挂起
 private final Lock lock = new ReentrantLock();
 private final Condition condition = lock.newCondition();
condition.await():挂起
signal():唤醒某个
signalAll():唤醒所有线程
await(long):在等待多少时间后自动唤醒

ReadWriteLock()
可以实现读写锁分离,读锁实现的时候,允许其他线程访问读取变量但是不允许写。
把读写操作分别用读锁和写锁来加锁,在读取时,多个线程可以同时获得读锁,这样就大大提高了并发读的执行效率。
读的时候不允许写:悲观读锁

StampedLock()
新的读写锁,但是读锁是乐观锁
需要在使用时候特殊处理,验证是否在乐观:读锁后发生写锁
long stamp = stampedLock.tryOptimisticRead(); // 获得一个乐观读锁
if (!stampedLock.validate(stamp)) { // 检查乐观读锁后是否有其他写锁发生
    stamp = stampedLock.readLock(); // 获取一个悲观读锁
    try { 重新读,并且修正源数据 } finally {
        stampedLock.unlockRead(stamp); // 释放悲观读锁
    }
}
StampedLock是不可重入锁。
提给的线程安全对象
cocurrent 集合类
atomic 类
CAS操作包含三个操作数—— 内存位置的值(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置更新为新值。否则,处理器不做任何操作。(重复获取并计算的步骤)
CAS是一种有名的无锁算法。无锁编程,即不适用锁的情况下实现多线程之间的变量同步,也就是在没有现成被阻塞的情况下实现变量的同步。

线程池
简单地说,线程池内部维护了若干个线程,没有任务的时候,这些线程都处于等待状态。如果有新任务,就分配一个空闲线程执行。如果所有线程都处于忙碌状态,新任务要么放入队列等待,要么增加一个新线程进行处理。

ExecutorService
Java标准库提供了ExecutorService接口表示线程池,它的典型用法如下:

// 创建固定大小的线程池:
ExecutorService executor = Executors.newFixedThreadPool(3);
// 提交任务:
executor.submit(task1);
ThreadPoolExecutor
分类
FixedThreadPool:线程数固定的线程池,适合使用在任务量比较固定但耗时长的任务。
CachedThreadPool:线程数根据任务动态调整的线程池,针对短期异步线程较多的情况
SingleThreadExecutor:仅单线程执行的线程池,线程死了以后再创建一个线程代替执行,适合使用在多个任务顺序执行的场景。
ScheduledThreadPool:定期反复执行,例如,每秒刷新证券价格。这种任务本身固定,需要反复执行的,可以使用ScheduledThreadPool。放入ScheduledThreadPool的任务可以定期反复执行。
使用shutdown()方法关闭线程池的时候,它会等待正在执行的任务先完成,然后再关闭。shutdownNow()会立刻停止正在执行的任务。

关键参数
corePoolSize:核心线程数,该参数说明了在线程池中保持核心线程的数量。无论是否向池子里提不提交任务,池子里至少会保持核心线程数数量。(创建为0,提交任务增加,达到这个数字后再也不减少)
maximumPoolSize:最大线程数
keepAliveTime:是线程池中空闲线程等待工作的超时时间。
workQueue:线程满了之后使用的缓存任务队列
CPU密集型:cpu利用率较高,设置线程数量和cpu核心数一样即可。使cpu得到充分利用。
IO密集型:IO密集型,主要进行长时间的IO操作,cpu利用率不如cpu密集型高,一般设置线程数为CPU两倍
一般使用
提交Runnable接口给线程池执行,但是一般不支持返回值
public static void execute(Runnable runnable) {
    executorService.execute(runnable);
}
提交Callable接口给线程池执行,但是支持返回值(泛型接口)
public static <T> Future<T> execute(Callable<T> callable) {
    return executorService.submit(callable);
}
Future<V>的使用
get() // 获取结果(可能会等待)
get(long timeout, TimeUnit unit) // 获取结果,但只等待指定的时间;
cancel(boolean mayInterruptIfRunning) // 取消当前任务;
isDone() // 判断任务是否已完成。
CompletableFuture 的使用
异步任务结束时,会自动回调某个对象的方法;
异步任务出错时,会自动回调某个对象的方法;
主线程设置好回调后,不再关心异步任务的执行。
thenAccept(); // 处理正常结果
exceptional(); // 处理异常结果
thenApplyAsync(); // 用于串行化另一个CompletableFuture
anyOf(); // 任一个成功
allOf(); // 全部成功 用于并行化多个CompletableFuture
 
// 异步执行两次
CompletableFuture<String> task1 = CompletableFuture.supplyAsync(() -> {
    return method1();
});
CompletableFuture<String> task2 = CompletableFuture.supplyAsync(() -> {
    return method2();
});
 
// 合并
CompletableFuture<Object> task3 = CompletableFuture.anyOf(task1, task2);
ForkJoin
ForkJoinPool线程池可以把一个大任务分拆成小任务并行执行,任务类必须继承自RecursiveTask或RecursiveAction。
// 无返回结果
public class test extends RecursiveAction {
    @Override
    protected void compute() {}
}
 
// 有返回结果
public class test<T> extends RecursiveTask<T> {
    @Override
    protected <T> compute() {}
}
ForkJoinPool 最适合的是计算密集型的任务
ForkJoinPool 适合并行流处理
ThreadLocal
Java标准库提供了一个特殊的ThreadLocal,它可以在一个线程中传递同一个对象。
ThreadLocal 相当于给每个线程都开辟了一个独立的存储空间,各个线程的ThreadLocal 关联的实例互不干扰。

static ThreadLocal<User> threadLocalUser = new ThreadLocal<>();
threadLocalUser.set(xx);
threadLocalUser.remove();
ThreadLocal一定要在 finally{} 中清除,或者直接使用 try (resource) {...} 隐式封装
Socket类阻塞不响应
以下哪些在接收到Thread.interrupt()会抛出InterruptedException异常
A、Thread.sleep()
B、java.net.Socket的阻塞方法
C、java.nio.channels.SocketChannel的阻塞方法
D、Thread.wait()
答案解析
ACD java.net.Socket 类的方法阻塞时不响应interrupt!写多线程程序时必须回避这些类

以下哪些方法在线程被中断时不会抛出InterruptedException异常:
A: Thread.sleep()
B: SocketChannel.write()  
C: Socket.getOutputStream().write()
D: Socket.connect()
答案解析
CD java.net.Socket 类的方法阻塞时不响应interrupt!写多线程程序时必须回避这些类

锁同步机制
下列描述中,可能会产生死锁的是:

 A.两个或多个线程以不同的顺序请求和释放锁
 B.在产生阻塞的操作中持有锁
 C.同步方法或使用对象内置锁的同步代码块中,直接抛出异常
 D.异常条件下没有正确释放锁
答案解析 ABD
锁的获取和释放顺序需要保持包裹关系 (()(()))
下列哪种操作可能带来死锁:

A. lock(m1) lock(m2) unlock(m1) unlock(m2)
B. lock(m1) lock(m2) unlock(m2) lock(m2) unlock(m1) unlock(m2)
C. lock(m1) lock(m2) unlock(m1) lock(m1) unlock(m2) unlock(m1)
D. lock(m1) lock(m2) unlock(m1) unlock(m2) lock(m1) unlock(m1)
答案解析 C
同步类
CountDownLatch,类似于计数器的方式,用于等待一个或多个线程执行完操作开始自身代码的执行。
CyclicBarrier即同步屏障,它主要功能是让一组线程达到一个屏障(也可以称为同步点)是被阻塞,直到最后一个线程达到屏障是,屏障才被打开,所有被拦截的线程才会继续执行。
CountDownLatch计数器只能使用一次,而CyclicBarrier的计数器可以使用 reset方法重置,所以适合更复杂的业务场景
Semaphore即信号量,主要用来控制并发访问特定资源的线程数量,协调各个线程合理使用公共资源。
Exchanger,用于两个线程之间的数据交换。
关于多线程并发,说法不正确的是:()
A、创建新线程时需指定线程名
B、使用Thread对象的setUncaughtExceptionHandler方法注册未捕获异常处理者
C、建议使用非volatile变量作为通知用的变量
D、避免不加控制地创建新线程,而应该使用线程池来管控资源
答案解析C
如果信号量(Semaphore)的初始值是2,经过多次wait和signal操作后,信号量的值变为-2,则当前系统处于临界区的进程数和等待进入临界区的进程数是? ()
A. 2,2
B. 2,3
C. 3,3
D. 1,2
答案解析 A 等待的进程数就是资源量的绝对值
当线程调用start()后,其所处状态为()。

A. 阻塞状态
B. 运行状态
C. 就绪状态
D. 新建状态
答案解析 :C 有资源才会开始
atomic包下提供的能原子更新数组中元素的类不包括()

A. AtomicReference
B. AtomicIntegerArray
C. AtomicLongArray
D. AtomicReferenceArray
答案解析A AtomicReference为标量类,作用是原子更新引用类型
以下哪种方式创建的线程池适合使用在很耗时的任务()
A. Executors.newCachedThreadPool()
B. Executors.newFixedThreadPool()
C. Executors.newWorkStealingPool()
D. Executors.newSingleThreadExecutor()
答案解析
C 说明: A、newCachedThreadPool:可缓存线程的线程池,适用于并发不固定的短期小任务 B、newFixedThreadPool:创建一个固定大小的线程池,可控制线程最大并发数,超出的线程会在队列中等待 C、newWorkStealingPool:适合使用在很耗时的操作,但是newWorkStealingPool不是ThreadPoolExecutor的扩展,它是新的线程池类ForkJoinPool的扩展,但是都是在统一的一个Executors类中实现,由于能够合理的使用CPU进行对任务操作(并行操作),所以适合使用在很耗时的任务中 D、newSingleThreadExecutor:单线程的线程池,适用于串行化任务,任务一个接着一个地执行

反射
一般反射时进行的操作是获取要反射类的Class对象,从而获取类型元数据(metadata),比如字段、属性、构造器、方法、注解等,获取后并调用。
反射出无、有参的构造方法并得到对象

无参:
Object object1=clazz1.newInstance();
有参:
Constructor constructor1=clazz2.getConstructor(int.class,String.class);
Object object2=constructor1.newInstance(18,"小明");
Java反射机制的作用包括 (多选)()
A. 在运行时判断任意一个对象所属的类。
B. 在运行时构造任意一个类的对象。
C. 在运行时判断任意一个类所具有的成员变量和方法。
D. 在运行时调用任意一个对象的方法。
答案解析 ABCD
方法
反射不可以直接通过getField获取私有成员的值
Field getField(String name) 根据变量名,返回一个具体的具有public属性的成员变量
Field[] getFields() 返回具有public属性的成员变量的数组
Field getDeclaredField(String name) 根据变量名,返回一个成员变量(不分public和非public属性)
Field[] getDelcaredFields() 返回所有成员变量组成的数组(不分public和非public属性)
 
Method method=clazz5.getMethod("printMessage",String.class,int.class,int.class);
Object object5=clazz5.newInstance();
method.invoke(object5, "周星星",50,9527);
下列有关Java反射的说法错误的是: ( )
A. 反射可以获取Method,通过invoke进行方法的调用;
B. 反射不可以直接通过getField获取私有成员的值;
C. 反射可以获取注解(@Target为Runtime)信息;
D. 反射可以获取类的构造器

答案解析 BC
A:基操,正确 B:获取到对象的私有字段Field后,然后设定 setAccessible 为true,然后调用字段的get方法,就可以获取到对象的数据了,同时也可以通过反射的方法获取字段的get和set方法来获取需要修改的字段 C:注解@Target没有Runtime,@Retention才有Runtime。反射可以获取注解信息,通过调用class对象的getDeclaredAnnotations()方法。 D:可以

下面哪个不是Class类中定义的反射方法 ()
A. getDeclaredFields
B. getDeclaredNames
C. getDeclaredMethods
D. getDeclaredConstructors
答案解析
B 解析:getName() 获取该类的名称,因为类名唯一,所以没有getNames(

 以下代码输出:()
class Parent {
    public int a = 100;
    private int b = 200;
    protected int c =300;
    public int f() {
        return 10;
    }
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Field[] fields = Parent.class.getDeclaredFields();
        System.out.println(fields.length);
 
        Field[] fields1 = Parent.class.getFields();
        System.out.println(fields1.length);
    }
}
A. 1 3
B. 3 1
C. 1 1
D. 3 3
答案解析B


IO / NIO / Process
IO
Java IO库有两个支系:(通过结尾就知道是什么类的子类)

面向字节流的InputStream和OutputStream
面向字符的Reader和Writer
RandomAccessFile 与输入流和输出流不同之处就是RandomAccessFile可以访问文件的任意地方同时支持文件的读和写,并且它支持随机访问。RandomAccessFile包含InputStream的三个read方法,也包含OutputStream的三个write方法。
构造函数:
创建随机访问文件流,以从File参数指定的文件中读取,并可选择写入文件。
RandomAccessFile(File file, String mode)
创建随机访问文件流,以从中指定名称的文件读取,并可选择写入文件。
RandomAccessFile(String name, String mode)

构造函数中mode参数传值介绍:
r 代表以只读方式打开指定文件 。
rw 以读写方式打开指定文件。
rws 读写方式打开,并对内容或元数据都同步写入底层存储设备 。
rwd 读写方式打开,对文件内容的更新同步更新至底层存储设备 。
Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据
Java中的字符流处理的最基本的单元是Unicode码元(大小2字节),它通常用来处理文本数据

字节流和字符流的区别

字节流操作的基本单元为字节byte[];字符流操作的基本单元为Unicode码元String。
字节流默认不使用缓冲区,要使用内存缓冲区以提高读取的效率,我们应该使用BufferedInputStream ;字符流使用缓冲区。
字节流在操作的时候本身是不会用到缓冲区的,是与文件本身直接操作的,所以字节流在操作文件时,即使不关闭资源,文件也能输出;
字符流在操作的时候是使用到缓冲区的。如果字符流不调用close或flush方法,则不会输出任何内容。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。
字节流和字符流的转换

InputStreamReader,OutputStreamWriter来关联,实际上是通过byte[]和String来关联
在从字节流转化为字符流时,实际上就是byte[]转化为String时,而在字符流转化为字节流时,实际上是String转化为byte[]时。
 关于RandomAccessfile的说法错误的是? ()
A. 内部基于指针形式可以随机读写文件
B. 可以通过RandomAccessFile的FileChannel间进行mmap操作
C. RandomAccessFile继承InputStream和OutputStream
D. RandomAccessFile只能对文件进行操作
E. 支持r,rw,rws,rwd四种模式
答案解析
C RandomAccessFile父类:java.lang.Object

如下代码执行三次的结果 ()
FileOutputStream outputStream = new FileOutputStream("test.txt", true);
outputStream.write("ABCDE".getBytes(StandardCharsets.UTF_8));
outputStream.close();
 
A. ABCDE
B. ABCDEABCDEACBDE
C. 编译报错
D. ABCDE
  ABCDE
  ABCDE
答案解析
B,new FileOutputStream("text.txt",true) true表示追加,false表示覆盖

为从文本文件中进行读取内容,应该使用哪个处理流文件 ()
A. BufferedReader
B. BufferedWriter
C. BufferedInputStream
D. BufferedOutputStream
答案解析A

哪个类写操作是线程安全的? ()
A. FileWriter
B. RandomAccessFile
C. FileOutputStream
D. FileChannel
答案解析 D

字节流、字符流区别描述正确的是: (多选)
A. 字节流关注流,不关注内容,字符流按行读取,关注文本
B. 字节流的基类InputStream/OutputStream,字符流是Reader/Writer
C. 字符流是对字节流的装饰,释放时反向逐一关闭
D. 字符流最终都会按照字节流处理
答案解析 BD

内存流可以不用关闭(关与不关都可以,没影响)
ByteArrayOutputStream和ByteArrayInputStream其实是伪装成流的字节数组(把它们当成字节数据来看就好了),他们不会锁定任何文件句柄和端口,如果不再被使用,字节数组会被垃圾回收掉,所以不需要关闭。
使用装饰流时,只需要关闭最后面的装饰流即可,装饰流是指通过装饰模式实现的java流,又称为包装流,装饰流只是为原生流附加额外的功能(或效果),java中的缓冲流、桥接流也是属于装饰流。
NIO
Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的
Java IO和NIO之间第一个最大的区别是,IOIO的各种流是阻塞的,NIO线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
Channel
双向的,可以独写

FileChannel
DatagramChannel 是一个能收发UDP包的通道
SocketChannel SocketChannel是一个连接到TCP网络套接字的通道
ServerSocketChannel 是一个可以监听新进来的TCP连接的通道
这里看名字就可以猜出个所以然来:分别可以对应文件IO、UDP和TCP( Server和Client)。
Buffer
NIO中的关键Buffer实现有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer,LongBuffer, ShortBuffer, 分别对应基本数据类型: byte, char, double, float, int, long, short。
当然NIO中还有MappedByteBuffer, HeapByteBuffer, DirectByteBuffer等
没有StringBuffer
Java IO buffer状态变量不包括?

A capacity
B limit
C flag
D position
答案解析
C 容量(Capacity):缓冲区能够容纳的数据元素的最大数量; 位置(Position):下一个要被读或写的元素的索引; 边界(Limit):缓冲区的第一个不能被读或写的元素; 标记(Mark):一个备忘位置。

Buffer的视图方法会对创建视图的对象同步修改

以下说法正确的是

A、临时文件由于会定期被清理掉,所以不用显示的清理临时文件
B、java.nio包中的Buffer类定义了一系列方法,如wrap()、slice()、duplicate(),这些方法会创建一个新的buffer对象,修改这个新buffer对象不会导致原始的封装数据也被修改
C、运行一个外部进程时,如果此进程往其输出流发送任何数据,则必须将其输出流清空。类似的,如果进程会往其错误流发送数据,其错误流也必须被清空
D、Java代码中常用的抽象方法Reader.read()方法用于从流中读取一个字节或字符,返回值的范围为0~65535,所以应定义char类型接收返回值
答案解析
C 规则 6.3 防止让外部进程阻塞在输入输出流上 规则 6.4 对于从流中读取一个字符或字节的方法,使用int类型的返回值

Selector
Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便

有关NIO Selector说法错误的是:

A 可以设定Selector的监听事件,包括Connect/Accept/Read/Write;(看来机制介绍的还是很清楚的)
B Selector需要与Channel配合使用,Selector是Channel的复用器;
C Selector本身不是一个文件,不用Close
D Selector等事件就绪后,才会返回,避免了大量IO阻塞;
答案解析 C
SocketChannel可以向Selector注册哪些事件
A、SelectionKey.OP_ACCEPT
B、SelectionKey.OP_CONNECT
C、SelectionKey.OP_WRITE
D、SelectionKey.OP_READ
答案解析 BCD
ServerSocketChannel的有效事件是OP_ACCEPT,SocketChannel的有效事件是OP_CONNECT、OP_READ、OP_WRITE

Socket哪些操作可能会进入阻塞状态 ()
A. server socket的accpet()监听客户端连接
B. 执行socket的输出流写数据
C. 执行socket的输入流读取数据
D. Socket的getOutputStream(),getInputStream()
答案解析 ABC
进程
Runtime.exec()方法与相关联的ProcessBuilder.start()方法可以用来调用外部程序进程,这些外部程序运行时Process对象会产生哪些流(流也会被分别清空吗)(一会再次来解决这个)
A 错误流
B 监控流
C 输出流
D 输入流
答案解析
ACD process.getInputStream(); // 获取外部程序的输出流 process.getErrorStream(); process.getOutputStream(); // 获取外部程序的输入流

序列化
序列化:就是把对象转换成字节。
反序列化:把字节数据转换成对象。
序列化场景:

对象网络传输
对象保存到文件中
规则
父类实现了Serializable,子类不需要实现Serializable
相关注意事项
a)序列化时,只对对象的状态进行保存,而不管对象的方法;
b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
规则8.4.1 序列化对象中的HashMap、HashSet或HashTable等集合不能包含对象自身的引用
class Super implements Serializable {
private static final long serialVersionUID = -2589766491699675794L;
final Set<Super> set = new HashSet<>();
}
final class Sub extends Super {
    .....
    set.add(this) // 违反规则
}
建议8.4.1 尽量不要实现Serializable接口
建议除非必须使用的第三方接口要求必须实现Serializable接口,否则不建议使用的原因包括:()

A: 序列化对外公开了对象的物理实现
B: 序列化容易使一个类对其最初的内部表示产生依赖
C: 编写正确的反序列化代码有很大的挑战
D: 序列化增大了安全风险
E: 序列化增加了测试的难度
答案解析 ABCDE
建议8.4.1 实现Serializable接口的可序列化类应该显式声明serialVersionUID。如果可序列化类未显式声明serialVersionUID,则序列化运行时将基于该类的各个方面计算该类的默认serialVersionUID值,如“Java™ 对象序列化规范”中所述。但是,强烈建议所有可序列化类都显式声明serialVersionUID值,原因是计算默认的serialVersionUID对类的详细信息具有较高的敏感性,根据编译器实现的不同可能千差万别,这样在反序列化过程中可能会导致意外的InvalidClassException 。因此,为保证serialVersionUID值跨不同java编译器实现的一致性,序列化类必须声明一个明确的serialVersionUID值。
下面对Java反序列化的描述正确的是: ()

A. jdk提供的序列化操作,会将Java对象序列化二进制流,可以有效防止信息泄露或恶意篡改
B. Java的反序列化操作,可以绕过对象构造函数的执行
C. 对象序列化后,即使包含敏感数据也不会产生风险
D. Java反序列化时,目标class与预期class不一致时,会导致类型转换错误,所以即使反序列化不可信数据也不会有安全风险
答案解析 B
对于不安全反序列化漏洞的防护描述错误的是: ()
A. XMLDecoder是jdk原生类,提供了xml的反序列化操作,所以相对Xstream,更推荐使用XMLDecoder进行xml数据的反序列化操作
B. 使用jdk原生api进行反序列化操作,涉及不可信数据时,可以重载ObjectInputStream的resolveClass()方法,在该方法中对目标class进行白名单校验
C. 对不可信的XML数据进行反序列化操作,推荐使用XStream实现,该组件支持白名单检查,新版本也提供了默认安全校验机制
D. 对不可信的json数据进行反序列化操作,可通过禁止开启type功能进行防护
答案解析A

以下说法正确的是 ()
A. 临时文件由于会定期被清理掉,所以不用显示的清理临时文件
B. java.nio包中的Buffer类定义了一系列方法,如wrap()、slice()、duplicate(),这些方法会创建一个新的buffer对象,修改这个新buffer对象不会导致原始的封装数据也被修改
C. 运行一个外部进程时,如果此进程往其输出流发送任何数据,则必须将其输出流清空。类似的,如果进程会往其错误流发送数据,其错误流也必须被清空
D. Java代码中常用的抽象方法Reader.read()方法用于从流中读取一个字节或字符,返回值的范围为0~65535,所以应定义char类型接收返回值
答案解析 C

关于序列化说法不正确的是 ()
A. 序列化只能保存对象的非静态成员交量,不能保存任何的成员方法和静态的成员变量
B. transient关键字的作用是:阻止实例中那些用此关键字声明的变量持久化
C. 当一个父类实现序列化,子类若要实现序列化,需要显式实现Serializable接口
D. 一个子类实现了Serializable接口,它的父类都没有实现Serializable接口,要想将父类对象也序列化,就需要让父类也实现Serializable接口
答案解析C

以下说法正确的是:()
A、不要在代码中硬编码"\n"和"\r"作为换行符号,建议使用System.lineSeparator()方法获取运行时环境的换行符
B、编码时尽量依赖平台默认的字符编码方式
C、String类的toUpperCase()和toLowerCase()方法、format()方法,建议使用默认的编码模式进行转换
D、使用java.nio.charset中的类编码解码字符集
答案解析 AD

序列化安全
遮掩方式
防止未加密的敏感数据被序列的方法有
A、使用transient定义敏感数据
B、使用serialPersistentFields定义非敏感数据
C、重新定义Serializable接口的 writeObject()、writeReplace()、writeExternal()这些函数,不将包含敏感信息的字段写到序列化字节流中。
D、在序列化与反序列化涉及的 writeObject()和readObject()方法中使用安全管理器
答案解析 ABCD

JDBC
PreparedStatement
PreparedStatement会预编译,会被缓冲,在缓存区中可以发现预编译的命令,虽然会被再次解析,但不会被再次编译,能够有效提高系统性能
Statement每次的执行都需要编译SQL
PreparedStatement 和 Statement 都是接口
PreparedStatement 的所有场景都优先于Statement 接口
Java存储过程调用CallableStatement
PreparedStatement.setInt(int parameterIndex, int x)参数的含义 ()
A. 把第parameterIndex-1的参数值设置为x
B. 把第parameterIndex的参数值设置为x
C. 把第x-1的参数值设置为parameterIndex
D. 把第x的参数值设置为parameterIndex
答案解析 B 从1开始的数据

在java中,使用JDBC时,使用PreparedStatement执行sql语句有哪些好处 (多选)
A. 使用PreparedStatement进行sql注入防护是优选方案
B. 使用PreparedStatement多次执行同一条sql语句可以提升执行的效率
C. 使用PreparedStatement可以有效解决所有的sql注入问题
D. 正确使用PreparedStatement,可以有效防止sql注入的发生
答案解析 ABD

Statement 和 PreparedStatement之间的关系和区别
A PreparedStatement和Statement,都是接口   
B SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句,执行效率高。
C 说的sql直接用Statement执行,执行效率高
D 没有参数的SQL语句建议使用Statement执行
答案解析 AB
注入
如果在构造复杂sql语句查询时,预编译的sql语句生成方法不够灵活,需要开发者手动拼接sql,现在输入参数已将 ' 、 " 符号转义,请问如下针对mysql数据库的查询中,哪条是有可能受到sql注入攻击的? (多选)
A. "select * from users where id=" + request.getParameter("id");
B. "select * from users where username='" + request.getParameter("username") + "' and password='" + request.getParameter("password") + "' limit 1";
C. "select * from papers where title='" + request.getParameter("title") + "'";
D. "select * from papers where time='xxxxx' order by " + request.getParameter("columnName");
答案解析 AD 查看有没有'号
资源
数据库查询业务结束后关闭资源,先关ResultSet,再关Statement,最后关Connection。

关闭JDBC资源,需要先后关闭如下哪些资源(多选)
A. DriverManager
B. Connection
C. Statement
D. ResultSet
答案解析 BCD
在执行JDBC查询数据库时,假设物理内存足够用,如果查询结果集ResultSet要返回的记录数很多,比如上百万记录,则下列选项中对ResultSet的fetchsize属性描述正确的是:()
A. ResultSet的fetchSize越大,数据库服务端消耗的内存越小,性能也越快
B. ResultSet的fetchSize越大,数据库服务端消耗的内存越大,性能也越快
C. ResultSet的fetchSize越大,JDBC client端消耗的内存越大,性能也越快
D. ResultSet的fetchSize越大,JDBC client端消耗的内存越小,性能也越快
答案解析 C 结果集合的获取
有关ORM的说法错误的是()

A ORM的缓存机制可以提高数据操作性能Hibernate没有缓存机制;
B ORM依赖于JDBC和DataSource;
C ORM有多种实现,主流的Mybatis与Hibernate;
D ORM、对象关系转换,即数据库的单条数据与Java对应之间的映射;
答案解析 A
JVM 指令
jmap(Java Memory Map)是JDK自带的工具,用来将某个java程序的内存中的信息打印或者输出到文件中,然后通过jhat(Java Heap Analysis Tool)工具对输出的文件进行分析,从而找到可能出现的问题。jhat命令解析会Java堆dump并启动一个web服务器,然后就可以在浏览器中查看堆的dump文件了。
jvisualvm是jdk提供的一个可视化界面,可以看做是对jmap、jstack、jinfo等命令的一个可视化实现,使用jvisualvm可以更加直观的查看堆内存信息、检测死锁,GC等情况!
jstack命令用于生成虚拟机当前时刻的线程快照。
jstat 是用于见识虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、jit编译等运行数据,它是线上定位jvm性能的首选工具。
下面关于jmap说法不正确的是()
A. 使用jmap可以查看堆中对象的统计信息,包括类名,对象数量和内存大小
B. 使用jmap可以把java堆中的对象dump到本地文件
C. 使用jmap可以定位线程死锁的问题
D. 使用jmap可以打印java堆的配置情况和使用情况,还有使用的GC算法
答案解析 C

以下Jmap说法错误的是(  )
A. 打印Java堆概要信息,包括使用的GC算法、堆配置参数和各代中堆内存使用情况;
B. 可以将Java堆信息Dump到文件内
C. 可以查看JVM配置参数和运行的JVM 参数
D. 可以获取每个class的对象数目,占用内存大小和类全名信息
答案解析 C // jInfo 的作用
java进程频繁GC,用哪种工具定位:
A.jstat
B.jmap
C.jstack
D.jinfo
答案解析B 答案:频繁GC 查看内存使用 jmap
关于jvisualvm,以下说法正确的是()
A. jvisualvm无法监控远程服务器的运行状态
B. 运行jvisualvm,需要配置环境、设置Java程序工程以及虚拟机参数等
C. jvisualvm可以在Java程序运行起来以后再运行,通过某些协议连接到Java进程中
答案解析 C
(单选) 以下可用于分析线程死锁问题的命令是
A.jmap
B.jhat
C.jstack
D.jstat
答案解析 C
哪个命令监控java进程的gc情况:
A.jstat
B.jmap
C.jstack
D.jinfo
答案解析 A

JIT 编译器
热点代码预编译,热点代码的判定方式:
1:基于采样的热点探测
2:基于计数器的热点探测

JIT热点代码的阈值参数
-XX:CompileThreshold
解释器与编译器两者各有优势:当程序需要迅速启动和执行的时候,解释器可以首先发挥作用,省去编译的时间,立即执行。当程序运行环境中内存资源限制较大(如部分嵌入式系统中),可以使用解释器执行节约内存,反之可以使用编译执行来提升效率。

JVM强制不使用编译器
A. -client
B. -server
C. -Xint
D. -Xcomp
答案解析 C
java.exe的命令行参数支持强制虚拟机以不同模式(解释模式、编译模式、混合模式)运行。
-Xint 解释模式;-Xcomp 编译模式; -Xmixed混合模式

JavaC 编译过程
使用javac编译时,包含以下哪几个过程:()

A. 语义分析及生成字节码
B. 词法分析及填充符号表
C. Server Compiler
D. 注解处理
E. Client Compiler
答案解析ABD

解析和填充符号表过程
插入式注解处理器的注解处理过程
分析和字节码生成过程

垃圾回收 GC
垃圾回收的算法
GC主要的回收的内存区域是堆区方法区
JVM内存模型中Heap区分两大块,一块是 Young Generation,另一块是Old Generation
在Young Generation中,有一个叫Eden Space的空间,主要是用来存放新生的对象,还有两个Survivor Spaces(from、to),它们的大小总是一样,它们用来存放每次垃圾回收后存活下来的对象。
在Old Generation中,主要存放应用程序中生命周期长的内存对象。
在Young Generation块中,垃圾回收一般用Copying的算法,速度快。每次GC的时候,存活下来的对象首先由Eden拷贝到某个SurvivorSpace,当Survivor Space空间满了后,剩下的live对象就被直接拷贝到OldGeneration中去。因此,每次GC后,Eden内存块会被清空。
在Old Generation块中,垃圾回收一般用mark-compact的算法,速度慢些,但减少内存要求
识出垃圾后,需要回收,有关回收的说法错误是:

A 复制copy后,即把内存区域分成两个等分,from区域与to区域,都从from区分内存,回收即是把from区域还在使用的内存,copy到to内存,….,比较消耗内存;(看来不同的路线,选择机制还是不一样的)
B 压缩compact,重新整理达在使用的内存,一般做法是把还在使用的内存前移,填充回收空间,留下一大片连续的内存;压缩的问题是开销大;(这块需要反复计算才可以解决)
C Java的GC机制会选择其中一种方法进行垃圾回收;(GC的回收过程中多种回收机制一起处理的结果)
D 消除Sweep,直接清除,方法简单,但是会造成内存碎片,给再分配造成不可抑制的麻烦;(这个缺点是很明显的)
答案解析 C
可达性算法的原理是以一系列叫做 GC Root 的对象为起点出发,引出它们指向的下一个节点,再以下个节点为起点,引出此节点指向的下一个结点。这样通过 GC Root 串成的一条线就叫引用链),直到所有的结点都遍历完毕,如果相关对象不在任意一个以 GC Root 为起点的引用链中,则这些对象会被判断为垃圾对象,会被 GC 回收。
垃圾回收算法()
A.引用计数
B.标记清楚
C.复制
D.分块
答案解析 ABCD

GC Root
GC Root 对象有哪些垃圾回收的根对象的范围有以下几种:

  1. 虚拟机(JVM)栈中引用对象(栈帧中的本地变量表)
  2. 方法区中的类静态属性引用对象
  3. 方法区中常量引用的对象(final 的常量值)
  4. 本地方法栈JNI的引用对象
不能作为GC Root的对象:
A.方法区中类静态属性引用的对象
B.方法区内类非静态属性引用的对象
C.方法区中常量引用的对象
D.本地方法中JNI引用的对象
答案解析 B
GC 规范
关于主动调用gc方法的描述,下列说法正确的是()
A. 在频率/周期性的逻辑中更要尽量 避免主动GC的调用
B. 在GC过程中的某些阶段程序会完全停顿,这会让程序失去响应,对系统造成非常大的风险
C. 调用主动GC方法后,系统立即进行垃圾回收操作
D. 如果触发了JVM的全量GC操作,会增加gc的次数,也就增加了程序因为GC而停顿的时间
答案解析ABD
指定堆外内存最大值使用什么参数()C
A. -Xmx
B. -XX:PermSize
C. -XX:MaxDirectMemorySize

设置新生代内存50M用什么参数()C
A. -Xmx50m =>java heap最大值
B. –Xms50m =>java heap初始值,默认为操作系统wuli内存的1/64但小于1G
C. –Xmn50m =>java heap Young区,即新生代的大小
D. –Xss50m =>每个线程的堆栈大小
答案解析 C
Full GC
  1. MaxDirectMemeorySize(即NIO direct-buffer)超过(堆外内存最大值)
  2. 永生代(Perm)或者Metaspace被写满。
  3. 年老代(tenured)被写满或者几次晋升对象平均大小超过年老代的空闲大小。
  4. 调用System.gc()。
正则
Java 的反斜杠写在代码里需要写两次标识正则 //d

如果要匹配 n ~ m 次,用 {n,m} 即可,如果要匹配至少 n 次,用 {n,} 即可。需要注意 , 后不能有空格。

正则的基础规则中,除了 \d,还有 \w和\s,w 是 word 的简写,表示匹配一个常用字符,包括字母、数字、下划线。s 是 space 的简写,表示匹配一个空格,包括三种

将字母换成大写,就表示相反的意思。用 \d 你可以匹配一个数字,\D 则表示匹配一个非数字。

有时候,我们对某些位置的字符没有要求,仅需要占个位置即可。这时候我们就可以用 . 字符。

对匹配的次数没有要求,匹配任意次均可,这时,我们就可以用 * 字符。

+ 表示 至少匹配一次。它等价于 {1,}

匹配 0 次,要么匹配 1 次,我们就可以用 ? 匹配。它等价于 {0,1}

[] 用于匹配指定范围内的字符,比如[123456789] 可以匹配 1~9

[] 取反的方式是:[^],比如不能是 [123] 的表示方法为 [^123] 或者 [^1-3]

^在[]外表示以什么开头

X|Y 表示匹配X或匹配Y

$表示以什么结尾

支持正则的函数
String str = “123\\d”;
String str1 = str.replaceAll(“\\d”, “456”); 
String str2 = str.replace(Pattern.quote(“\\d”), “456”);
String str3=str.replace(“\\d”, “456”); 
str1、str2、str3的输出结果是什么
 
1. 支持正则,替换全部数字(\\ 作为反斜杠的转义):456456456\d
2. 消除正则,单纯替换 123\d
3. 不支持正则 123456
String s = "a$b$c";
String[]  sArray = s.split("$");
for (String value : sArray) {
    System.out.println(value);
}
输出为 a$b$c,表示正则匹配不上,所以不会分割
开发者测试
测试设计
Fuzz测试
Fuzz测试,通过对数据变异进行,将变异后的数据交给处理程序,观察处理程序的异常行为,来寻找程序漏洞(Bug)。
DT Fuzz测,将Fuzz测试引入到开发阶段,与DT(Developer test)测试中的单元测试(UT)、接口测试(IT)、系统测试(ST)等相结合,利用白盒测试方法,基于DT测试框架进行Fuzz测试
白盒测试是根据被测程序的内部结构设计测试用例的一种测试方法。

针对DT FUZZ测试,下面的说法正确的是()
A. DT FUZZ测试中,如果被测函数代码有修改,但被测函数被调用逻辑没有修改,不需要修改测试用例
B. 尽量选择模块外层函数为被测目标,编写测试用例,测试过程中,本模块内部函数可以随意打桩存疑
C. DT FUZZ测试,编写测试用例可以不考虑函数的调用上下文
D. 结构化的参数DT FUZZ工具都可以构造
答案解析  A 说明: B、本模块内部函数可以随意打桩有问题,具体的原因需要进一步搜索资料 C、基于正确的函数调用上下文编写测试用例,如果一个函数,不同的调用上下文执行不同的代码,需要为每个上下文编写测试用例 D、结构化的参数要自己构造,比如链表,指针,这类参数无法变异出来
白盒测试
语句覆盖:每一可执行语句至少执行一次,不一定进入所有分支
判定覆盖:分支覆盖一次。取真和取假都执行一次。就算不执行语句,也会执行对应分支。
条件覆盖:每个判断的每个条件的可能取值一次 每个条件的真假取值至少被覆盖一次;条件覆盖不能保证判定覆盖;
判定 - 条件覆盖:同时满足判定和条件覆盖
条件组合覆盖:每个判定的条件取值组合至少能被覆盖一次,不一定能实现路径覆盖
路径覆盖:覆盖所有的分支路径
判定覆盖只关心判定表达式的值(真/假),而条件覆盖涉及到判定表达式的每个条件的值(真/假)

为以下流程图所示的程序段设计一组测试用例,下面()用例满足判定/条件覆盖标准的最小的测试数据组

条件1: x>8&& y >5
条件2: x >0 || y >0
条件3: x>16|| y > 10
判定-条件覆盖:每个条件的每个判断语句的真假至少执行一次,并且每个条件的真假也至少执行一次

A. (X=0, Y=0); (X=1,Y=0); (X=15, Y=9); (X=17, Y=6)
B. (X=0, Y=0); (X=1, Y=1); (X=15,Y=9); (X=17, Y=11)
C. (X=0, Y=0); (X=17, Y=11)
D. (X=0, Y=0); (X=1, Y=0); (X=17, Y=6)
答案解析 B
关于逻辑覆盖,下列说法正确的有

A. 100%的判定覆盖无法保证100%的语句覆盖,若判定覆盖达到100%,则语句覆盖必为100%
B. 判定覆盖无法保证一定能查出判断条件存在的错误,即使语句覆盖率达到了100%,也不能发现其中的逻辑错误
C. 100%的条件覆盖不一定满足100%的判定覆盖覆盖条件的测试用例不一定覆盖判定
D. 100%的判定条件覆盖可以保证100%的条件覆盖判定-条件覆盖率实际上就是判定覆盖率和条件覆盖率的组合
答案解析 BCD

如果输入条件规定了整型参数的范围及默认值,只用边界值分析方法,()可以作为测试数据。

A. 最大值和最小值

B. 最小值-1

C. 最大值+1

D. 默认值

答案:(ABC)



在测试系统中有3个参数,通过pair –wise设计方法设计用例,需要几个用例覆盖?

参数A 2中可能

参数B 3种可能

参数C 3种可能

A. 6 B. 18 C. 3 D.9

答案:(D)

解析: pair-wise测试用例数为最大两个因子取值个数的乘积 (33得9)



黑盒测试
测试软件产品的功能,而不需关注软件产品的内部结构和处理过程。等价类划分 | 边界值分析

输入条件是有N个取值的枚举量,则等价类划分结果是()个有效等价类和()个无效等价类

A. N,1
B. N,2
C. 1,1
D. N,0
答案解析 A
输入条件规定了输入数据的一组n个值且分别处理,可获得n个有效等价类和一个无效等价类

在某大学学籍管理信息系统中,假设学生年龄的输入范围为16—40,则根据黑盒测试中的等价类划分技术,下面划分正确的是

A. 可划分为2个有效等价类,2个无效等价类
B. 可划分为1个有效等价类,2个无效等价类
C. 可划分为2个有效等价类,1个无效等价类
D. 可划分为1个有效等价类,1个无效等价类
答案解析 B
输入条件规定了取值范围,可获得一个有效等价类和两个无效等价类
因子组合
因子组合技术:

AC (All Combinations)所有组合 :组合个数=所有因子的取值个数乘积
EC( Each Choice )出现一次就行:组合个数=最多取值的因子的取值个数
BC(Basic Choice)以一个为基础 每次改变一个:组合个数=所有因子的取值-因子个数+1
N-wise:每N个测试因子的取值组合至少覆盖一次
某系统有三个输入A,B,C,每个输入的取值个数分别为4,6,7,使用EC(单一选择组合)方法设计测试用例,至少需要设计()个用例
A. 3 B. 7 C. 15 D. 17
答案解析

(B)解析:

EC(单一选择组合): 所有因子中取值最多的那个因子的取值个数  B

BC(基本选择组合): 所有因子取值个数和 - 因子个数 + 1 C

AC(全组合): 所有因子取值个数的乘积 

EC(单一选择组合): 所有因子中取值最多的那个因子的取值个数 BC(基本选择组合): 所有因子取值个数和 - 因子个数 + 1 AC(全组合): 所有因子取值个数的乘积

测试准则
测试代码与业务代码质量要求一样,用例写作遵循FIRST原则:

F:Fast,执行要快,要求测试用例粒度要小;
I:Independent,独立,对其他测试没有依赖,可以单独执行;
R:Repeatable,每次测试结果要相同,才能有效回归测试,必须与外部环境无关;
S:Self-Validating,测试结果应该是简单明确的true or false;
T:Timely,测试代码和生产代码同步输出,及时验证;
测试执行应确保与外部环境无关,避免用例随机失败,确保满足测试用例()原则
A. 解耦
B. 可重复
C. 一致性
D. 及时反馈
答案解析 B
R:可重复,测试通常会被放到持续集成中,每次有代码check in时单元测试都会被执行。

高效可靠的测试对于重构至关重要,在已经有较完善的白盒测试的情况下,由于代码规模巨大测试反馈时间很长,为了在重构代码的过程中保证有效验证的同时减少测试反馈时间提升效率,正确的做法是()
A. 不做白盒测试,直接进行系统功能验证,减少测试次数
B. 每次随机选取部分测试用例执行,以减少每次测试工作量
C. 选择与修改代码有关的数据和测试用例,减少测试执行范围
D. 不论修改影响范围如何都应该进行全覆盖测试,保证不出问题
答案解析
C 题目分析:A随机选取偶然性大,不可取;B基本的白盒测试还是需要的,把错误透到后端,问题定位代价大,效率低;C正确;

良好的测试防护网是重构成功的重要前提,其中单元测试是构建测试防护网常用的手段。下述哪种做法是重构过程中较好的单元测试行为( )
A. 重构过程中,一旦修改代码,为了保证修改正确性,就对所有测试用例进行全量覆盖测试。
B. 为了减少重复,将多个前置条件相同(如输入相同)的功能点在一个测试用例里进行合并测试。
C. 被测对象依赖了外部接口,为了便于观察调用行为,对外部接口打桩,并通过printf等输出打印信息进行观察。
D. 重构过程中,为了提升测试效率,优先设计与修改代码有关的测试用例。
答案解析
D 题目分析:选项A不符合单一原则;选择B不符合自确认原则;选项C正确,符合测试景深的思想;选项D修改的代码可多可少,从反馈效率上考虑,不建议所有情况都进行全量测试。

某项目对于存量代码进行重构,需要补充测试防护网,他们的做法中错误的是()
A. 重构过程中对代码有新的理解或者发现新的问题时逐步补充新的测试用例
B. 在重构代码前先对需要修改的代码补充自动化测试用例
C. 测试用例可以自动化执行,但是需要开发人员人工确认执行结果是否符合预期
D. 要求测试必须补充到非常完善充分以后,才可以修改代码,使得团队在前一大半时间都在补充用例,实际没有重构多少代码
答案解析
CD 题目分析:A正确,重构应该先建立测试防护网;D错误,一次建立完善充分的测试是不现实的,应该从修改的代码开始建立用例并逐步完善,避免一开始就陷入对完美测试的无尽追求中,参考《重构》一书构筑测试体系章节中“编写未臻完善的测试并实际运行,好过对完美测试的无尽等待。”;C错误,自动化用例应该能够直接反馈是否正确而不需要人工比对;B正确,测试防护网需要不断补充完善

1、运行下列代码,实际的输出结果是什么?


2、以下哪个命令可以监控Java进程的gc情况



3、根据Java语言编程规范,以下哪种方式不能正确的从集合中删除元素



4、下面这段代码的输出结果为


5、下例程序的输出为:


6、进程频繁GC,主要使用以下哪种工具进行问题定位和分析?


7、执行如下代码片段,变量str2的结果是

 

8、多线程模拟一个简单的服务叫号系统,有n个服务窗口,如果所有窗口忙时,顾客将等待,当有空闲窗口时,最先等待的客户将被通知并服务,以下哪个多线程同步器最合适:


9、关于JVM GC finalize() 方法说明,哪项是错误的


10、在开启了安全管理配置的情况下,安全配置文件内容为:security.policy: grant {}。上述代码的执行结果是



11JAVA堆内存分为年轻代、年老代和永久代,minor GC主要发生在哪里


12、下面的程序运行结果为


13、某个进程启动,需要并发执行多个初始化任务,当所有任务执行完成后,输出一个信息:进程启动成功。完成以上功能,以下哪个多线程同步器最合适


14、产品代码初始化集合时,由于不了解Java集合类的自动扩容机制以及其初始大小,容易引发性能问题。因此在可以预估元素数量的场景下,应指定初始大小。关于如下常用集合/StringBuilder的初始化大小描述错误的是


15、安全场景下强随机数可以使用以下哪种方式生成


16、以下代码的结果正确的是


17、执行如下哪个选项,不可能出发JVMGC


18、给定如下代码


19、执行以下代码输出的结果是


20、有以下一段代码:请问使用以下哪条命令编译无编译错误


21、执行以下代码,将会打印


22、减少或避免java.lang.ClassCastException,下面不推荐的处理方式是


23、针对以下代码,以下说法错误的是


24、下列程序的输出结果是


25、以下关于Java原语waitnotifynotifyAll,正确的是


26、针对Thread.sleepObject.wait和监视器锁,以下说法正确的是


27atomic包下提供的能原子更新数组中元素的类不包括


28、以下不属于运行时异常的是哪个


29、下列使用NIO对文件读写进行操作,哪个是错误的


30、现有java代码如下


31、无论发生多少异常,“try”块的哪一部分总是会执行


32、以下有关Java等待-通知(wait-notify)机制描述,错误的是


33、根据Java编程规范,关于日志下列说法错误的是


34、如下代码的输出是


35、关于以下程序说法正确的是


36、以下代码运行结果是



37、下面给出的JavaClassLoader中的描述,哪项描述是正确的


38、下列关于URLURI的描述,不正确的有


39、关于jinfo的用法,下面说法不正确的是


40、根据Java语言编程规范,以下哪个选项属于可信数据


41、白盒测试技术是根据被测对象的结构,系统化设计测试用例的一种方法,下列哪种结构不属于白盒测试用例设计时的分析范围


42、下列有关Map操作错误的是


43、执行下面代码后,控制台输出的是什么


44、以下代码运行输出是


45、假定Tester类有默认构造函数,并且有如下test方法


46、根据编程规范,以下关于equalshashCode说法正确的有


47、以下有关Arrays.asList(T… data)方法说法哪些是正确的


48、频繁主动GC可能导致如下哪些问题


49、如下哪些数据类型有常量NaNNot-a-Number


50、有关final关键字的描述,正确的有


解释:

  1. final不能保证发布变量的构造函数原子性,需要使用其它同步手段。
  2. final变量的语义不保证Happens-Before,只是保证了赋值操作ordering


51、给定以下代码,在TODO处的写法,选项中正确的有


52、根据Java编程规范,关于泛型以下描述正确的有


53、下面选项中的都是与数组相关的代码片段,哪些没有语法错误


54、线程安全的Map有哪些


55、关于测试分层,如下描述正确的有


56、关于ThreadLocal,以下说法正确的有


57、当一个自定义的类装载器要覆写getPermission()方法的时候,如果没有调用父类的getPermission方法来获取默认的系统规则,则


58、关于JUnit4描述正确的有


59、经常使用“mvn clean package”命令进行项目打包,请问该命令执行了哪些动作来完成该任务


60jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]可显示指定Java进程的GC相关信息,如:以下于老年代相关的列,哪些说法正确


下面是用JDK1.8编译的getSum方法的操作字节码,其源码对应下面选项中的是哪一个() 



如下关于字符串校验的说法,哪个选项是错误的


下面的代码片段是把资金从一个账户转到另一个账户,多线程调用transferMoney方法转账。下面说法正确的是


对于下面创建新对象的方法,表述正确的选项是


Java NIO提供了与标准IO不同的IO工作方式,以下相关描述错误的是


多线程并发读写某个整型变量,说法错误的是


关于JVM GC finalize()方法说明,哪项是错误的


经常使用"mvn clean package"命令进行项目打包,请问该命令执行了哪些动作来完成该任务


Java NIO提供了与标准IO不同的IO工作方式,下面说法正确的有


频繁主动GC可能导致如下哪些问题


下面选项中的都是与数组相关的代码片段,哪些没有语法错误





【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。