一、以下程序运行的结果为(run main)
public class Example extends Thread{
@Override
public void run(){
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.print("run");
}
public static void main(String[] args){
Example example=new Example();
example.run();
System.out.print("main");
}
}
解析:
这个类虽然继承了Thread类,但是并没有真正创建一个线程。
创建一个线程需要覆盖Thread类的run方法,然后调用Thread类的start()方法启动
这里直接调用run()方法并没有创建线程,跟普通方法调用一样,是顺序执行的。
二、泛型
1、创建泛型对象的时候,一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹配的异常。
2、JVM如何理解泛型概念 —— 类型擦除。
事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。
处理方法很简单,我们叫做类型变量T的擦除(erased) 。
总结:泛型代码与JVM
- 虚拟机中没有泛型,只有普通类和方法。
- 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
- 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。
- 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。
三、有关下述Java代码描述正确的选项是__运行正常,输出testMethod__。
public class TestClass {
private static void testMethod(){
System.out.println("testMethod");
}
public static void main(String[] args) {
((TestClass)null).testMethod();
}
}
分析:
- 此处是类对方法的调用,不是对象对方法的调用。
- 方法是static静态方法,直接使用"类.方法"即可,因为静态方法使用不依赖对象是否被创建。
- null可以被强制类型转换成任意类型(不是任意类型对象),于是可以通过它来执行静态方法。
- 非静态的方法用"对象.方法"的方式,必须依赖对象被创建后才能使用,若将testMethod()方法前的static去掉,则会报空指针异常 。此处也验证了2)的观点
- 当然,不管是否静态方法,都是已经存在的,只是访问方式不同。
四、释放锁
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()的线程有可能在进入到可执行状态后马上又被执行。只是通知调度器自己可以让出cpu时间片,但只是建议,调度器也不一定采纳 。
yield()只能使同优先级或更高优先级的线程有执行的机会。
4.join方法
join()等待该线程终止。join()有资格释放资源其实是通过调用wait()来实现的 。
等待调用join方法的线程结束,再继续执行。
如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。
五、编译java程序的命令文件是(javac )
- javac.exe是编译功能javaCompiler
- java.exe是执行程序,用于执行编译好的.class文件
- javadoc.exe用来制作java文档
- jdb.exe是java的调试器
- javaprof.exe是剖析工具
六、接口不能扩展(继承)多个接口。(× )
Java中类是单继承,但接口可以多继承。Interfere1 extends Interface2,Interface3...
七、socket
socket编程中,accept/listen/connect/close,哪个socket的操作是不属于服务端操作的()?
八、JDK中提供的java、javac、jar等开发工具也是用Java编写的。(√)
除了jre中的JVM不是用java实现的,jdk的开发工具包应该都是用java写的 。
九、匿名内部类不可以定义构造器。(√)
由于构造器的名字必须与类名相同,而匿名类没有类名,所以匿名类不能有构造器。
十、正则表达式
1.什么是正则表达式的贪婪与非贪婪匹配
如:
String str="abcaxc";
Patter p="ab*c";
- 贪婪匹配:正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到:abcaxc(ab*c)。
- 非贪婪匹配:就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到:abc(ab*c)。
2.编程中如何区分两种模式
默认是贪婪模式;在量词后面直接加上一个问号?就是非贪婪模式。
- 量词:{m,n}:m到n个
- *:任意多个
- +:一个到多个
- ?:0或一个
- 以上来自博主的博客,然后这道题目
- .表示除\n之外的任意字符
- *表示匹配0-无穷
- +表示匹配1-无穷
- (?=Expression) 顺序环视,(?=\\()就是匹配正括号
懒惰模式正则:src=".*? (?=\\()) "
结果:北京市
因为匹配到第一个"就结束了一次匹配。不会继续向后匹配。因为他懒惰嘛。
十一、JSON
在 JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:
- 对象表示为键值对
- 键和值必须用双引号
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组