答题与解题(5)

Java SE专题

1、可将语句块或方法设为同步使用的语句是(A)
A、synchronized
B、static
C、abstract
D、final

解题:synchronized 用于方法或者代码块前,使此方法或者代码块变成同步的
static 用于声明静态变量
abstract 用于定义抽象类或者方法
final 用于声明常量,即只能赋值一次的变量

2、下列说法正确的是(C )
A、volatile,synchronized 都可以修改变量,方法以及代码块
B、volatile,synchronized 在多线程中都会存在阻塞问题
C、volatile能保证数据的可见性,但不能完全保证数据的原子性,synchronized即保证了数据的可见性也保证了原子性
D、volatile解决的是变量在多个线程之间的可见性、原子性,而sychroized解决的是多个线程之间访问资源的同步性

解题:synchronized关键字和volatile关键字比较:
volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

3、对于以下代码段,4个输出语句中输出true的个数是( C )。

class A{}

class B extends A{}

class C extends A{}

class D extends B{}

A obj = new D();

System.out.println(obj instanceof B);

System.out.println(obj instanceof C);

System.out.println(obj instanceof D);

System.out.println(obj instanceof A);
A、1
B、2
C、3
D、4

解题:A obj = new D(),由题得,D继承B继承A,而C继承A,所以答案就是3,多态得一种表现。

4、在一个基于分布式的游戏服务器系统中,不同的服务器之间,哪种通信方式是不可行的(A)?
A、管道
B、消息队列
C、高速缓存数据库
D、套接字

解题:管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

5、paint() 方法使用哪种类型的参数 ?( )
A、Graphics
B、Graphics2D
C、String
D、Color

解题:绘图函数,java.awt中的paint方法
public void paint(Graphics g)
Graphicslei类是所有图形的抽象基类

6、What results from the following code fragment?(C)
int i = 5;
int j = 10;
System.out.println(i + ~j);
A、Compilation error because”~”doesn’t operate on integers
B、-5
C、-6
D、15

解题:-n=n+1可推出n=-n-1,所以~10=-11再加5结果为-6

7、String与StringBuffer的区别。
A、String是不可变的对象,StringBuffer是可以再编辑的
B、字符串是常量,StringBuffer是变量
C、String是可变的对象,StringBuffer是不可以再编辑的
D、以上说法都不正确

解题:String, StringBuffer,StringBuilder的区别
java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。
1.可变与不可变
String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。
private final char value[];
String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
char[] value;
StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer();
不能通过赋值符号对他进行付值. , 如 sb = “welcome to here!”;//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法. sb.append(“hello”);
2.是否多线程安全
String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码:

1   public   synchronized  StringBuffer reverse() {
2       super .reverse();
3       return   this ;
4  }
5  
6   public   int  indexOf(String str) {
7       return  indexOf(str, 0);         //存在 public synchronized int indexOf(String str, int fromIndex) 方法
8  }

StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的 。
3.StringBuilder与StringBuffer共同点
StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。
抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(…)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。
效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。

8、以下集合对象中哪几个是线程安全的(CD)
A、LinkedList
B、ArrayList
C、Vector
D、Hashtable

解题:集合中线程安全的类有:vector,stack,hashtable,enumeration,除此之外均是非线程安全的类与接口

9、关于下面的一段代码,以下哪些说法是正确的:AD
public static void main(String[] args) {
String a = new String(“myString”);
String b = “myString”;
String c = “my” + “String”;
String d = c;
System.out.print(a == b);
System.out.print(a == c);
System.out.print(b == c);
System.out.print(b == d);
}
A、System.out.print(a == b)打印出来的是false
B、System.out.print(a == c)打印出来的是true
C、System.out.print(b == c)打印出来的是false
D、System.out.print(b == d)打印出来的是true

解题:A:a指向堆内存,b指向常量池,因此地址不相等,false
B:java有常量优化机制,c也指向常量池,且与b指向同一个,则a与c地址不相等,false;
C:b与c地址相等,true
D:d是c的副本,地址相同,所以b与d地址相等,true

10、下面有关Java的说法正确的是( ACDF )
A、一个类可以实现多个接口
B、抽象类必须有抽象方法
C、protected成员在子类可见性可以修改
D、通过super可以调用父类构造函数
E、final的成员方法实现中只能读取类的成员变量
F、String是不可修改的,且java运行环境中对string对象有一个对象池保存

解题:此题考察对概念的理解,解释一下错误的选项B错在必须,E选项被final的方法不能被调用

数组

1、对于不同的使用者,一个表结构既可以是栈,也可以是队列,也可以是线性表。A
A、正确
B、错误

解题:线性表可分为一般线性表和受限线性表。一般线性表也就是我们通常所说的“线性表”,可以自由的删除或添加结点。受限线性表主要包括栈和队列,受限表示对结点的操作受限制

