牛客网刷题错题集--2021-09-01

牛客网刷题错题集(2021/9/1)

时间:9月1日,记一次牛客网刷题错题集。

下列语句哪一个是不正确的()

正确答案: D 你的答案: C (错误)
Log4j支持按分钟为间隔生成新的日志文件
Log4j是一个打印日志用的组件
Log4j支持按年为间隔生成新的日志文件
Log4j的日志打印级别可以在运行时重新设置
答案解析:

日志的级别之间的大小关系如右所示:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF Log4j建议只使用四个级别,优先级从高到低分别是 ERROR > WARN > INFO > DEBUG。 log4j在运行期间是不可以重新设置的

如果一个接口Glass有个方法setColor(),有个类BlueGlass实现接口Glass,则在类BlueGlass中正确的是? ( )

正确答案: C 你的答案: D (错误)
protected void setColor() { …}
void setColor() { …}
public void setColor() { …}
以上语句都可以用在类BlueGlass中
答案解析:

JAVA 子类重写继承的方法时,不可以降低方法的访问权限,子类继承父类的访问修饰符要比父类的更大,也就是更加开放,假如我父类是protected修饰的,其子类只能是protected或者public,绝对不能是friendly(默认的访问范围)或者private,当然使用private就不是继承了。还要注意的是,继承当中子类抛出的异常必须是父类抛出的异常的子异常,或者子类抛出的异常要比父类抛出的异常要少。

下面哪个Set类是排序的?

正确答案: B 你的答案: A (错误)
LinkedHashSet
TreeSet
HashSet
AbstractSet
答案解析:

LinkedHashSet
继承于HashSet、又基于 LinkedHashMap 来实现
TreeSet
使用二叉树的原理对新 add()的对象按照指定的顺序排序(升序、降序),每增加一个对象都会进行排序,将对象插入的二叉树指定的位置。
HashSet
存储元素的顺序并不是按照存入时的顺序(和 List 显然不同) 而是按照哈希值来存的所以取数据也是按照哈希值取得

检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果。

public class Example {  
  String str = new String("good");  
  char[] ch = {'a','b','c'};  
  public static void main(String[] args) {  
     Example ex = new Example();  
     ex.change(ex.str, ex.ch);  
     System.out.print(ex.str +"and");  
     System.out.print(ex.ch);   
  }  
   
  public void change(String str, char ch[]){  
     str= "test ok";  
     ch[0]= 'g';  
  }  
}  

正确答案: D 你的答案: B (错误)
test okandabc
test okandgbc
goodandabc
goodandgbc
答案解析:

java 中String是 immutable的,也就是不可变,一旦初始化,其引用指向的内容是不可变的。

也就是说,String str = “aa”;str=“bb”;第二句不是改变“aa”所存储地址的内容,而是另外开辟了一个空间用来存储“bb”;同时由str指向

原来的“aa”,现在已经不可达,GC时会自动回收。

因此String作为参数传进来时候,str= "test ok"; 实际给副本引用str指向了新分配的地址,该地址存储“test ok”。

因此,原先的str仍然指向“good”

执行语句“int a= ’ 2 ’ ”后,a的值是( )

正确答案: B 你的答案: A (错误)
2
50
49
0
答案解析:

常用ASCII码值:空格为32;数字0为48;“A”为65;“a”值为97。

下面这条语句一共创建了多少个对象:String s=“welcome”+“to”+360;

正确答案: A 你的答案: B (错误)
1
2
3
4
答案解析:

是否大家有没有刷到这类面试题:在执行String s = "Hello";s = s + " world!";这两行代码后,原始的String对象中的内容到底变了没有?
答案的解析:
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
       private String s;
              ...
       public Demo {
              s = "Initial Value";
       }
       ...
}
而非
s = new String("Initial Value");

后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。

至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
说说我的看法:字面量的创建是发生在编译期,类似于上述面试题,答案只创建一个对象。

下列哪些情况下会导致线程中断或停止运行( )

正确答案: A B 你的答案: A B D (错误)
InterruptedException异常被捕获
线程调用了wait方法
当前线程创建了一个新的线程
高优先级线程进入就绪状态
答案解析:

A选项正确,Java中一般通过interrupt方法中断线程
B选项正确,线程使用了wait方法,会强行打断当前操作,进入阻塞(暂停)状态,然后需要notify方法或notifyAll方法才能进入就绪状态
C选项错误,新创建的线程不会抢占时间片,只有等当前线程把时间片用完,其他线程才有资格拿到时间片去执行。
D选项错误,调度算法未必是剥夺式的,而准备就绪但是还没有获得CPU,它的权限更高只能说明它获得CPU被执行的几率更大而已
本人线程知识薄弱,呜呜呜.......

以下关于final关键字说法错误的是

正确答案: A C 你的答案: A B (错误)
final是java中的修饰符,可以修饰类、接口、抽象类、方法和属性
final修饰的类肯定不能被继承
final修饰的方法不能被重载
final修饰的变量不允许被再次赋值
答案解析:

final修饰类、方法、属性!不能修饰抽象类,因为抽象类一般都是需要被继承的,final修饰后就不能继承了。
final修饰的方法不能被重写而不是重载! 
final修饰属性,此属性就是一个常量,不能被再次赋值! 

执行如下程序代码

char chr = 127;
int sum = 200;
chr += 1;
sum += chr;

后,sum的值是 ; ( )

备注:同时考虑c/c++和Java的情况的话

正确答案: A C 你的答案: C D (错误)
72
99
328
327
答案解析:

java中只有byte, boolean是一个字节, char是两个字节, 所以对于java来说127不会发生溢出, 输出328
但是对于c/c++语言来说, char是一个字节, 会发生溢出, 对127加一发生溢出,  0111 1111 --> 1000 0000, 1000 0000为补码-128, 所以结果为200-128=72

下面有关java threadlocal说法正确的有?

正确答案: A B C D 你的答案: A C D (错误)
ThreadLocal存放的值是线程封闭,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递
从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收
在Thread类中有一个Map,用于存储每一个线程的变量的副本
对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式
答案解析:

ThreadLocal类用于创建一个线程本地变量
在Thread中有一个成员变量ThreadLocals,该变量的类型是ThreadLocalMap,也就是一个Map,它的键是threadLocal,值为就是变量的副本。通过ThreadLocal的get()方法可以获取该线程变量的本地副本,在get方法之前要先set,否则就要重写initialValue()方法。
ThreadLocal的使用场景:
        数据库连接:在多线程中,如果使用懒汉式的单例模式创建Connection对象,由于该对象是共享的,那么必须要使用同步方法保证线程安全,这样当一个线程在连接数据库时,那么另外一个线程只能等待。这样就造成性能降低。如果改为哪里要连接数据库就来进行连接,那么就会频繁的对数据库进行连接,性能还是不高。这时使用ThreadLocal就可以既可以保证线程安全又可以让性能不会太低。但是ThreadLocal的缺点时占用了较多的空间。

总结

学而时习之,不亦说乎!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值