day01_4月12日
选择题
第一题
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();
}
}
A 0 2 2 4 4 6
B 2 4 2 4 2 4
C 2 2 4 4 6 6
D 4 4 4 4 6 6
答案:C
首先初始化 Test,使得 data 被赋于默认值 0, 而 result = 0;
接下来创建线程,开始运行,由于加锁(synchronized)了,不会出现变量的覆盖,所以三者所访问的都是变化后的 mv 的变量
Thread t1 = new ThreadExample(mv),运行前 data = 0, result = 0,运行后 data = 2, result = 2
Thread t2 = new ThreadExample(mv),运行前 data = 2, result = 2,运行后 data = 4, result = 4
Thread t3 = new ThreadExample(mv),运行前 data = 4, result = 4,运行后 data = 6, result = 6
第二题
要使对象具有序列化能力,则其类应该实现如下哪个接口()。
A java.io.Serializable
B java.lang.Cloneable,
C java.lang.CharSequence
D java.lang.Comparable
答案:A java.io.Serializable
Serializable 接口时专门提供给类实现序列化的;
Cloneable 接口是用来实现克隆方法的,Object.clone() 方法可以合法的对该类实力进行按字段复制;
实现 CharSequence 接口的类有:CharBuffer、String、StringBuffer、StringBuillder 四个类,这样当处理 String 或者 StringBuffer 的类既不用重载了
Comparable 接口用于对实现它的每个类的对象进行整体排序
第三题
下列选项中属于面向对象设计方法主要特征的是( )。
A 继承
B 自顶向下
C 模块化
D 逐步求精
答案:A
面向对象基本方法的基本概念有对象、类和实例、消息、继承与多态性
第四题
关于下列程序段的输出结果,说法正确的是:( )
public class MyClass{
static int i;
public static void main(String argv[]){
System.out.println(i);
}
}
A 有错误,变量i没有初始化。
B null
C 1
D 0
答案:D 0
static 修饰的变量(成员变量,即类变量)会被赋予默认值,而如果没有被 static 修饰,那么就会报错
第五题
下列代码的执行结果是:( )
public class Test3{
public static void main(String args[]){
System.out.println(100%3);
System.out.println(100%3.0);
}
}
A 1和1
B 1和1.0
C 1.0和1
D 1.0和1.0
答案:B 1 和 1.0
Java 中的被余数可以时小数,其所求得得余数也是余数
第六题
在基本 JAVA 类型中,如果不明确指定,整数型的默认是 __ 类型,带小数的默认是 __ 类型? ( )
A int float
B int double
C long float
D long double
答案:B int double
整数类型后加上"L"表示 long 类型;
浮点数类型后加上”f"表示 float类型;
第七题
方法通常存储在进程中的哪一区()
A 堆区
B 栈区
C 全局区
D 方法区
D 方法区
JVM 内存五大区:
- 线程私有:
- 程序计数器:用于指示当前线程所执行的字节码执行到第几行,每个线程都有一个
- 虚拟机栈:一个线程的每个方法再执行的时候都会创造一个栈帧,存储局部变量表,操作栈,动态链接,方法入口,当每个方法被调用的时候,栈帧入栈,方法执行完后,栈帧出栈。
- 本地方法栈:本地方法栈在作用运行机制、异常类型等方面和虚拟机栈相同,区别是:虚拟机栈执行的是 Java 方法,而本地方法栈执行 native 方法。
- 线程共享:
- 堆区:堆区是用来存储对象实例
- 方法区:方法区是线程共享,用于存储已经被虚拟机加载的类信息,包括版本,field,方法,接口等信息,final 常量,静态变量,编译器及时编译的代码等。方法区上执行垃圾回收很少,所以方法区也被称为永久代。
第八题
不考虑反射,关于私有访问控制符 private 修饰的成员变量,以下说法正确的是()
A 可以三种类所引用:该类自身、与它在同一包中的其他类,在其他包中的该类的子类
B 可以被两种类访问和引用:该类本身、该类的所有子类
C 只能被该类自身所访问和修改
D 只能被同一个包中的类访问
答案:C
private 只能被自身所访问和修改
第九题
Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少 ( ).
A 11 ,-11
B 11 ,-12
C 12 ,-11
D 12 ,-12
答案:C 12, -11
round(n) 时返回不小于 n 的最小整数,所以是往大数方向去取整数
第十题
假设 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();
答案:C A.method1();
static 修饰的变量及方法可以被 类名+方法名 的形式调用
编程题
一、组队竞赛
【组队竞赛】牛牛举办了一次编程比赛,参加比赛的有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
解析
这个代码比较考验是否能明白其中的道理,首先将队伍的能力值进行排序,使其升序排列,以 5 2 8 4 1 5 举例,排序后为 1 2 4 5 5 8,由于只取中间值作为水平值的最大值和之一,所以最小的两个数 1 2被排除,这两个数是 team 中每队各一个;最大值也不要,因为最大值是不计入水平值总和的,那么就只用取中间区间中的值,倒数第二大的值 team[team.length - 2] 是必取的,因为要保证水平值最大,如果要是 team[team.length - 2] 为中间值,那么最大值 8 和 5(team[team.length - 2] )必须为一组,那么剩下的一组只能是 team[2] 和 team[3],这样一来就能得出水平值总和的最大值:9
由此可以得到规律:从 team[tap] 处开始查找,每 1 个元素就相加就能得到水平值总和最大值
注:
- tap 为小组数
- 为什么要跳过 1 个元素?这个 tap 没有关系,跳过 1 个元素是为了跳过该组的最大值
代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int tap = scanner.nextInt();
int[] team = new int[tap * 3];
//将能力值放进一个数组
for(int i = 0; i < team.length; i++){
team[i] = scanner.nextInt();
}
//排序
Arrays.sort(team);
long sum = 0;
for(int i = tap; i <= team.length - 2; i = i + 2){
sum += team[i];
}
System.out.println(sum);
}
}
二、删除公共字符
【删除公共字符】输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符 串变成”Thy r stdnts.”
输入描述:
每个测试输入包含2个字符串
输出描述:
输出删除后的字符串
示例1:
输入
They are students. aeiou
输出
Thy r stdnts.
解析
本题可以采用先将短的字符串拆分到数组或顺序表中,然后长的字符串遍历比较,如果是不一样就存放到 新创建的字符串中,这种方法的时间复杂度为O(N^2),因为要同时遍历两个字符串。
当然也可以和我一样,先将短的字符串放到哈希表中,然后再将长的字符串拆分(接下来称为ch),然后查看哈希表中与 ch 相同的值是否为 null,如果为 null 说明短的字符串中没有这个字符,那么就可以直接放到新的字符串中。
代码
import java.util.HashMap;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str1 = scanner.nextLine();
String str2 = scanner.nextLine();
String str3 = "";
if(str1.length() < str2.length()){
String tmp = str1;
str1 = str2;
str2 = tmp;
}
HashMap<Character, Integer> map = new HashMap<>();
for(int i = 0; i < str2.length(); i++){
char ch = str2.charAt(i);
if(map.get(ch) == null){
map.put(ch, 1);
}else{
map.put(ch, map.get(i + 1));
}
}
for(int i = 0; i < str1.length(); i++){
char ch = str1.charAt(i);
if(map.get(ch) == null){
str3 += ch;
}
}
System.out.println(str3);
}
}