错题一
- 下面有关java final的基本规则,描述错误的是?
正确答案及分析:B
final修饰的方法,不允许被子类覆盖。
final修饰的类,不能被覆盖。
final修饰的变量,不能改变值。
final所修饰的成员变量只能赋值一次,可以在类方法中赋值,也可以在声明的时候直接赋值,
而final修饰的局部变量可以在声明的时候初始化,也可以在第一次使用的通过方法或者表达式给它赋值。
错题二
- 下列哪个线程会导致线程销毁?
正确答案及分析:D
A.调用sleep()方法让线程进入睡眠状态---睡眠指定的时间后再次执行;
B.调用wait()方法让线程进入等待状态 ----等待别的线程执行notify()或notifyAll()唤醒后继续执行;
C.调用start()方法让线程进入就绪状态---得到CPU时间就执行线程;
看下面红框中的这句话,start方法开启一个新的线程执行run方法,所以start方法执行完,
不代表run方法执行完,线程也不一定销毁。
D.调用run()方法是线程的具体逻辑方法,执行完,线程就结束。
错题三
- 下列Java程序的输出结果为
public class Example{
String str=new String("hello");
char[]ch={'a','b'};
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]='c';
}
}
正确答案及分析:B
你就记住一句话:数组和对象都是引用传递。
基本数据类型和String类型都是值传递,数组,对象等都是引用传递
基本数据类型包括:byte,short,int,long,float,double,char,boolean
引用传递类型包括:Object对象,Array数组,Function函数。
错题四
- 以下哪个类包含方法flush()?
正确答案及分析:B
flush()方法是输出存储在内存中的全部的内容(批量输出)
flush()函数强制将缓冲区中的字符流,字节流等输出,目的是如果输出流输出到缓冲区完成后,
缓冲区并没有填满,那么缓冲区就会一直等待被填满,所以在关闭输出流之前要调用flush()
错题五
- 下面这段程序的输出结果是()
public class Main { public static void main(String[] args) { split(12); } public static int split(int number) { if (number > 1) { if (number % 2 != 0) { System.out.print(split((number + 1) / 2)); System.out.print(split(number / 2)); } return number; } }
正确答案及分析:A
这道题考察进栈与出栈的顺序,先进后出。
这道题有个知识点,方法在出栈的时候,执行的是return语句,因为出栈就意味着方法结束并消费,如果没有return语句,那么方法出栈的
时候什么都不执行,直接销毁。
1.执行split(12)时,执行代码System.out.print(split(number / 2))
split(12/2)进栈,此时number=6;
2.执行split(6)时,执行代码System.out.print(split(number / 2))
split(6/2)进栈,此时number=3;
3.执行split(3)时,
复制代码
第1行 if (number % 2 != 0)
第2行 System.out.print(split((number + 1) / 2));
第3行 System.out.print(split(number / 2));
按照顺序执行
先执行第2行
首先split((3+1)/2)进栈,此时number=2,
再执行split(2),那么split(2/2)进栈,此时number=1, 最后return 1,
注意此时第2行代码还没有结束
此时
split(2/2)出栈,输出1;
split((3+1)/2)出栈,输出2;
第二行代码结束,再执行第三行,此时number=3,执行System.out.print(split(number / 2))
split(3/2)进栈,number=1,return,那么就需要出栈了
split(3/2)出栈,输出1
split(6/2)出栈,输出3
split(12/2)出栈,输出6;
最终结果12136;
split(number)方法,最终返回的是number这个值,所以split(n)出栈的输出结果就是n
整理:
split(12/2)进栈
split(6/2)进栈
split((3+1)/2)进栈
split(2/2)进栈
split(2/2)出栈,输出1
split((3+1)/2)出栈,输出2
split(2/2)进栈
split(2/2)出栈,输出1
split(6/2)出栈,输出3
split(12/2)出栈,输出6
错题六
- Math.floor(-8.5)=( )
正确答案及分析:D
Math.floor() 表示向下取整,返回double类型 (floor---地板) Math.floor(-4.2) = -5.0
Math.ceil() 表示向上取整,返回double类型 (ceil---天花板) Math.ceil(5.6) = 6.0
Math.round() 四舍五入,返回int类型 Math.round(-4.6) = -5
错题七
- 结构型模式中最能体现扩展性的模式是()
正确答案及分析:A
设计模式分为三大类:
创建型设计模式:单例模式,工厂方法模式,简单工厂模式,建造者模式、原型模式
结构型设计模式:适配器模式,***模式,AOP、装饰器模式、
行为型设计模式:观察者模、板方法模式
----------------------------------------------------
结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的
东西:类与类的实例。故可以分为类结构模式和对象结构模式。
在GoF设计模式中,结构型模式有:
1.适配器模式 Adapter
适配器模式是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两个成熟的类需要通信,但是接口不同,由于开闭原则,我们不能去修改这两个类的接口,所以 就需要一个适配器来完成衔接过程。
2.桥接模式 Bridge
桥接模式将抽象部分与它的实现部分分离,是它们都可以独立地变化。它很好的支持了开闭原则和组合锯和复用原则。实现系统可能有多
角度分类,每一种分类都有可能变化,那么就把这些多角度分离出来让他们独立变化,减少他们之间的耦合。
3.组合模式 Composite
组合模式将对象组合成树形结构以表示部分-整体的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
4.装饰模式 Decorator
装饰模式动态地给一个对象添加一些额外的职责,就增加功能来说,它比生成子类更灵活。也可以这样说,装饰模式把复杂类中的核心职责和
装饰功能区分开了,这样既简化了复杂类,有去除了相关类中重复的装饰逻辑。 装饰模式没有通过继承原有类来扩展功能,但却达到了一样的
目的,而且比继承更加灵活,所以可以说装饰模式是继承关系的一种替代方案。
5.外观模式 Facade
外观模式为子系统中的一组接口提供了同意的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式中,
客户对各个具体的子系统是不了解的,所以对这些子系统进行了封装,对外只提供了用户所明白的单一而简单的接口,用户直接使用这个接口
就可以完成操作,而不用去理睬具体的过程,而且子系统的变化不会影响到用户,这样就做到了信息隐蔽。
6.享元模式 Flyweight
享元模式为运用共享技术有效的支持大量细粒度的对象。因为它可以通过共享大幅度地减少单个实例的数目,避免了大量非常相似类的开销。
享元模式是一个类别的多个对象共享这个类别的一个对象,而不是各自再实例化各自的对象。这样就达到了节省内存的目的。
7.***模式 Proxy
为其他对象提供一种***,并由***对象控制对原对象的引用,以间接控制对原对象的访问。
错题八
- 关于身份证号码,以下正确的正则表达式是()
正确答案及分析:A C
A选项:isIDCard=/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/
C选项:isIDCard=/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/
^:起始符号,^x表示以x开头
$:结束符号,x$表示以x结尾
[n-m]:表示从n到m的数字
\d:表示数字,等同于[0-9]
X{m}:表示由m个X字符构成,\d{4}表示4位数字
15位身份证的构成:六位出生地区码+六位出身日期码+三位顺序码
18位身份证的构成:六位出生地区码+八位出生日期码+三位顺序码+一位校验码
C选项的构成:
[1-9]\d{5}:六位出生地区码,出生地区码没有以0开头,因此第一位为[1-9]。
[1-9]\d{3}:八位出生日期码的四位年份,同样年份没有以0开头。
((0\d)|(1[0-2])):八位出生日期码的两位月份,| 表示或者,月份的形式为0\d或者是10、11、12。
(([0|1|2]\d)|3[0-1]):八位出生日期码的两位日期,日期由01至31。
\d{4}:三位顺序码+一位校验码,共四位。
错题九
- 下列哪些操作会使线程释放锁资源?
正确答案及分析:B C
1.sleep()方法
在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。sleep()使当前线程进入阻塞状态,在指定时间内不会执行。
2.wait()方法
在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。
当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。唤醒当前对象锁的等待线程
使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。
waite()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block
中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。
3.yield方法
暂停当前正在执行的线程对象。
yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。yield()只能使同优先级
或更高优先级的线程有执行的机会。
4.join方法
join()等待该线程终止。等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会
执行完毕,导致结果不可预测
算法一
-
给定
S
和T
两个字符串,当他们分别被输入到空白的文本编辑器后,判断两者是否相等,并返回结果。#
代表退格字符。注意:如果对空文本输入退格字符,文本继续为空。
示例1:
输入:S = "ab#c", T = "ad#c" 输出:true 解释:S 和 T 都会变成 “ac”。
示例2:
输入:S = "ab##", T = "c#d#" 输出:true 解释:S 和 T 都会变成 “”。
示例3:
输入:S = "a##c", T = "#a#c" 输出:true 解释:S 和 T 都会变成 “c”。
示例4:
输入:S = "a#c", T = "b" 输出:false 解释:S 会变成 “c”,但 T 仍然是 “b”。
提示:
1.
1<=S.length<=200
2.
1<=T.length<=200
3.
S
和T
只含有小写字母以及字符#
class Solution { public boolean backspaceCompare(String S, String T) { //先比较两个字符串是否相等 return result(S).equals(result(T)); } public String result(String v){ //获取字符串的长度 char[] c=new char[v.length()]; //把当前字符串中的所有元素存放在字符数组中 char[] a=v.toCharArray(); //标记c数组存储的元素 int len=0; //遍历字符数组中的所有元素 for(int i=0;i<a.length;i++){ if(len>0&&a[i]=='#'){ len--; }else if(len==0&&a[i]=='#'){ continue; }else{ c[len]=a[i]; len++; } } return new String(c,0,len); } }