系列文章目录
Java基础知识题(一)
Java基础知识题(二)
Java基础知识题(三)
Java基础知识题(四)
Java基础知识题(五)
文章目录
系列文章目录
模块1
单选题1
单选题2
单选题2
单选题4
单选题5
模块2
单选题1
单选题2
补充一:理解is-a,has-a,like-a以及use-a?
单选题3
补充二:线程Thread
多选题4
多选题5
前言
本文主要介绍十道Java当中的笔试基础题,以及相关Java知识的补充。以及线程与is-a、has-a、like-a、use-a介绍。
模块1
单选题1
1.关于类的叙述正确的是()。
A 在类中定义的变量称为类的成员变量,在别的类中可以直接使用
B 局部变量的作用范围仅仅在定义它的方法内,或者是在定义它的控制流块中
C 使用别的类的方法仅仅需要引用方法的名字即可
D 只要没有定义不带参数的构造函数,JVM都会为类生成一个默认构造函数
正确答案:B
参考答案:B 【解析】 A在类中定义的变量称为类的成员变量,在别的类中不可以直接使用局部变量的 C使用别的类的方法需要通过该类的对象引用方法的名字 D只要没有定义任何构造函数,JVM都会为类生成一个默认构造函数
知识点:Java
题友讨论:
A,类是一个封装,类的成员只能在类内部使用,外部需要 “对象名.变量名” 来引用。 B,正确,局部变量只在定义它的代码块或者函数内部可见 C,跟类的成员变量一样,需要指定对象才能引用 D,如果类没有构造方法,JVM会生成一个默认构造方法,如果定义了任意类型的构造方法,编译器都不会自动生成构造方法。
单选题2
2.已知如下类定义:
class Base {
public Base (){
//...
}
public Base ( int m ){
//...
}
public void fun( int n ){
//...
}
}
public class Child extends Base{
// member methods
}
如下哪句可以正确地加入子类中?
A private void fun( int n ){ //...}
B void fun ( int n ){ //... }
C protected void fun ( int n ) { //... }
D public void fun ( int n ) { //... }
正确答案:D
官方解析:暂无官方题目解析,去讨论区看看吧!
知识点:Java
题友讨论:
方法的重写(override)两同两小一大原则: 方法名相同,参数类型相同 子类返回类型小于等于父类方法返回类型, 子类抛出异常小于等于父类方法抛出异常, 子类访问权限大于等于父类方法访问权限。
A,B,C都会提示如下信息: Cannot reduce the visibility of the inherited method from Base 意思就是告诉你:不能降低从基类继承的方法的可见性。 那么,为什么不能降低可见性呢? 因为,每个子类的实例都应该是一个基类的有效实例,如果降低了方法的可见性,那么就相当于子类失去了一个父类的方法,这个时候,父类将不是一个有效的基类。 子类重写了父类的方法,子类的方法的权限修饰符不能比父类低,最好与父类一致。(public>protected>默认修饰符>private) 父类是public的,那么子类只能是public的
此处加入一段Java四种权限修饰符的优先级: Java当中四种权限修饰符的权限大小分别为:public>protected>默认>private。 方法和成员变量被不同的访问权限修饰符修饰时,会有不同的访问权限。 下面进行细节展开,具体介绍四种权限修饰符。 public:修饰符修饰的方法或成员变量对所有类都可见,任何人都可以访问。 protected:本包的其它类和所有子类可以访问。 默认:不加之外的3个修饰符即默认。在该情况下,仅本包可见,同一个包内的其他类的成员可以访问,而其它包中的成员不可以访问。 private:仅本类可以访问,类的创建者和内部方法可以访问,其它类不可以访问。 private:(同一个类) 默认:(同一个类、同一个包的子类无关类) protected:(同一个类、同一个包的子类无关类、不同包的子类) public:()同一个类、同一个包的子类无关类、不同包的子类、不同包的无关类
单选题2
3.选项中哪一行代码可以替换 //add code here 而不产生编译错误
public abstract class MyClass {
public int constInt = 5;
//add code here
public void method() {
}
A public abstract void method(int a);
B consInt=constInt+5;
C public int method();
D public abstract void anotherMethod(){}
正确答案:A
你的答案:B
参考答案: A是抽象方法,抽象类可以包含抽象方法,也可以不包含,实现重载。(√) B 在类中不能constInt = constInt + 5(×) C 返回值不能作为重载的依据(×) D 有方法体的不能作为抽象函数(×)
知识点:Java
题友讨论:
A:抽象类可以包含抽象方法 B:类中定义成员和方法,不能直接进行运算,可以写在代码块{}或者静态代码块中static{}中 C: 与第四行想要构成重载,二者区别是返回类型,但是返回类型不能作为重载的依据 D: 该方法使用abstract修饰,是抽象方法,但是他有方法体(带有{}的就是方法体,即使里面是空的),就不能作为抽象方法 1.抽象类不能实例化,所以必须被继承 2.抽象类可以不含抽象方法,但含有抽象方法的类一定是抽象类 3.继承抽象类的类必须实现抽象类中的抽象方法或将自己声明为抽象类 4.抽象方法没有方法体,具体实现由子类决定
单选题4
4.有如下一段程序:
public class Test{
private static int i=1;
public int getNext(){
return i++;
}
public static void main(String [] args){
Test test=new Test();
Test testObject=new Test();
test.getNext();
testObject.getNext();
System.out.println(testObject.getNext());
}
}
请问最后打印出来的是什么?()
A 2
B 3
C 4
D 5
正确答案:B
你的答案:A
参考答案:return i++, 先返回i,然后i+1; 第一次调用getNext()方法时,返回的是1,但此时i=2; 第二次调用 getNext()方法时,返回的是2,但此时i=3; 第三次调用 getNext()方法时,返回的是3,但此时i=4;
知识点:2015、Java、Java工程师
题友讨论:
该题主要考察的是static属性和i++操作。 因为i是static的,是类属性,所以不管有多少对象,都共用的一个变量。这里getNext()方法被调用了三次,所以进行了三次i++操作。 但是由于getNext()操作的返回是:return i++; i++是先返回,后++,所以在println是,已经返回了i(此时i为3),再进行自增的,所以这里结果为3 return i++; return ++i; 两者是不一样的。 前者返回i,然后i = i+1; 后者直接范围 i+1;
单选题5
5.Which statement is true for the class java.util.ArrayList?
A The elements in the collection are ordered.
B The collection is guaranteed to be immutable.
C The elements in the collection are guaranteed to be unique.
D The elements in the collection are accessed using a unique key.
E The elements in the collections are guaranteed to be synchronized.
5.对于 java.util.ArrayList 类,哪个语句为 true?
A 集合中的元素是有序的。
B 集合保证是不可变的。
C 集合中的元素保证是唯一的。
D 使用唯一键访问集合中的元素。
E 集合中的元素保证是同步的。
正确答案:A
你的答案:D
参考答案:A Serializable, Cloneable , Iterable <E>, Collection <E>, List <E>, RandomAccess List接口是有序的,通常允许重复,因此可以确定A对,C错;ArrayList是实现List 接口的大小可变数组,所以B错;D是Map的特性,所以D错;查看手册: Note that this implementation is not synchronized. ArrayList的实现是不是线程同步的,所以E错。
知识点:Java、数组、链表
题友讨论:
元素在集合中有序,指的是元素插入过程中记录了元素的插入顺序
ArrayList有序指的是元素保持插入时的先后顺序
1.数组大小指定之后是不可变的,集合是可变的;
2.List中元素可以重复,Set不可重复;
3.ArrayList的存储结构是线性的,动态分配内存,有序的,可以重复,优点是可以随机访问快;
4.ArrayList是线程不安全的,不需要线程同步
ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处:
1> 动态的增加和减少元素
2> 实现了ICollection和IList接口
3> 灵活的设置数组的大小
Synchronized属性指示当前的ArrayList实例是否支持线程同步,而ArrayList.Synchronized静态方法则会返回一个ArrayList的线程同步的封装。
如果使用非线程同步的实例,那么在多线程访问的时候,需要自己手动调用lock来保持线程同步
ArrayList和Vector是类似的:
(1)两者都是基于索引的,内部有一个数组支持
(2)两者都维护插入的顺序
(3)两者都允许null值
不同之处在于:
(1)ArrayList是不同步的,而Vector是同步的,所以ArrayList更高效,不会过载
(2)ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表,当需要在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList
模块2
单选题1
1.当点击鼠标或者拖动鼠标时,触发的事件是下列的哪一个?()
A KeyEvent
B AxtionEvent
C ItemEvent
D MouseEvent
正确答案:D
你的答案:A
知识点:Java
题友讨论:
接口 MouseListener
用于接收组件上“感兴趣”的鼠标事件(按下、释放、单击、进入或离开)的侦听器接口。(要跟踪鼠标移动和鼠标拖动,请使用 MouseMotionListener。)
void | mouseClicked(MouseEvent e) 鼠标按键在组件上单击(按下并释放)时调用。 |
---|---|
void | mouseEntered(MouseEvent e) 鼠标进入到组件上时调用。 |
void | mouseExited(MouseEvent e) 鼠标离开组件时调用。 |
void | mousePressed(MouseEvent e) 鼠标按键在组件上按下时调用。 |
void | mouseReleased(MouseEvent e) 鼠标按钮在组件上释放时调用。 |
触发ActionEvent这个事件的动作有:
-
1.点击按钮。
-
2.双击列表中选项。
-
3.选择菜单项。
-
4.在文本框中输入回车。
单选题2
2.在面向对象编程里,经常使用is-a来说明对象之间的继承关系,下列对象中不具备继承关系的是?()
A 手机与小米手机
B 企业家与雷军
C 编程语言与Java
D 中国与北京
正确答案:D
知识点:Java
题友讨论:
补充一:理解is-a,has-a,like-a以及use-a?
1.is-a关系:表示子类和父类之间的继承关系。比如:一个Student类,继承了父类Person类,我们可以说一个学生就是一个人,也就是Student is a Person。
2.has-a关系:表示的是从属关系。比如:一个类有多个对象(人有多种职业,学生是其中的一种),一个对象有多种属性(学生有班级,学号,成绩等等属性),这些就是从属关系。
3.like-a关系:表示的是接口的实现类和接口之间的关系。比如:我们都说UZI是一个神一样的男人,简单来说就是UZI like a 神,这里“UZI”就是接口的实现类,“神”就是接口(因为接口可以理解为就是一种抽象类),我们可以推出like-a关系,就是具体和抽象之间的关系。
4.use-a关系:表示的是一个类和另外一个类的属性或方法之间的关系。比如:一个类里面new了另外一个类的对象,我们就可以使用这个对象调用另一个类的方法或属性,这就是use-a关系。通俗的理解就是:你手机没电了,又没带充电宝,所以你就借用了你兄弟的充电宝。你用的不是自己的,是别人的。
其他版本解释:
Is-a:
是a:A Is B:A是B(继承关系,继承)。
has-a:
有a:A has B:A有B(从属关系,聚合)。
like-a:
像a:A like B:A像B(组合关系,接口)。
关于Is-a、has-a、like-a的使用场景:
如果A,B是Is-a关系,那么应该使用继承,例:玻璃杯、塑料杯都是杯子。
如果A,B是has-a关系,那么应该是用聚合,例:汽车由发动机,底盘,车身,电气设备等组成,那么应该把发动机,底盘这些类聚合成汽车。
如果A,B是like-a关系,那么应该使用组合,例:空调继承于制冷机,但它同时有加热功能,那么你应该把让空调继承制冷机类,并实现加热接口。
单选题3
3.当编译并运行下面程序时会发生什么结果()
public class Bground extends Thread{
public static void main(String argv[]){
Bground b = new Bground();
b.run();
}
public void start(){
for(int i=0;i<10;i++){
System.out.println("Value of i = "+i);
}
}
}
A 编译错误
B 运行错误
C 编译通过并输出0到9
D 编译通过,但无输出
正确答案:D
你的答案:C
知识点:Java、Java工程师、2017
题友讨论:
对于线程而言,start是让线程从new变成runnable。run方法才是执行体的入口。 但是在Thread中,run方法是个空方法,没有具体实现。 Bground继承了Thread,但是没有重写run方法,那么调用run方法肯定是无输出。 首先继承Thread,然后调用run方法,bgroud并没有重写run方法,那么就是调用父类Thread的run方法。 然后查看父类代码
@Override
public void run() {
if (target != null) {
target.run();
}
}
private Runnable target; 其中target是Runnable对象 明显target并没有显示初始化。 所以不会有显示。 一般target的初始化是这样的,将runnable对象作为thread参数进行线程的创建
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
再看init()
private void init(ThreadGroup g, Runnable target,String name,long stackSize) {
init(g, target, name, stackSize, null);
}
在init(g, target, name, stackSize, null),可以找到this.target = target;
此时进行了初始化。
最后说一说,Thread 的执行过程,Theard的启动方法是start().线程类调用start();然后执行start0()本地方法,然后就没办法再追溯下去了。
start我听过别人说,是一个准备工作(比如你要吃苹果,不得先洗一下,真正吃时间是洗完后),并没有获得cpu,调用run()才是获得了cpu。
补充二:线程Thread
用户线程的优点:
1 可用于不支持线程技术的操作系统,因为在进程中有其私有的线程控制块(TCB)列表,用来记录各个线程的信息(如线程的寄存器,栈指针,PC)。
2 线程切换由用户级线程库函数完成,不需要用户态与内核态的切换,速度很快。
用户线程的缺点:
1.由于操作系统不参与线程调度,一个线程发起系统调用而阻塞,就会导致这个进程中的其他用户线程都无法执行
2.当一个进程开始运行时,除非它主动交出CPU的使用权,不然进程中的其他用户线程无法运行,因为用户态的线程没法打断当前运行中的线程,它没有这个特权,只要操作系统才有,但是用户线程不是由操作系统管理的。
那内核线程如何理解?存在什么优势和缺陷?
内核线程是由操作系统管理,线程对应的TCB自然是放在操作系统里的,这样线程的创建、终止和管理都是由操作系统负责。线程控制块,线程表 在内核空间中。进程控制块,线程表在内核空间
内核线程的优点:
1.在一个进程当中,如果某个内核线程发起系统调用而被阻塞,并不会影响其他内核线程的运行
2.分配给线程,多线程的进程获得更多的CPU运行时间。
内核线程的缺点:
1.在支持内核线程的操作系统中,由内核来维护进程和线程的上下文信息,如PCB和TCB
2.线程的创建、终止和切换都是通过系统调用的方式来进行的,因此对于系统来说,系统开销比较大。
如何理解轻量级进程?
轻量级进程(LWP)是内核支持用户线程,一个进程可以有一个或多个轻量级进程,轻量级进程都是由一个内核线程支持的,每个轻量级进程和内核线程是一对一映射的。
LWP只能由内核管理并像普通进程一样被调度。Linux内核是支持LWP的典型例子。
Lwp与普通线程的区别在于它只是一个最小的执行上下文和调度程序所需的统计信息。一个进程代表程序的一个实例,而轻量级进程代表程序的执行线程,因为一个执行线程不像进程那样需要那么多状态信息,所以LWP也不带有这样子的信息。
在LWP上也是可以使用用户线程,LWP与用户线程的对应关系有三种:
1:1模式: 一个LWP对应一个用户线程,再对应到一个内核线程
优点:实现并行,当一个LWP阻塞,不会影响其他LWP。
缺点:每个用户线程,就产生一个内核线程,创建线程的开销比较大。
N:1模式:一个LWP对应多个用户线程,再对应一个内核线程。
优点:用户线程要开几个都没问题,且上下文发生用户空间,切换效率高。
缺点:一个用户线程如果阻塞了,则整个线程都将会阻塞,另外在多核CPU中,是没有办法充分利用CPU的。
M:N模式:多个LWP对应多个用户线程,根据前面的的两个模型混搭在一起形成M: N模型,该模型提供了两级控制,多个用户线程对应到多个LWP。
优点:综合了前面两种模式的优点,大部分的线程上下文发生在用户空间,且多个线程又可以充分利用多核CPU的资源。
多选题4
4.在你面前有一个n阶的楼梯,你一步只能上1阶或2阶。请问,当N=11时,你可以采用多少种不同的方式爬完这个楼梯(),当N=9时呢呢()?
A 11
B 144
C 55
D 89
正确答案:BC
你的答案:AD
知识点:Java、Java工程师、C++工程师、测试工程师、2019、测试开发工程师
题友讨论:
#include<iostream>
using namespace std;
int p(int n){
if(n<=1)
return 1;
if(n==2)
return 2;
return p(n-2)+p(n-1);
}
int main(){
int num;
cin>>num;
int result=p(num);
cout<<result<<endl;
return 0;
}
当台阶只有一阶时,只能走一步,只有一种走法。
当两级台阶时,可以走一步,也可以一次走两步,有两种走法。
当三级台阶时,可以走一步,走三次。可以先走一步,再两步。也可以,先两步,再一步。总共三种方法。
可以看到当台阶是3时,第1级台阶选中之后(一种),剩下可以走的方式恰好是台阶为2时的总数,总的数量为前两个之和,所以是f(3)=f(1)+f(2)。
即,f(n)=f(n-2)+f(n-1),总结起来刚好是一个斐波那契数列。
高中概率论
走2阶台阶的次数可能会出现0-5种情况,计算每一次总步数中的哪几步是走2阶台阶的所有可能
C(0,11)+C(1,10)+C(2,9)+C(3,8)+C(4,7)+C(5,6)=1+10+36+56+35+6=144
C(N,M)表示从M个数中,随机抽取N个数的所有情况
public class Test {
public static int Iadder (int n){
if (n == 1){
return 1;
}else if (n == 2){
return 2;
}else{
return Iadder(n-1)+Iadder(n-2);
}
}
public static void main(String[ ] args){
System.out.println(Iadder(11) + "|" + Iadder(9));
}
}
//非递归版
private static int JumpFloor(int n) {
int[] arr = new int[n];
//0阶0种跳法
arr[0] = 0;
//1阶1种跳法
arr[1] = 1;
//2阶2种跳法
arr[2] = 2;
int i;
for (i = 3; i < arr.length; i++) {
//根据斐波拉契数列,后一位的跳法等于前两位的和
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[i - 1] + arr[i - 2];
}
多选题5
5.在JAVA中,下列哪些是Object类的方法()
A synchronized()
B wait()
C notify()
D notifyAll()
E sleep()
正确答案:BCD
你的答案:BE
参考答案:A synchronized Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 B C D 都是Object类中的方法 notify(): 是唤醒一个正在等待该对象的线程。 notifyAll(): 唤醒所有正在等待该对象的线程。 E sleep 是Thread类中的方法 wait 和 sleep的区别: wait指线程处于进入等待状态,形象地说明为“等待使用CPU”,此时线程不占用任何资源,不增加时间限制。 sleep指线程被调用时,占着CPU不工作,形象地说明为“占着CPU睡觉”,此时,系统的CPU部分资源被占用,其他线程无法进入,会增加时间限制。
知识点:Java
题友讨论:
此处可以查看这篇文章看完整的object介绍
Java当中的object介绍以及相关方法介绍
总结
以上就是今天的内容~
欢迎大家点赞👍,收藏⭐,转发🚀,
如有问题、建议,请您在评论区留言💬哦。
最后:转载请注明出处!!