题目整理

一、以下程序运行的结果为(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();
   }
}

题目整理_第1张图片

分析:

  • 此处是类对方法的调用,不是对象对方法的调用。
  • 方法是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的操作是不属于服务端操作的()?

题目整理_第2张图片

八、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 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:

  • 对象表示为键值对
  • 键和值必须用双引号
  • 数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组

你可能感兴趣的:(题目整理)