第一题 类加载
一个Java源程序文件中定义几个类和接口,则编译该文件后生成几个以.class为后缀的字节码文件。(A)
A 正确 B错误
解析:
// 父类 class yanhe { public final static void ha(){ System.out.println("父类"); } // 匿名内部类 class xiaoxi{ } } //接口 interface USB{ } public class timu extends yanhe{ public static void main(String[] args){ ha(); final int a = 10; } }
编译过后的输出文件如下:
可以看到,有匿名内部类的class文件、接口USB的class文件以及父类的class文件
第二题 关于集合
下列哪个说法是正确的?(D) A.ConcurrentHashMap使用synchronized关键字保证线程安全 B.HashMap实现了Collection接口 C.Array.asList方法返回java.util.ArrayList对象 D.SimpleDateFormat是线程不安全的
解析:
A .ConcurrentHashMap实际上是HashMap的升级版,使用segment来分段和管理锁,并不是synchronized;
B:下图是HashMap类继承体系图,可以看到HashMap实现了Map接口,而Map接口与Collection接口没有关系。Collection集合体系图
Map集合继承体系图
ArrayList.asList()是个坑
C.Arrays.asList()返回的对象不支持add()、remove()、clear()等方法。 这是因为Arrays.asList()是个坑。Arrays.asList方法返回的ArrayList 对象来自java.util.Arrays.ArrayList,并不是我们熟悉的java.util.ArrayList, 这个ArrayList是Arrays的一个内部类,这个类并没有实现add()、remove()方法, 而是直接使用它的父类AbstractList的相应方法,而AbstractList中的add()和 remove()是直接抛出java.lang.UnsupportedOperationException异常的! D.SimpleDateFormat是线程不安全的,Java8之后提出了一个新的格式安全的DateTimeFormatter
第三题 重载与重写
将下列哪个代码(A、B、C、D)放入程序中标注的【代码】处将导致编译错误?(B) class A{ public float getNum(){ return 3.0f; } } public class B extends A{ 【代码】 } A: public float getNum(){return 4.0f;} // 满足返回类型与形参列表一致,访问修饰符也一样(重写) B: public void getNum(){} //返回类型不一样,无法形成重写 C: public void getNum(double d){}//返回值和参数列表不同,属于类B独有的方法,不是重写 D: public double getNum(float d){return 4.0d;}//返回值和参数列表不同,属于类B独有的方法,不是重写 C和D在类B中是方法重载的体现
解析:
方法重载:java 中允许同一个类中, 多个同名方法的存在, 但要求 形参列表不一致!
方法重写:方法重写也叫方法覆盖,是子类重写父类中的方法。
两者区别:
名称 发送范围 方法名 形参列表 返回类型 修饰符 重载 本类 必须一样 类型、个数、
顺序至少一个不一样
无要求 无要求 重写 父子类 必须一样 相同 相同或者是父类返回类型的子类
不能缩小父类的访问范围
第四题 继承
在java中,下列对继承的说法,正确的是(A)
A:子类能继承父类的所有成员
B:子类继承父类的所有非私有方法和状态
C:子类只能继承父类的public方法和状态
D:子类只能继承父类的方法
这道题其实很有迷惑性!
在我们长期接收的思想便是子类是无法调用父类中的私有成员方法和变量的,这就让许多人认为子类无法继承父类的私有实现,其实子类是可以继承父类的所有东西,只不过对于父类私有的属性和方法子类只是拥有,却没有使用的权限,但利用反射时可以调用。
第五题 构造器
如果Child extends Parent,那么正确的有(BCD)? A:如果Child是class,且只有一个有参数的构造函数,那么必然 会调用Parent中相同参数的构造函数 B:如果Child是interface,那么Parent必然是interface C:如果Child是interface,那么Child可以同时extends Parent1, Parent2等多个interface D:如果Child是class,并且没有显示声明任何构造函数,那么此时 仍然会调用Parent的构造函数 解析: A:子类构造器第一行都默认为super(),默认调用父类的无参构造。一旦父类没有无参构造, 则子类需要显示的声明调用父类的哪个有参构造。至于调用父类的什么构造方法,与子类构造方法无关。 B:接口只能继承接口(java 接口不可以继承类) C:接口是可以多继承的,但类不可以 D:子类的构造方法都默认为super()去调用父类的无参构造(这个super()调用父类无参构造时被省略了)
第六题 Map接口
9.对 Map 的用法,正确的有:(CD) A:new java.util.Map().put("key" , "value") ; Map是一个接口,不能被实例化 B:new java.util.SortedMap().put("key" , "value") ; SortedMap是一个接口,不能被实例化 C:new java.util.HashMap().put( null , null ) ; HashMap是基于哈希实现Map接口的类,可以存储null键和null值 D:new java.util.TreeMap().put( 0 , null ) ; TreeMap是通过红黑树实现Map接口的类,key不可以为null, 会报空指针异常,value可以为null
以下是Shein的笔试题目
第一题: Synchronized 解析
关于下面一段Java 代码的说法正确的是() publie class Test{ private synchronized void a()} private void b(){ synehronized (this){ } } private synchronized static void c(){ } private void d(){ synchronized(Test.class) } }
A.同一个对象,分别调用方法a和c,锁住的是同一个对象
B.同一个对象, 分别调用方法a、b、c, 锁住的不是同一个对象
C.同一个对象, 分别调用方法b和c, 锁住的不是同一个对象
D.同一个对象, 分别词用方法a和b,锁住的是同一个对象
答案: BCD非静态方法和this锁的都是对象实例
而静态方法和.Class锁的都是Class对象
所以ab,是一个对象,cd是一个对象,可我总感觉d选项说的有问题,abc方法确实锁的不是一个对象,ab是一个对象,d是另一个对象,个人认为B选项不够严谨。
第二题 Hash冲突
解决Hash冲突的方法描述错误的有(D)? A.开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中 形成一个探查(测)序列。沿此序列逐个单元地查找,直到找到给定 的关键字,或者碰到一个 开放的地址(即该地址单元为空)为止。 B.拉链法解决冲突的做法是:将所有关键字为同义词的结点链接在同一个单链表中 C.拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短 D.当结点规模较大时,开放定址法较为节省空间
解析:
相比于开放定址法,拉链法的优点:
①拉链法处理冲突简单,且无堆积现象,即非同义词决不会发生冲突,因此平均查找长度较短;
②由于拉链法中各链表上的结点空间是动态申请的,故它更适合于造表前无法确定表长的情况;
③开放定址法为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间。而拉链法中可取α≥1,且结点较大时,拉链法中增加的指针域可忽略不计,因此节省空间。
第三题 关于 并发代码
两个线程并发执行以下代码, 假设a是全局变量,那么以下输出哪个是可能的?(AB) int a=1; void foo(){ ++a; printf("%d",a); } A 3 2 B 2 3 C 3 3 D 2 2
答案是;ABCD 假设线程x和y同时执行,x和y可随时被抢占,a的初始值为1 A:3, 2 y先执行++a,a为2; y再执行printf,a入栈,在打印到终端之前切换到x x执行++a,a为3; x执行printf,输出3;再切换到y y执行打印,输出2 B:2 3 x先执行++a,a为2; x再执行printf,输出2;切换到y y执行++a,a为3; y执行printf,输出3; C:3 3 x先执行++a,a为2;切换到y y执行++a,a为3; y执行printf,输出3;切换到x x执行printf,输出3 D:2 2 类似C, 执行++a操作但没有写回到内存 这里关键有两点: (1)两个线程可随时被抢占 (2)++a和printf不是原子指令,可随时被打断;特别注意函数printf,a作为参数压栈后,a再变化则不会影响输出(printf实际打印的是压栈的参数,是值拷贝的栈变量)
第四题 JDK17新特性
JDK17包含以下哪些特性? A.协程 B.Sealed Classes(密封类) C.CMS GC D.ZGC
答案 B JDK17的新特性列表
假设MySQL数据库表:
如下哪些sql语句查询能较好的利用索引?()
A.select b from WHERE b like ‘aaa%’; B.select a,b from T WHERE a=‘2015-10-25’ ORDER BY b ASC,c ASC; C.select a,b,c from T WHERE a=‘2015-10-25’ ORDER BY b ASC; D.select a,b,c from T WHERE a=‘2015-10-25’ ORDER BY a,b; 答案:AD 一、什么是索引: 简单的来说,建立索引在进行数据库操作的时候不需要全盘一条条的扫描,删选出符合的记录, 索引内部自己有一套优化算法,因此借助索引来对数据库进行操作可以提高查询的效率。 二、什么时候建立的索引将失效或效率不高(情况有很多,这里列举常见的几种, 假设在字段name上建立了索引): 1、使用了运算符!=,以及关键字not in, not exist等,认为产生的结果集很大,往往导致 引擎不走索引而是走全盘扫描 2、对索引字段使用了函数,如where substr(name, 1, 3)=‘mark’, 导致索引无效 3、使用like和通配符,第一个字符是%将导致索引失效,如where name like "%ark“ (A正确) 三、order by与索引 首先利用where进行数据查询,这一步是免不了的,至于这一步有没有利用索引暂时不考虑,关键是在获取 所有符合的记录后还需要进行排序,看看order by是如何利用索引的。 如果order by中的字段有 建立索引同时: 1、该字段没有出现在where中,则在排序的时候需要正常排序,默认order by是升序排序, 故索引没有对排序产生有利帮助 (B,C错误) 2、该字段同时同时出现在where中,则在获取记录后不进行排序,而是直接利用索引, 效率变高。(D正确)
编程题目一 MySQL 查询语句-子查询
现在有知乎问答创作情况表answer_tb如下,其中 answer_date表示创作日期 author_id指创作者编码 issue_id表示问题id char_len 表示回答字数: 请你统计11月份日人均回答数量(回答问题数目/答题人数) 按照回答日期排序,结果保留两位小数
SELECT a.answer_date, ROUND((a.issue/a.author), 2) AS per_num
FROM (SELECT answer_date, COUNT(issue_id) AS issue, COUNT(DISTINCT author_id) author FROM answer_tb GROUP BY answer_date) a;select a.answer_date, round((a.issue/a.author_number),2) as per_num from (select answer_date, count(issue_id) as issue , count(distinct author_id ) as author_number from answer_date group by answer_date) a;
IO流
1. 下面哪个流类属于面向字符的输入流? (D)
A. BufferedWriter
B. FileInputStream
C. ObjectInputStream
D. InputStreamReader
解析:
以 InputStream(输入)/OutputStream(输出)为后缀的是字节流;
以Reader(输入)/Writer(输出)为后缀的是字符流。
在java.io包中,可指定以某种编码(UTF-8,GBK等)读取数据的类是— InputStreamReader
流的输入输出属于IO操作,使用后一定需要手动关闭 字符流和字节流的类都是位于java.io包中的 字符流——Reader Writer 字节流 Stream
序列化
阅读 Shape 和 Circle 两个类的定义。在序列化一个 Circle 的对象 circle 到文件时,下面哪个字段会被保存到文件中?(B)
class Shape { public String name; } class Circle extends Shape implements Serializable{ private float radius; transient int color; public static String type = "Circle"; }
A. name B. radius C. color D. type
知识点: java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
什么是 Java 序列化,如何实现 Java 序列化?
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。
序列化的实现:将需要被序列化的类实现 Serializable 接口,该接口没有需要实现的方法, implements Serializable 只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
关于union 与 union all 的区别
结果 速度 union 不含有重复的记录 慢(要对结果进行去重) union all 含有重复的记录 快
Java中,数据类型分为基本数据类型(或叫做原生类、内置类型)和引用数据类型。原生类是指基本数据类型。
数组不是原生类,java中的数组是对象。在Java编程语言中,数组是动态创建的对象,可以赋值给Object类型的变量。Object类的所有方法都可以在数组上调用