2、下列给定程序中,函数fun的功能是:把形参a所指数组中的最小值放在元素a[0]中,接着把a所指数组中的最大值放在a[1]元素中;再把a所指数组元素中的次小值放在a[2]中,把a索取数组元素中的次大值放在a[3],以此类推。
例如:若a所指数组中的数据最初排列为:9,1,4,2,3,6,5,8,7;按规则移动后,数据排列为:1,9,2,8,3,7,4,6,5。形参n中存放a所指数组中数据的个数。
规定fun函数中的max存放的当前所找的最大值,px存放当前所找最大值得下标。 请在程序的下画线处填入正确的内容并将下画线删除,使程序得出正确的结果。
试题程序。

#include<stdio.h>
#define N 9
void fun(int a[ ], int n)
{
    int i, j, max, min, px, pn, t;
    for (i = 0; i < n - 1; i += 2)
    {
 
        max = min = __;
        px = pn = i;
        for (j = i + 1; j < n; j++)
        {
 
            if (max <  __)
            {
                max = a[j];
                px = j;
            }
 
            if (min > __ )
            {
                min = a[j];
                pn = j;
            }
        }
        if (pn != i)
        {
            t = a[i];
            a[i] = min;
            a[pn] = t;
            if (px == i)
                px = pn;
        }
        if (px != i + 1)
        {
            t = a[i + 1];
            a[i + 1] = max;
            a[px] = t;
        }
    }
}
int main( )
{
    int b[N] = {9, 1, 4, 2, 3, 6, 5, 8, 7};
    printf("\nThe original data:\n");
    for (int i = 0; i < N; i++)
        printf("% 4d", b[i]);
    printf("\n");
    fun(b, N);
    printf("\nThe data after mocinng \n");
    for (int i = 0; i < N; i++)
        printf("% 4d", b[i]);
    printf("\n");
}

A、0 a[i] a[i]
B、a[i] a[j] a[j]
C、0 a[j] a[j]
D、a[i] a[i] a[i]

解题:max与min不是赋初值,而是每一次循环均会重新赋值,且每一次循环i值加2,故应该每次赋给未排序的i序列的最左边的值。

3、在以下哪个操作中, 数组比链表更快?D
A、原地逆序
B、头部插入
C、返回头节点
D、返回随机节点

解题:数组的优点,查找O(1)

4、数组Q[0…m-1]用来表示一个循环队列, 用front指向队头元素,rear指向队尾元素的后一个位置 ,则当前队列中的元素数是。(队列总的元素数不会超过队列大小)A
A、(rear-front+m)% m
B、rear-front+1
C、rear-front-1
D、rear-front

解题:情况1 : size = rear - front 情况2: size = (rear - 0) + (m - front) = m + rear - front 综合:size = (m + rear -front) % m

5、若二维数组 a 有 m 列,则计算任一元素 a[i][j] 在数组中的位置公式为( )。
(假设 a[0][0] 位于数组的第一个位置上)D
A、im+j
B、j
m+i
C、im+j-1
D、i
m+j+1

解题:直接把a[0][0] 代入,即i = 0, j =0。只有i*m+j+1 = 1,位置和下标的区别,下标从0开始,位置从1开始,得出答案。

数组编程专题

1、给定一个按非递减顺序排序的整数数组 A,返回每个数字的平方组成的新数组,要求也按非递减顺序排序
在这里插入图片描述
解题思路:由题得出,我们需要将数组每一位上面的元素进行平方,然后进行重新排序,那么我们完全可以先得出平方数,然后将每一个数存入创建的一个新数组,然后运用Arrays.sort方法进行排序,就可以完成。
在这里插入图片描述
代码实现:

class Solution {
    public int[] sortedSquares(int[] A) {
        int n = A.length;
		int arr[] = new int[n];
		for(int i=0;i<n;i++) {
			arr[i]=A[i]*A[i];
		}
		Arrays.sort(arr);
		return arr;
    }
}

2、给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
在这里插入图片描述
**解题思路:**题目要求两数之和等于给定的target,那么我们可不可以遍历数组中的元素,使得遍历的这个元素等于target-这个元素,那么问题就迎刃而解,那肯定需要两个循环来完成,因为每次你都要从第一个i加第一个i之后的j,那么数组中所有的元素都进行两两相加。
在这里插入图片描述
代码实现:

public static void main(String[] args) {
		int[] A = {2,7,11,19};
		int[] is = new Test01().twoSum(A, 9);
		System.out.println(Arrays.toString(is));
	}

	public static int[] twoSum(int[] nums, int target) {
		
		for(int i=0;i<nums.length;i++ ) {
			for(int j=i+1;j<nums.length;j++) {
				if(nums[j]==target-nums[i]) {
					return new int[] {i,j};
				}
			}
		}
		throw new IllegalArgumentException("没有两元素之和等于target");
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值