目录
一、选择题
1.执行如下程序,输出结果是( 2 24 46 6)
class Test
{
private int data;
int result = 0;
public void m()
{
result += 2;
data += 2;
System.out.print(result + " " + data);
}
}
class ThreadExample extends Thread
{
private Test mv;
public ThreadExample(Test mv)
{
this.mv = mv;
}
public void run()
{
synchronized(mv)
{
mv.m();
}
}
}
class ThreadTest
{
public static void main(String args[])
{
Test mv = new Test();
Thread t1 = new ThreadExample(mv);
Thread t2 = new ThreadExample(mv);
Thread t3 = new ThreadExample(mv);
t1.start();
t2.start();
t3.start();
}
}
解释:
Test mv =newTest()声明并初始化对data赋默认值
使用synchronized关键字加同步锁线程依次操作m()
t1.start();使得result=2,data=2,输出即为2 2
t2.start();使得result=4,data=4,输出即为4 4
t3.start();使得result=6,data=6,输出即为6 6
System.out.print(result +" "+ data);是print()方法不会换行,输出结果为2 24 46 6
2.要使对象具有序列化能力,则其类应该实现如下哪个接口()。
A java.io.Serializable B java.lang.Cloneable C java.lang.CharSequence D java.lang.Comparable
解释:
java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法。只是用于标志此接口的实现类可以被序列化与反序列化。
java.lang.Cloneable接口是一个标志性接口,在接口内部没有定义任何属性与方法。以指示Object.clone()方法可以合法地对该类实例进行按字段复制。
java.lang.CharSequence接口对许多不同种类的char序列提供统一的只读访问接口。CharSequence是char值的一个可读序列。
java.lang.Comparable接口,此接口强制对实现它的每个类的对象进行整体排序,此序列被称为该类的自然排序
3.下列选项中属于面向对象设计方法主要特征的是( )。
A 、继承 B、 自顶向下 C、 模块化 D、 逐步求精
解释:面向对象是一种设计方法,题目问的正是这种设计方法的特征。即面向对象的主要特征:封装、继承、多态
4.关于下列程序段的输出结果,说法正确的是:( )
public class MyClass{
static int i;
public static void main(String argv[]){
System.out.println(i);
}
}
A、 有错误,变量i没有初始化。 B、 null C、1
解释:
成员变量:包括实例变量和类变量, 类变量在不设置初始值时,会进行默认值赋值,而局部方法中声明的局部变量则必须进行初始化,他不会进行默认值赋值。
i为成员变量,有默认的初始值,如果定义在方法内部,就没有初始值。
另:成员变量和局部变量的区别:https://blog.youkuaiyun.com/Aug_IK/article/details/116135096
5.下列代码的执行结果是:( 1和1.0 )
public class Test3{
public static void main(String args[]){
System.out.println(100%3);
System.out.println(100%3.0);
}
}
解释:
100对3取余,两者都是int型,所以结果也是int型,也就是1
100对3.0取余,虚拟机会对100进行转换,转换成100.0,也就是double型,结果也就是double型,也就是1.0
在基本 JAVA 类型中,如果不明确指定,整数型的默认是int 类型,带小数的默认是double类型。
数值类型之间的合法转换:6 个实心箭头,表示无信息丢失的转换; 有 3 个虚箭头, 表示可能有精度损失的转换。
6.方法通常存储在进程中的哪一区(方法区)
解释:JVM内存五大区
1.线程私有:
1.程序计数器:用于指示当前线程所执行的节码执行到第几行;每个线程都有一个;
2.虚拟机栈:一个线程的每个方法在执行的时候都会创造一个栈帧,存储局部变量表,操作站,动态链接,方法入口,当每个方法被调用的时候,栈帧入栈,方法执行完后,栈帧出栈。
3.本地方法栈:本地方法栈在作用,运行机制,异常类型等方面和虚拟机栈相同,区别是:虚拟机栈执行的是Java方法,而本地方法栈执行native方法,
2.线程共享:
1.堆区:堆区是用来存储对象实例。
2.方法区:方法区是线程共享,用于存储已经被虚拟机加载的类信息,包括版本,field,方法,接口等信息,final常量,静态变量,编译器及时编译的代码等。方法区上执行垃圾回收很少,所以方法区也被称为永久代。
7.不考虑反射,关于私有访问控制符 private 修饰的成员变量,以下说法正确的是()
A、 可以三种类所引用:该类自身、与它在同一包中的其他类,在其他包中的该类的子类
B、 可以被两种类访问和引用:该类本身、该类的所有子类
C、 只能被该类自身所访问和修改
D、 只能被同一个包中的类访问
解释:
四种访问权限:https://blog.youkuaiyun.com/Aug_IK/article/details/112968222
8.Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( 12 ,-11 ).
解释:Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11而不是-12。
floor : 意为地板,指向下取整,返回不大于它的最大整数
ceil : 意为天花板,指向上取整,返回不小于它的最小整数
round : 意为大约,表示“四舍五入”,而四舍五入是往大数方向入。
需要强调的是,Math.round的“四舍五入”和平常的“小于4不进位,大于4则进位”是不一样的;参考:
(1)负数
Math.round(-11.6) = -12
Math.round(-11.5) = -11
(2)正数
Math.round(11.5) = 12
Math.round(11.6) = 12
9.假设 A 类有如下定义,设 a 是 A 类的一个实例,下列语句调用哪个是错误的?()
public class A
{
public int i;
static String s;
void method1(){}
static void method2(){}
}
A、 System.out.println(a.i); B、 a.method1(); C、 A.method1(); D、 A.method2();
解释:静态成员和静态方法,可以直接通过类名进行调用;其他的成员和方法则需要进行实例化成对象之后,通过对象来调用。
二、编程题
1、组队竞赛
题目描述: 【组队竞赛】牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i,现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人。
牛牛发现 队伍的水平值等于该队伍队员中第二高水平值。
例如: 一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3 一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3;
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2;
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示: 如果牛牛把6个队员划分到两个队伍
如果方案为 : team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.
而如果方案为: team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.
没有比总和为10更大的方案,所以输出10
输入描述:代码片段 输入的第一行为一个正整数n(1 ≤ n ≤ 10^5) 第二行包括3*n个整数a_i(1 ≤ a_i ≤ 10^9),表示每个参赛选手的水平值.
输出描述:输出一个整数表示所有队伍的水平值总和最大值.
示例1:
输入:2
5 2 8 5 1 5
输出:10
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main1 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int n=scanner.nextInt();//队伍数
long[] data=new long[3*n];//总人数
//输入每个人的水平值,并排序
for (int i = 0; i < data.length; i++) {
data[i]=scanner.nextLong();
}
Arrays.sort(data);
Long res=0L;
for(int i=0;i<n;i++){
//取得水平值(这里是倒着取,方便),假如res
int mid=data.length-(2*(i+1));
res+=data[mid];
}
System.out.println(res);
}
}
}
无需知道具体如何组队,只要让有个数大于中间数即可,举例更直观一些,比如说1 2 3 4 5 6 7 8 9,需要找出来的是最大的6个数,(6是总数9的2/3,每个队只需要找出较大的两个),然后这六个数中4 6 8就分别是各个队的最大得分,至于剩下的1 2 3 如何分队都无所谓的。所以就是将所有的数排序,找到较大的总数的2/3,然后从大到小,取偶数位置的数即可。
/**
*
* 方法2:
*/
import java.util.Arrays;
import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] x = new int[3*n];
for(int i=0;i<3*n;i++)
{
x[i]=in.nextInt();
}
Arrays.sort(x);
long sum = 0;
int i=x.length-2;
while(i>=n-1)
{
sum = sum+x[i];
i = i-2;
}
System.out.println(sum);
}
}
2、删除公共字符
题目描述:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符 串变成”Thy r stdnts.
输入描述:每个测试输入包含2个字符串
输出描述:输出删除后的字符串
示例1:
输入:They are students. aeiou
输出:Thy r stdnts.
代码:
import java.util.Scanner;
public class Main3 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s1=scanner.nextLine();
String s2=scanner.nextLine();
String res="";
for (int i = 0; i < s1.length(); i++) {
char c=s1.charAt(i);
int j=0;
for(;j<s2.length();j++){
if(c==s2.charAt(j)){
break;
}
}
if(j==s2.length()){
res+=c;
}
}
System.out.println(res);
}
}