赞
踩
JavaSE进阶01:继承、修饰符
JavaSE进阶02:多态、抽象类、接口
JavaSE进阶03:内部类、Lambda表达式
JavaSE进阶04:API中常用工具类
JavaSE进阶05:包装类、递归、数组的高级操作、异常
JavaSE进阶06:Collection集合、迭代器、List、ArrayList、LinkedList
JavaSE进阶07:泛型、Set集合、TreeSet、二叉树、红黑树
JavaSE进阶08:HashSet、Map集合、HashMap、TreeMap、可变参数、不可变集合
JavaSE进阶09:Stream流、File类
JavaSE进阶10:IO流、字节流、字节缓冲流
JavaSE进阶11:字符流、字符缓冲流、转换流、对象操作流、Properties集合
JavaSE进阶12:多线程、线程同步、线程池
JavaSE进阶13:网络编程入门、UDP通信程序、TCP通信程序、日志、枚举
JavaSE进阶14:类加载器、反射
JavaSE进阶15:XML、注解、单元测试
JavaSE进阶扩充:JDK8 HashMap底层分析(了解)
JavaSE进阶扩充:JDK8 ArrayList线程安全问题和源码分析、集合常见面试题
Java进阶作业
1 简答题
1.2 简答题一
请分析如下程序编译是否会报错并说明原因?并给出正确的代码!
答:
会
不在同一个包下且没有import导入
1.3 简答题二
请分析如下程序在控制台的执行结果并说明原因?
答:
中国
中国
static修饰的变量被该类的所有对象共享
1.4 简答题三
请分析如下程序编译是否会报错并说明原因?
答:
会
静态成员方法只能访问静态成员
1.5 简答题四
请分析如下程序编译是否会报错并说明原因?
答:
不会
静态成员方法只能访问静态成员,静态方法可以通过类名调用
2 编程题
第一题:练习今日的代码
第二题:分析以下需求,并用代码实现
1.定义Person类
属性:
姓名name、性别gender、年龄age、国籍nationality;
方法:吃饭eat、睡觉sleep,工作work。
2.根据人类,创建一个学生类Student
增加属性:
学校school、学号stuNumber;
重写工作方法(学生的工作是学习)。
3.根据人类,创建一个工人类Worker
增加属性:
单位unit、工龄workAge;
重写工作方法(工人的工作是盖房子)。
4.根据学生类,创建一个学生干部类 StudentLeader
增加属性:
职务job;
增加方法:开会meeting。
5.编写测试类分别对上述3类具体人物进行测试。
6.要求运行结果:
要求使用全参构造分别写出学生和工人对象还有学生干部对象。调用他们的work方法,和学生干部的开会方法
输出内容如下:
学生需要学习!
工人的工作是盖房子!
学生干部喜欢开会!
package test18;
public class Person {
private String name;
private String gender;
private int age;
private String nationality;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNationality() {
return nationality;
}
public void setNationality(String nationality) {
this.nationality = nationality;
}
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
public void work(){
System.out.println("工作");
}
}
package test18;
public class Student extends Person {
private String school;
private int stuNumber;
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public int getStuNumber() {
return stuNumber;
}
public void setStuNumber(int stuNumber) {
this.stuNumber = stuNumber;
}
@Override
public void work() {
System.out.println("学生需要学习!");
}
}
package test18;
public class Worker extends Person{
private String unit;
private int workAge;
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public int getWorkAge() {
return workAge;
}
public void setWorkAge(int workAge) {
this.workAge = workAge;
}
@Override
public void work() {
System.out.println("工人的工作是盖房子!");
}
}
package test18;
public class StudentLeader extends Student{
private String job;
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public void meeting(){
System.out.println("学生干部喜欢开会!");
}
}
package test18;
public class Test18 {
public static void main(String[] args) {
Student student=new Student();
student.work();
Worker worker = new Worker();
worker.work();
StudentLeader studentLeader = new StudentLeader();
studentLeader.meeting();
}
}
第三题:分析以下需求,并用代码实现
1.定义项目经理类
属性:
姓名 工号 工资 奖金
行为:
工作work
2.定义程序员类
属性:
姓名 工号 工资
行为:
工作work
3.要求:向上抽取一个父类,让这两个类都继承这个父类,共有的属性写在父类中,子类重写父类中的方法
编写测试类:完成这两个类的测试
package test19;
public class Worker {
private String name;
private int number;
private int wages;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int getWages() {
return wages;
}
public void setWages(int wages) {
this.wages = wages;
}
public void work(){
System.out.println("姓名:"+name+",工号:"+number+",工资:"+wages+"的人在工作");
}
}
package test19;
public class Manager extends Worker {
private int bonus;
public int getBonus() {
return bonus;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
@Override
public void work() {
System.out.println("姓名:"+getName()+",工号:"+getNumber()+",工资:"+getWages()+",奖金:"+getBonus()+"的项目经理在工作");
}
}
package test19;
public class Coder extends Worker {
@Override
public void work() {
System.out.println("姓名:"+getName()+",工号:"+getNumber()+",工资:"+getWages()+"的程序员在工作");
}
}
package test19;
public class Test19 {
public static void main(String[] args) {
Manager manager = new Manager();
manager.setName("张三");
manager.setNumber(001);
manager.setWages(11111);
manager.setBonus(222222);
manager.work();
Coder coder = new Coder();
coder.setName("李四");
coder.setNumber(002);
coder.setWages(33333);
coder.work();
}
}
第四题:根据需求完成代码:
1.定义动物类
属性:
年龄,颜色
行为:
eat(String something)方法(无具体行为,不同动物吃的方式和东西不一样,something表示吃的东西)
生成空参有参构造,set和get方法
2.定义狗类继承动物类
行为:
eat(String something)方法,看家lookHome方法(无参数)
3.定义猫类继承动物类
行为:eat(String something)方法,逮老鼠catchMouse方法(无参数)
4.定义Person类
属性:
姓名,年龄
行为:
keepPet(Dog dog,String something)方法
功能:喂养宠物狗,something表示喂养的东西
行为:
keepPet(Cat cat,String something)方法
功能:喂养宠物猫,something表示喂养的东西
生成空参有参构造,set和get方法
5.测试以上方法
package test20;
public class Animal {
private int age;
private String color;
public Animal() {
}
public Animal(int age, String color) {
this.age = age;
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void eat(String something){
System.out.println(getAge()+"岁的"+getColor()+"宠物吃:"+something);
}
}
package test20;
public class Dog extends Animal {
public Dog() {
}
public Dog(int age, String color) {
super(age, color);
}
public void lookHome(){
System.out.println("看家");
}
}
package test20;
public class Cat extends Animal {
public Cat() {
}
public Cat(int age, String color) {
super(age, color);
}
public void catchMouse(){
System.out.println("逮老鼠");
}
}
package test20;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void keepPet(Dog dog,String something){
System.out.print(age+"岁的"+name+"喂养宠物狗,");
dog.eat(something);
}
public void keepPet(Cat cat,String something){
System.out.print(age+"岁的"+name+"喂养宠物猫,");
cat.eat(something);
}
}
package test20;
public class Test20 {
public static void main(String[] args) {
Cat cat = new Cat(11,"橘黄色");
Dog dog = new Dog(2,"黑色");
Person person = new Person("王五", 12);
person.keepPet(dog, "剩饭");
person.keepPet(cat, "猫粮");
}
}
1 简答题
1.1 简答题一
下面程序编译是否会报错并说明原因?
答:
报错
父类私有成员变量只能通过get方法调用,private改成public、protected或默认都不报错
1.2 简答题二
下面程序编译是否会报错并说明原因?
答:
报错
Java中类只支持单继承,不支持多继承
1.3 简答题三
下面程序执行完毕以后在控制台输出的结果是什么并说明原因?如果想输出23和45代码应该怎么书写?
答:
System.out.println(super.num);//23
System.out.println(this.num);//45
1.4 简答题四
下面程序编译是否会报错并说明原因?
答:
报错,子类必须调用父类的构造方法,此时父类没有无参构造方法,则必须调用父类的有参构造方法。
1.5 简答题五
下面程序编译是否会报错并说明原因?
答:
子类重写父类方法时,子类方法的访问权限不能比父类更低,public>默认>private
1.6 简答题六
下面程序编译是否会报错并说明原因?并给出正确的代码!
答:
报错
非抽象类不能使用抽象方法
public abstract class Animal {
public abstract void eat();
public void sleep(){
System.out.println("sleep");
}
}
2 编程题
第一题:练习今天代码.
第二题:根据需求完成代码:
1.定义手机类
行为:
打电话,发短信
2.定义接口IPlay
行为:
玩游戏
3.定义旧手机类继承手机类
行为:
继承父类的行为
4.定义新手机继承手机类实现IPlay接口
行为:继承父类的行为,重写玩游戏方法
5.定义测试类
在测试类中定义一个 用手机的方法,要求该方法既能接收老手机对象,也能接收新手机对象
在该方法内部调用打电话,发短信以及新手机特有的玩游戏方法
public class Phone {
public void call(){
System.out.println("打电话");
}
public void message(){
System.out.println("发短信");
}
}
public interface IPlay {
public abstract void game();
}
public class OldPhone extends Phone{
}
public class NewPhone extends Phone implements IPlay{
@Override
public void game() {
System.out.println("玩游戏");
}
}
public class Test0202 {
public static void usePhone(Phone phone){
phone.call();
phone.message();
if (phone instanceof NewPhone){
((NewPhone) phone).game();
}
}
public static void main(String[] args) {
NewPhone newPhone = new NewPhone();
OldPhone oldPhone = new OldPhone();
usePhone(newPhone);
usePhone(oldPhone);
}
}
第三题:根据需求完成代码:
1.定义动物类
行为:
eat方法(无具体行为,要求子类必须重写该方法)
2.定义狗类继承动物类
行为:
eat方法(啃骨头),看家方法lookHome
3.定义猫类继承动物类
行为:
eat方法(吃鱼),抓老鼠方法catchMouse
4.测试类:
定义一个方法,要求该方法既能接收狗对象也能接收猫对象
在该方法的内部调用eat()方法,并且如果是狗的话调用狗的看家方法
public abstract class Animal {
public abstract void eat();
}
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("啃骨头");
}
public void lookHome(){
System.out.println("看家");
}
}
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("吃鱼");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
public class Test0203 {
public static void show(Animal animal){
animal.eat();
if (animal instanceof Dog){
((Dog) animal).lookHome();
}else if(animal instanceof Cat){
((Cat) animal).catchMouse();
}
}
public static void main(String[] args) {
Dog dog=new Dog();
Cat cat = new Cat();
show(dog);
show(cat);
}
}
第四题:根据需求完成代码:
1.定义动物类
属性:
年龄,颜色
行为:
eat(String something)方法(无具体行为,,something表示吃的东西,要求子类必须重写该方法)
生成空参有参构造,set和get方法
2.定义狗类继承动物类
行为:
eat(String something)方法,看家lookHome方法(无参数)
3.定义猫类继承动物类
行为:eat(String something)方法,逮老鼠catchMouse方法(无参数)
4.定义Person类
属性:
姓名,年龄
行为:
keepPet(Dog dog,String something)方法
功能:喂养宠物狗,something表示喂养的东西
行为:
keepPet(Cat cat,String something)方法
功能:喂养宠物猫,something表示喂养的东西
生成空参有参构造,set和get方法
ps
5.定义测试类(完成以下打印效果):
keepPet(Dog dog,String somethind)方法打印内容如下:
年龄为30岁的老王养了一只黑颜色的2岁的宠物
2岁的黑颜色的狗两只前腿死死的抱住骨头猛吃
keepPet(Cat cat,String somethind)方法打印内容如下:
年龄为25岁的老李养了一只灰颜色的3岁的宠物
3岁的灰颜色的猫眯着眼睛侧着头吃鱼
6.思考:
1.Dog和Cat都是Animal的子类,以上案例中针对不同的动物,定义了不同的keepPet方法,过于繁琐,能否简化,并体会简化后的好处?
答:
可以使用多态简化,多态能提高程序的扩展性
代码如下:
public void keepPet(Animal animal,String something){
System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+animal.getColor()+"的"+animal.getAge()+"岁的宠物");
animal.eat(something);
}
2.Dog和Cat虽然都是Animal的子类,但是都有其特有方法,能否想办法在keepPet中调用特有方法?
答:
instanceof关键字:会判断左边的对象是否是右边的类型,返回boolean类型
代码如下:
public void keepPet(Animal animal,String something){
System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+animal.getColor()+"的"+animal.getAge()+"岁的宠物");
animal.eat(something);
if (animal instanceof Dog){
((Dog) animal).lookHome();
}else if(animal instanceof Cat){
((Cat) animal).catchMouse();
}
}
完整代码如下:
public abstract class Animal {
private int age;
private String color;
public abstract void eat(String something);
public Animal() {
}
public Animal(int age, String color) {
this.age = age;
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
public class Dog extends Animal{
@Override
public void eat(String something) {
System.out.println(getAge()+"岁的"+getColor()+"的狗两只前腿死死的抱住"+something+"猛吃");
}
public void lookHome(){
System.out.println("狗看家");
}
}
public class Cat extends Animal {
@Override
public void eat(String something) {
System.out.println(getAge()+"岁的"+getColor()+"的猫眯着眼睛侧着头吃"+something);
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
public class Person {
private String name;
private int age;
// public void keepPet(Dog dog,String something){
// System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+dog.getColor()+"的"+dog.getAge()+"岁的宠物");
// dog.eat(something);
// }
// public void keepPet(Cat cat,String something){
// System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+cat.getColor()+"的"+cat.getAge()+"岁的宠物");
// cat.eat(something);
// }
public void keepPet(Animal animal,String something){
System.out.println("年龄为"+getAge()+"岁的"+getName()+"养了一只"+animal.getColor()+"的"+animal.getAge()+"岁的宠物");
animal.eat(something);
if (animal instanceof Dog){
((Dog) animal).lookHome();
}else if(animal instanceof Cat){
((Cat) animal).catchMouse();
}
}
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test0204 {
public static void main(String[] args) {
Person person1 = new Person("老王", 30);
Person person2 = new Person("老李", 25);
Dog dog=new Dog();
dog.setAge(2);
dog.setColor("黑颜色");
Cat cat=new Cat();
cat.setAge(3);
cat.setColor("灰颜色");
person1.keepPet(dog, "骨头");
person2.keepPet(cat, "鱼");
}
}
第五题:根据需求完成代码:
1.定义动物类:
行为:
吼叫;没有具体的吼叫行为
吃饭:没有具体的吃饭行为
2.定义缉毒接口
行为:
缉毒
3.定义缉毒狗:犬的一种
行为:
吼叫:汪汪叫
吃饭:狗啃骨头
缉毒:用鼻子侦测毒
4.定义测试类:
使用多态的形式创建缉毒狗对象,调用缉毒方法和吼叫方法
public abstract class Animal {
public abstract void roar();
public abstract void eat();
}
public interface AntiDrug {
public abstract void drug();
}
public class Dog extends Animal implements AntiDrug {
@Override
public void roar() {
System.out.println("汪汪叫");
}
@Override
public void eat() {
System.out.println("狗啃骨头");
}
@Override
public void drug() {
System.out.println("用鼻子侦测毒");
}
}
public class Test0205 {
public static void main(String[] args) {
Dog dog=new Dog();
dog.drug();
dog.roar();
}
}
1 简答题
1.1 简答题一
请分析如下程序是否会报错(编译版本JDK1.8)并说明原因?并给出正确的代码!
答:
会报错
原因:JDK8接口新增默认方法和静态方法。但上述method方法不是静态或默认方法。
public default void method(){
System.out.println("非抽象类的method方法");
}
1.2 简答题二
请分析如下程序是否会报错并说明原因?并给出正确的代码!
答:
会报错
原因:类和接口是实现的关系,不是继承关系
class InterImpl implements Inter{//
}
1.3 简答题三
请分析如下程序是否会报错并说明原因?并给出正确的代码!
答:
会报错
原因:接口和接口之间的关系是继承关系,不是实现的关系
public interface Inter extends Inter1,Inter2{
}
1.4 简答题四
请分析如下程序那几行代码会报错并说明原因?
答:
第十行报错
原因:接口中的成员变量存在默认的修饰符:public static final
因此number是一个常量,其值不能被改变
1.5 简答题五
请分析如下程序是否会报错并说明原因?并给出正确的代码!
答:
会报错
原因:InterImpl不是一个抽象类,name此时就需要重写Animal类以及Inter1和Inter2中所有的抽象方法,但是InterImpl没有重写Animal中的eat方法,因此会报错。
public class InterTest extends Animal implements Inter1,Inter2{
@Override
public void show(){
}
public void eat(){
}
}
1.6 简答题六
请分析如下程序是否会报错并说明原因?
答:
会报错
原因:通过多态创建Animal对象,编译看左边,在编译的时候需要查看Animal类中是否定义了eat方法。在Animal类中没有定义eat方法,因此编译报错。
1.7 简答题七
请分析如下程序在控制台的输出结果是什么并说明原因?
答:
结果:
6
Dog吃东西
原因:
1.通过多态访问成员变量:编译看左边,运行看左边
2.通过多态发访问成员方法:编译看左边,运行看右边
1.8 简答题八
请分析如下程序在控制台的输出结果是什么并说明原因?以及如何避免该问题?
答:
控制台报错:类型转换异常
原因:Animal本质的类型为Dog,不能将Dog转型为Cat,Dog和Cat之间不存在子父类的继承关系。
避免方法:在运行类型转换的时候,可以通过instanceof关键字进行类型的判断
Animal animal = new Dog();
if(animal instanceof Cat){
Cat cat=(Cat) animal;
cat.eat();
}
1 简答题
1.1 简答题一
请分析如下程序是否会报错并说明原因?
答:
会报错
原因:定义的Inter内部类是一个局部内部类,局部内部类不能通过private进行修饰
1.2 简答题二
请分析如下程序是否会报错并说明原因?并给出正确的代码!
答:
会报错
原因:在外部类中创建一个非静态的成员内部类对象的格式不对
Demo02.Inter inter=new Demo02().new Inter();
1.3 简答题三
请分析如下程序是否会报错并说明原因?并给出正确的代码!
答:
会报错
原因:在外部类中创建一个静态成员内部类对象的格式不对
Demo03.Inter inter = new Demo03.Inter();
1.4 简答题五
如下程序想在控制台输出30,20,10那么在9,10,11行代码的输出语句中应该填写什么代码?
答:
输出语句填写的代码分别是:num、this.num、Outer.this.num
1.5 简答题六
下面lambda表达式的书写是否正确并说明原因?并给出正确的代码!
答:
不正确
原因:Lambda表达式省略格式,如果有多个参数,参数类型在省略的时候需要全部省略。
show((int a ,int b)->a+b); 或者 show((a ,b)->a+b);
1.6 简答题六
请分析如下程序是否会报错并说明原因?
答:
不会报错
原因:
这个equals方法的具体实现来自于Object类,由此可以知道即使接口里面对equals方法进行了定义,实际上的实现还是Object方法中的,在Java语言规范中,如果一个接口没有父接口,那么就会将Object中的public方法在接口里隐含的申明一份,参数,返回值什么的都一样.
重写了父类Object类中任意一个public方法的方法并不算接口中的抽象方法。所以虽然Compare接口中有两个抽象方法compare和equals,但equals并不算接口中的抽象方法,所以Compare接口还是满足函数式接口的要求,Compare接口是一个函数式接口。
1.7 简答题七
请分析如下程序执行完毕以后在控制台的输出结果是什么并说明原因?
答:
控制台输出结果:false,false
原因:
1.使用==比较两个对象是否相等,比较的是地址值。
2.调用equals方法比较时,由于Student类中没有重写父类Object中的equals方法,因此调用的还是Obeject类中的equals。还是用的==。
1.8 简答题八
请分析如下程序执行完毕以后在控制台的输出结果是什么并说明原因?
答:
控制台输出:
com.itheima.object.demo00.Student@45554617c
我是一名老师!
原因:
直接输出对象名默认调用对象的toString方法,Student类没有重写Object类中的toString方法,因为直接打印地址值
Teacher类重写了Object类中的toString方法,按照重写方法输出
1.9 简答题九
如下程序:
执行完毕以后在控制台的数据结果为:
请说明产生该结果的原因,并且给出精确输出(得到结果为0.2)的代码!
答:
原因:
计算机是二进制的计算,浮点数会失去一定的精度
精确输出:
需要使用jdk中的BigDecimal类进行计算,代码如下
BigDecimal b1 = new BigDecimal("0.01");
BigDecimal b1 = new BigDecimal("0.05");
System.out.println(b1.divide(b2));
1 简答题
1.3 简答题三
请分析如下程序执行完毕以后在控制台的最终输出结果是什么并说明原因?
答:
会报错栈溢出,因为function和method方法无限循环调用,不断的将方法加载到栈内存,因此程序在执行一段时间后,栈内存不够用了,就会抛出StackOverflowError
1.4 简答题四
有数组:[23 , 78, 12 , 45 , 11 , 99]。现需要查找11这个元素在数组中出现的索引,请问是否可以使用二分查找进行实现?如果不能,请说明原因?并且给出你的查找代码。
答:
不能使用二分查找,因为初始数组不是有序的
public static int getIndex(int arr,int number){
for(int x=0;x<arr.length;x++){
if(arr[x]==number){
return x;
}
}
return -1;
}
1.5 简答题五
请分析如下程序执行完毕以后在控制台的输出结果是什么并说明原因?
答:
把数组越界异常的错误信息打印在控制区(红色字体)
因为arr数组只有3个整型数字,最大索引为2,不存在编号为3的索引。
catch只能捕获空指针异常NullPointerException,两个异常不属于同一类异常,因此还是执行JVM的异常处理机制:将异常的错误信息打印到控制台,并结束程序。
1.7 简答题七
简述throw和throws的区别?
答:
throw用在方法内部,后面跟一个异常对象,用来抛出一个异常
throws用在方法定义上,后面跟一个异常类型,用来给方法添加一个异常声明,该方法可能会出现异常
1.8 简答题八
下述程序编译能否通过?如果不能,请说明哪一个方法会报错并说明原因?
答:
不能编译通过
Son的show方法会报错
因为子类抛出的异常类不能超过父类中的异常类,如果父类被重写方法没有抛出异常,子类重写方法也不能使用throws,防止使用多态时,子类抛出异常无人处理。而RuntimeException为运行异常,编译时可以不做处理。
2 编程题
2.1 编程题目一
训练目标:掌握Java中递归算法的使用,以及理解其在实际开发中的应用
需求描述:面试题(爬楼梯问题):假设你正在爬楼梯,楼梯总共是n阶。每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到楼顶呢?假设总共有10阶,计算结果如下所示:
实现提示:
1、可以采用假设法,先推导出具体的规则
2、使用递归算法进行实现
/*
思路:终点的最后一步是1步的所有情况加上最后一步是2步的所有情况。
1阶的方案数:1
2阶的方案数:2
3阶方案数=到2阶的方案数+到1阶的方案数=3
4阶方案数=到3阶的方案数+到2阶的方案数=3+2=5
5阶方案数=到4阶的方案数+到3阶的方案数=5+3=8
...
*/
import java.util.Scanner;
public class ClimbStairs {
public static void main(String[] args) {
int count;
System.out.println("请输入楼层数:");
Scanner sc = new Scanner(System.in);
int labberNum = sc.nextInt();
count = upStairs(labberNum - 1) + upStairs(labberNum - 2);
System.out.println(labberNum + "阶楼梯共有:" + count + "种方案");
}
public static int upStairs(int labberNum) {
int count = 0;
if (labberNum == 0) {
return 1;
} else if (labberNum > 0) {
count = upStairs(labberNum - 1) + upStairs(labberNum - 2);
} else return 0;
return count;
}
}
1 简答题
1.1 简答题一
请说明下述程序执行完毕以后在控制台的输出结果是什么并说明原因?
答:
报错:Exception in thread "main" java.text.ParseException: Unparseable date: "2022/1/22"
原因:dateStr字符串的格式与dateFormat不对应,无法解析
1.2 简答题二
简述集合数组的区别?
答:
数组的长度是不可变的;集合的长度是可变的。
数组可以存基本数据类型和引用数据类型;集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类。
1.3 简答题三
请说明下面程序执行完毕以后在控制台的输出结果是什么并说明原因(从List集合的特点进行作答)?
List<String> list=new ArrayList<String>;
list.add("111");
list.add("222");
list.add("333");
list.add("444");
for(int x=0;x<list.size();x++){
System.out.println(list.get(x));
}
答:
111
222
333
444
原因:List存取有序、内容可以重复、有索引可以通过get方法获取
1.4 简答题四
请说明下面程序执行完毕以后在控制台的输出结果是什么并说明原因?如果要进行正常数据的输出应该对程序怎么改造?
// 通过多态的方式创建一个List集合对象
List<String> list = new ArrayList<String>() ;
// 添加元素
list.add("111") ;
list.add("222") ;
list.add("333") ;
list.add("444") ;
// 遍历集合
for(int x = 0 ; x < list.size() ; x++) {
System.out.println(list.remove(x));
}
答:
111
333
原因:集合的remove方法删除掉一个元素后,后面的元素会前移
Iterator<String> it=list.iterator();
while (it.hasNext()){
System.out.println(it.next());
it.remove();
}
1.5 简答题五
请说明下面程序执行完毕以后在控制台的输出结果是什么并说明原因?
// 通过多态的方式创建一个List集合对象
List<String> list = new ArrayList<String>() ;
// 添加元素
list.add("111") ;
list.add("222") ;
list.add("222") ;
list.add("333") ;
// 获取迭代器对象,通过迭代器对象对集合进行遍历
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
// 获取元素
String next = iterator.next();
// 判断元素
if(next.equals("itheima")) {
list.remove(next) ;
}
}
// 遍历集合
list.forEach( s -> System.out.println(s) );
list.remove(next)答:
报错:Exception in thread "main" java.util.ConcurrentModificationException。并发修改异常。
原因:在创建迭代器后,除非通过迭代器自身的remove和add方法从结构上对集合进行修改,其他修改方式都会抛出并发修改异常。因为iterator.next()获取了当前迭代器指向的元素,而list.remove(next)会删除它获取的元素并后面元素向前移,也就等同于强行修改了iterator.next()手中的元素,所以抛出异常。
1.6 简答题六
去银行办理业务,当银行办理业务人员过多的时候往往需要进行排队。关于排队数据使用哪一种数据结构来进行存储比较合适并说明你的理由?
答:
队列:先进先出
1.7 简答题七
请问Collection接口下有哪些类型的集合?它们分别是什么?
答:
可重复:List、ArrayList、LinkedList
不可重复:Set、HashSet、TreeSet
1.8 简答题八
请问Collection接口中定义的方法,它的所有子类是否都有,而且都会实现这些方法?
答:
都有且会实现这些方法。
1.9 简答题九
请问向Collection集合添加一个元素用什么方法?
答:
boolean add(E e)
2.0简答题十
请问从Collection集合中删除一个元素用什么方法?这个方法有返回值吗?
答:
boolean remove(Object o):从集合中移除指定的元素
boolean removeIf(Object o):根据条件进行移除
返回值都是boolean
2.1简答题十一
请问判断Collection集合中是否包含一个元素用什么方法?
答:
boolean contains(Object o):判断集合中是否存在指定的元素
2.2简答题十二
请问用什么方法可以获取Collection集合中元素的数量?
答:
int size():集合的长度,也就是集合中元素的个数
2 简答题【数据结构】
1 请写出数组结构的特点;
答:
数组结构是连续的内存空间,具有查询快、增删慢的特点。
2 请写出链表结构的特点
答:
链表由各个节点组成,具有查询慢、增删快的贴点。
3 请写出栈结构的特点;
答:
先进后出
4 请写出队列结构的特点;
答:
先进先出
3 编程题
3.1 编程题目一
训练目标:掌握Java中List集合的使用,以及理解其在实际开发中的应用
需求背景:"抓阄"是指每人从预先做好记号的纸卷或纸团中摸取一个,以决定做什么。比如:学羊叫5声、蛙跳10个、吃芥末、喝一杯啤酒、做10个俯卧撑等。
需求描述:请设计一个抓阄游戏程序,实现5个人的抓阄,程序的运行效果如下所示:
实现提示:
1、创建一个集合存储5个人的名称
2、创建一个集合存储5个阄的内容
3、遍历名称的集合,获取每一个参与人员的名称
4、生成一个随机数作为存储5个阄的集合的索引,从该集合中随机获取一个元素,并且删除获取到的元素
5、在控制台输出结果
参考代码:
package HomeWork;
import java.util.ArrayList;
import java.util.Random;
public class Homework1 {
public static void main(String[] args) {
ArrayList<String> name=new ArrayList<>();
ArrayList<String> drew=new ArrayList<>();
name.add("郭靖");
name.add("黄蓉");
name.add("黄药师");
name.add("老顽童");
name.add("瑛姑");
drew.add("吃芥末");
drew.add("学羊叫5声");
drew.add("做10个俯卧撑");
drew.add("喝一杯啤酒");
drew.add("蛙跳10个");
Random random=new Random();
for (int i = 0; i < name.size() ; i++) {
System.out.print(name.get(i)+":");
System.out.println(drew.remove(random.nextInt(drew.size())));
}
}
}
3.2 编程题目二
训练目标:掌握Java中List集合的使用,以及理解其在实际开发中的应用
需求背景:"斗地主"游戏是大家都比较喜欢的游戏。游戏规则:本游戏为三人游戏,一副牌54张,每人17张,留3张做底牌,在确定地主之前玩家不能看底牌。确定地主后,地主可获得3张底牌。
实现提示:
1、创建四个List集合对象,分别用来存储3个玩家的牌以及底牌
2、遍历牌盒将合适的牌存储到上述指定的集合中
3、看牌就是对集合的元素进行遍历
4、数字3很神奇,一个数对3取余,会有意想不到的效果
参考代码:
package HomeWork;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Entry {
public static void main(String[] args) {
//创建一个牌盒,也就是定义一个集合对象,用ArrayList集合实现
List<String> broker = new ArrayList<>();
/*往牌盒里装牌
* ♦♣♥♠
* */
//定义花色数组
String[] colors = {"♦", "♣", "♥", "♠"};
//定义点数数组
String[] numbers = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
//拼接让每个花色都有13张从2-A的牌
for (String color : colors) {
for (String number : numbers) {
broker.add(color + number);
}
}
//加入大小王
broker.add("小王");
broker.add("大王");
// 洗牌,打乱集合中的元素
Collections.shuffle(broker);
// 补全代码
for (int i = 0; i < 54; i++) {
if (i==0){
System.out.print("玩家一的牌是:");
}else if(i/17==1&&i%17==0){
System.out.print("\n玩家二的牌是:");
}else if(i/17==2&&i%17==0){
System.out.print("\n玩家三的牌是:");
}else if(i/17==3&&i%17==0){
System.out.print("\n玩家的底牌是:");
}
System.out.print(broker.get(i)+"\t");
}
}
}
3.3编程题目三
请定义一个Collection类型的集合,存储以下字符串:
“JavaEE企业级开发指南”,”Oracle高级编程”,”MySQL从入门到精通”,”Java架构师之路”
要求:
请编程实现以下功能:
使用迭代器遍历所有元素,并打印
使用迭代器遍历所有元素,筛选书名小于10个字符的,并打印;
使用迭代器遍历所有元素,筛选书名中包含“Java”的,并打印
如果书名中包含“Oracle”,则删掉此书。删掉后,遍历集合,打印所有书名。
(注意:以上每个功能都单独写个方法,在main方法中逐个调用测试即可)
效果:
参考代码:
package HomeWork;
import java.util.ArrayList;
import java.util.Iterator;
public class Homework3 {
public static void main(String[] args) {
ArrayList<String> book=new ArrayList<>();
book.add("JavaEE企业级开发指南");
book.add("Oracle高级编程");
book.add("MySQL从入门到精通");
book.add("Java架构师之路");
method1(book);
method2(book);
method3(book);
method4(book);
}
public static void method1(ArrayList<String> arr){
System.out.println("---所有元素如下---");
Iterator<String> it=arr.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
public static void method2(ArrayList<String> arr){
System.out.println("---书名小于10个字符的元素如下---");
Iterator<String> it=arr.iterator();
while (it.hasNext()){
String s=it.next();
if(s.length()<10){
System.out.println(s);
}
}
}
public static void method3(ArrayList<String> arr){
System.out.println("---书名中包含“Java”元素如下---");
Iterator<String> it=arr.iterator();
while (it.hasNext()){
String s=it.next();
if(s.contains("Java")){
System.out.println(s);
}
}
}
public static void method4(ArrayList<String> arr){
System.out.println("---删除“oracle”的元素如---");
Iterator<String> it=arr.iterator();
while (it.hasNext()){
String s=it.next();
if(s.contains("Oracle")){
it.remove();
}
}
System.out.println(arr.toString());
}
}
3.4编程题目四
请定义一个Collection类型的集合,存储以下分数信息:
88.5,39.2,77.1,56.8,89.0,99.0,59.5
要求:
请编程实现以下功能:
使用增强for遍历所有元素,并打印
使用增强for遍历所有元素,打印不及格的分数;
使用增强for遍历所有元素,计算不及格的分数的数量,和平均分,并打印计算结果。
使用增强for遍历所有元素,求出最高分,并打印;
效果:
参考代码:
package HomeWork;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class HomeWork4 {
public static void main(String[] args) {
int num=0;
double sum=0,max=0;
Collection<Double> collection=new ArrayList<>(Arrays.asList(88.5,39.2,77.1,56.8,89.0,99.0,59.5));
System.out.println("使用增强for遍历所有元素,并打印如下:");
for (Double aDouble : collection) {
System.out.println(aDouble);
}
System.out.println("使用增强for遍历所有元素,打印不及格的分数如下:");
for (Double aDouble : collection) {
if(aDouble<60){
System.out.println(aDouble);
num++;
sum+=aDouble;
}
if(max<aDouble){
max=aDouble;
}
}
System.out.println("不及格的分数有:"+num+"个,不及格的人平局分是:"+sum/num);
System.out.println("集合中的最大值是:"+max);
}
}
3.5编程题目五
请定义方法找出集合中所有姓张的人并且年龄大于18岁的并全部返回,然后在main方法中输出返回的人;
集合原始数据有: 张三,22 李四,26 张翠山,38 赵六,19 张三丰,103 张无忌,17 赵敏,16
要求:
集合中的人需要以对象的形式存在,人只要有姓名和年龄两个成员变量即可;
注意:仔细思考一下自定义的方法要不要设计参数和返回值;
效果:
参考代码:
package HomeWork;
import java.util.ArrayList;
import java.util.Iterator;
public class HomeWork5 {
public static void main(String[] args) {
ArrayList<Student> arrayList=new ArrayList<>();
arrayList.add(new Student("张三",22));
arrayList.add(new Student("李四",26));
arrayList.add(new Student("张翠山",38));
arrayList.add(new Student("赵六",19));
arrayList.add(new Student("张三丰",103));
arrayList.add(new Student("张无忌",17));
arrayList.add(new Student("赵敏",16));
method(arrayList);
System.out.println(arrayList.toString());
}
public static void method(ArrayList<Student> arr){
Iterator<Student> iterator=arr.iterator();
while(iterator.hasNext()){
Student s=iterator.next();
if (s.getAge()<18||!s.getName().contains("张")){
iterator.remove();
}
}
}
}
4 源码分析题
配合源码分析ArrayList集合通过空参构造方法创建对象,并第一次添加元素的过程.
答:
new ArrayList()空参数构造方法创建一个默认初始数,组长度为0,第一次add()方法,因为此时集合长度是0,需要底层grow()方法进行数组扩容,此时最低容量为sizi+1即0+1=1。调用newCapacity方法,形参为最低容量1,新容量和旧容量计算出都是0,新容量-最低容量<=0满足if条件,此时集合数组是默认初始,则返回容量10。最后原来旧数组和扩容的数组10作形参给Arrays的copyOf方法,得到一个拥有原文内容且扩容到10的组。再回到add()方法把第一个元素添加到容量为10的数组中。
1 简答题
1.1 简答题一
请分析下面程序的运行结果是什么并说明原因?如果想让错误提前到编译期应该对代码进行如何处理?
答:
报错
list集合里有Interger类型,不能付给forEach中的String e。
办法:增加泛型
1.2 简答题二
简述Set集合的特点?
答:
不可以存储重复元素
没有索引,不能使用普通for循环遍历
存取无序
1.3 简答题三
如下程序
上述程序执行完毕以后会在控制台输出如下错误内容:
请说明产生该问题的原因?如果想先按照学生的年龄进行从大到小排序,如果年龄相同再按照学生的姓名进行排序,那么可以对代码进行怎样的改造?
答:
想要使用TreeSet,需要制定排序规则。
Student类实现Comparable接口的compareTo方法。
@Override
public int compareTo(Student o) {
int result = o.age-this.age;
return result;
}
1.4 简答题四
下面这棵树是不是一颗平衡二叉树?请说明你分析的依据?如果不是,那么怎么对其进行调整让其成为一颗平衡二叉树?
答:
不是
15节点左子树高度为0,右子树高度为2,高度差超过1。
右子树左旋
10
7 17
4 8 15 19
3 9
1.5 简答题五
下面三棵树,哪一颗是红黑树并说明原因?
答:
第一不是:根节点必须是黑色
第二不是:不能出现两个红色节点相连的情况
第三是
2 编程题
题目1
训练目标:掌握Java中TreeSet集合的使用,以及理解其在实际开发中的应用
需求背景:中国福利彩票"双色球"投注区分为红色球号码区和蓝色球号码区,红色球号码区由1-33共三十三个号码组成,蓝色球号码区由1-16共十六个号码组成。如下所示:
投注时选择6个红色球号码和1个蓝色球号码组成一注进行单式投注,每注金额人民币2元。
需求描述:现通过程序模拟双色球随机生成一注号码。程序运行结果如下所示:
实现提示:
1、生成的双色球号码不能重复,因此可以考虑使用TreeSet集合存储双色球号码
2、针对红球的生成,需要生成多次,因此可以考虑使用循环
import java.util.Random;
import java.util.TreeSet;
public class HomeWork {
public static void main(String[] args) {
TreeSet<Integer> ts=new TreeSet<>();
Random random=new Random();
int blue=random.nextInt(16)+1;
while (ts.size()<6) {
ts.add(random.nextInt(33)+1);
}
System.out.println("红球:"+ts.toString()+" | 蓝球:"+blue);
}
}
题目2
已知数组信息如下:
{2.2,5.5,6.6,2.2,8.8,1.1,2.2,8.8,5.5,2.2,6.6}
请使用代码找出上面数组中的所有的数据,要求重复的数据只能保留一份;
要求:
使用HashSet集合实现;
效果:
参考答案:
package homeWork;
import java.util.HashSet;
public class HomeWork3 {
public static void main(String[] args) {
double[] arr={2.2,5.5,6.6,2.2,8.8,1.1,2.2,8.8,5.5,2.2,6.6};
HashSet<Double> hashSet=new HashSet<>();
for (int i = 0; i < arr.length ; i++) {
hashSet.add(arr[i]);
}
System.out.println("去除重复的元素后,结果是:"+hashSet.toString());
}
}
题目3
随机生成8个不重复的10至20之间的随机数并保存Set集合中,然后打印出集合中所有的数据;
要求:
使用TreeSet集合实现;
效果:
(由于是随机的,所以8每次运行结果都不一样是正常的!!!)
参考答案:
package homeWork;
import java.util.Random;
import java.util.TreeSet;
public class HomeWork4 {
public static void main(String[] args) {
TreeSet<Integer> ts=new TreeSet<>();
Random rd=new Random();
int i=1,num=0;
while(ts.size()<8){
num=rd.nextInt(11)+10;
ts.add(num);
System.out.println("第"+i+"次生成的随机数是:"+num);
i++;
}
System.out.println("集合中保存的8个不重复的随机数是:"+ts.toString());
}
}
题目4
键盘输入3本书按照价格从低到高排序后输出,如果价格相同则按照书名的自然顺序排序;
要求:
1:书以对象形式存在,包含书名和价格(int类型)两个属性;
2:要求即使直接打印书对象的时候,也能看到书的名称和价格,而不是书对象的地址值;
3:分别使用自然排序和比较器排序实现效果;
效果:
参考答案:
自然排序方式:
package homeWork;
public class Book implements Comparable<Book>{
private String name;
private int price;
public Book() {
}
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
@Override
public int compareTo(Book o) {
int result=this.price-o.price;
result=result==0?this.name.compareTo(o.getName()):result;
return result;
}
}
package homeWork;
import java.util.Scanner;
import java.util.TreeSet;
public class BookTest {
public static void main(String[] args) {
TreeSet<Book> ts=new TreeSet<>();
Scanner sc=new Scanner(System.in);
int i=0;
do{
i++;
Book book=new Book();
System.out.println("请输入第"+i+"本书的名称:");
book.setName(sc.next());
System.out.println("请输入第"+i+"本书的价格(整数):");
book.setPrice(sc.nextInt());
boolean flag=ts.add(book);
if(flag){
System.out.println("添加"+book.getName()+" 书已经成功,继续添加请输入1,输入其他数字将结束!");
}else{
i--;
System.out.println("添加"+book.getName()+" 书已经失败,该书已存在,继续添加请输入1,输入其他数字将结束!");
}
}while(sc.nextInt()==1);
System.out.println("您一共添加了:"+i+"本书们分别是:");
for (Book t : ts) {
System.out.println(t);
}
}
}
比较器方式:
package homeWork;
public class Book{
private String name;
private int price;
public Book() {
}
public Book(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
package homeWork;
import java.util.Scanner;
import java.util.TreeSet;
public class BookTest {
public static void main(String[] args) {
TreeSet<Book> ts=new TreeSet<>((o1,o2) ->
o1.getPrice()-o2.getPrice()==0?o1.getName().compareTo(o2.getName()):o1.getPrice()-o2.getPrice()
);
Scanner sc=new Scanner(System.in);
int i=0;
do{
i++;
Book book=new Book();
System.out.println("请输入第"+i+"本书的名称:");
book.setName(sc.next());
System.out.println("请输入第"+i+"本书的价格(整数):");
book.setPrice(sc.nextInt());
boolean flag=ts.add(book);
if(flag){
System.out.println("添加"+book.getName()+" 书已经成功,继续添加请输入1,输入其他数字将结束!");
}else{
i--;
System.out.println("添加"+book.getName()+" 书已经失败,该书已存在,继续添加请输入1,输入其他数字将结束!");
}
}while(sc.nextInt()==1);
System.out.println("您一共添加了:"+i+"本书们分别是:");
for (Book t : ts) {
System.out.println(t);
}
}
}
JavaSE进阶08:HashSet、Map集合、HashMap、TreeMap、可变参数、不可变集合
1 简答题
1.1 简答题一
请说明下述程序执行完成以后会输出几个学生的姓名和年龄并说明原因?【业务要求:如果两个学生对象的姓名和年龄都相同则认为是同一个对象】
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Test{
public static void main(String[] args) {
HashSet<Student> hashSet=new HashSet<>();
hashSet.add(new Student("张三", 18));
hashSet.add(new Student("李四", 18));
hashSet.add(new Student("王五", 18));
hashSet.add(new Student("王五", 18));
hashSet.forEach(s-> System.out.println(s));
}
}
答:
会输出4个学生,因为使用HashSet集合存储自定义对象,如果要保证数据的唯一性,要求自定义对象所对应的类必须重写Object类中的hashCode和equals方法,但Student并没有进行重写。
Student类添加:
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
1.2 简答题二
简述HashSet集合1.7和1.8版本的底层的数据结构、以及JDK1.8引入红黑树的意义?
答:
1.7:数组+链表
1.8:节点数<=8是数组+链表,节点数>8且数组长度>=64时是数组+红黑树
当链表中的结点过多,添加元素时又要将链表中所有元素都比较一次,非常影响性能,而红黑树效率更高。
1.3 简答题三
请说明下面程序执行完毕以后在控制台的输出结果是什么?并说明原因?
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Test{
public static void main(String[] args) {
TreeMap<Student,String> treeMap=new TreeMap<>();
treeMap.put(new Student("张三", 18),"北京");
treeMap.put(new Student("李四", 18),"上海");
treeMap.forEach((key,value)-> System.out.println(key+"---"+value));
}
}
答:
报错:ClassCastException
当自定义对象使用TreeSet,需要根据泛型制定排序规则。
1.4 简答题四
请说明下述程序执行完毕以后在控制台会输出几个元素并且元素的内容是什么?并说明原因?如果想对学生进行先按照年龄从小到大排序,如果年龄相同则按照姓名从小到大进行排序应该怎么实
现?
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return 0;
}
}
class Test{
public static void main(String[] args) {
TreeMap<Student,String> treeMap=new TreeMap<>();
treeMap.put(new Student("张三", 18),"北京");
treeMap.put(new Student("李四", 18),"上海");
treeMap.forEach((key,value)-> System.out.println(key+"---"+value));
}
}
答:
只会输出一个元素:Student{name='张三', age=18}---上海
因为compareTo方法返回值只能是0,0代表相同的键,TreeMap需要键唯一,所以后面全部添加不进去。
@Override
public int compareTo(Student o) {
int result = this.age - o.age;
result = result == 0 ? this.name.compareTo(o.name) : result;
return result;
}
1.5 简答题五
请分析下述程序存在的问题并说明原因?
public class Args {
public static void main(String[] args) {
System.out.println(show( "张三","李四",10));
}
public static String show(String...name,int age){
String result="";
for (int i = 0; i < name.length; i++) {
result+=name[i];
}
return result+"的年龄为:"+age;
}
}
答:
编译不通过。如果一个方法有多个参数,包含可变参数,可变参数要放在最后。
2 编程题
题目1
假如你有3个室友,请使用HashSet集合保存3个室友的信息;
信息如下:
赵丽颖,18
范冰冰,20
杨幂,19
要求:
1:室友以对象形式存在,包含姓名和年龄两个属性;
2:使用代码保证集合中同名同年龄的对象只有一份;(相同姓名和年龄的对象认为是同一个对象)
效果:
我的室友是:[ShiYou{name='赵丽颖', a=18}, ShiYou{name='杨幂', a=19}, ShiYou{name='范冰冰', a=20}]
参考答案:
import java.util.HashSet;
import java.util.Objects;
public class ShiYou {
private String name;
private int a;
public ShiYou() {
}
public ShiYou(String name, int age) {
this.name = name;
this.a = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return a;
}
public void setAge(int age) {
this.a = age;
}
@Override
public String toString() {
return "ShiYou{" +
"name='" + name + '\'' +
", a=" + a +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShiYou shiYou = (ShiYou) o;
return a == shiYou.a &&
Objects.equals(name, shiYou.name);
}
@Override
public int hashCode() {
return Objects.hash(name, a);
}
}
class Test{
public static void main(String[] args) {
HashSet<ShiYou> hs=new HashSet<>();
hs.add(new ShiYou("赵丽颖",18));
hs.add(new ShiYou("范冰冰",20));
hs.add(new ShiYou("杨幂",19));
hs.add(new ShiYou("杨幂",19));
System.out.println("我的室友是:"+hs.toString());
}
}
题目2
请使用HashMap集合保存街道两旁的店铺名称;使用门牌号作为键,店铺名作为值,然后使用三种方式遍历输出;
信息如下:
101,阿三面馆
102,阿四粥馆
103,阿五米馆
104,阿六快递
要求:
1:键是整数,值是字符串;
2:输出的信息使用"–"链接
效果:
参考答案:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Shop {
public static void main(String[] args) {
HashMap<Integer,String> shm=new HashMap<>();
shm.put(101, "阿三面馆");
shm.put(102, "阿四粥馆");
shm.put(103, "阿五米馆");
shm.put(104, "阿六快递");
System.out.println("方式1遍历 键找值");
Set<Integer> keySet=shm.keySet();
for (Integer key : keySet) {
System.out.println(key+"--"+shm.get(key));
}
System.out.println("===================");
System.out.println("方式2遍历 键值对对象");
Set<Map.Entry<Integer,String>> entrySet=shm.entrySet();
for (Map.Entry<Integer, String> integerStringEntry : entrySet) {
System.out.println(integerStringEntry.getKey()+"--"+integerStringEntry.getValue());
}
System.out.println("===================");
System.out.println("方式3遍历 接口中默认的forEach方法配合lambda");
shm.forEach((key,value)->{
System.out.println(key+"--"+value);
});
}
}
1 简答题
1.1 简答题一
简述Stream流的使用思想以及获取Stream流的常见方式?
答:
创建一条流水线,把数据放到流水线上进行操作直至终结。
单列集合:
集合对象.stream();
双列集合:
集合对象.keySet().steam(); 所有键放入流
集合对象.values().stream(); 所有值放入流
集合对象.entrySet().stream(); 所有键值对放入流
数组:
Arrays.stream(数组名);
同种数据类型的多个数据
Stream.of(数据1,数据2,数据3......);
1.2 简答题二
如下程序
上述程序执行完毕以后,在控制台的输出结果如下所示:
请说明出现该错误的原因?
答:
forEach是流的终结方法,使用一次终结操作后流中的元素已经用光了,不可以再对该流进行任何操作。
1.3 简答题三
运行如下程序观察控制台输出结果,说明产生该问题的主要原因?
// 创建一个List集合对象
List<String> list = Arrays.asList("hello", "java8", "stream");
// 获取上述list集合所对应的流对象
list.stream().map(s -> {
list.add("world") ; // 向list集合中添加元素
return s.toUpperCase(); // 将流中的元素转换成大写
}).forEach( s -> System.out.println(s)); // 遍历流中的元素
答:
Arrays.asList创建的集合是不可变集合,不能进行增加、修改、删除操作。
1.4 简答题四
如下程序是计算1-10之间的数据和,请说明如下程序执行完毕以后的结果并说明原因?如果想让程序进行正常执行,应该如何进行改造?
答:
报错:内存溢出,需要给递归调用设置出口。
public class FileDemo02 {
public static void main(String[] args) {
int result=calc(10);
System.out.println(result);
}
public static int calc(int number){
if(number==1)
return 1;
else
return number+calc(number-1);
}
}
2 编程题
题目1
请在D盘根目录下创建一个文件:test1.txt(随意录入一些内容),再创建一个目录:测试目录
要求:
import java.io.File;
public class homeWork {
public static void main(String[] args) {
File file1=new File("D:\\test1.txt");
method(file1);
System.out.println("----------------------");
File file2=new File("D:JavaFileSpace");
method(file2);
}
public static void method(File file){
System.out.println("File的名字:"+file.getName());
System.out.println("File的绝对路径:"+file.getAbsolutePath());
System.out.println("File的相对路径:"+file.getPath());
System.out.println("File是否存在:"+file.exists());
System.out.println("File是否为文件:"+file.isFile());
System.out.println("File是否为文件夹:"+file.isDirectory());
}
}
题目2
请编写main()方法,创建以下File对象:
File file1 = new File(“test.txt”);//相对路径
File file2 = new File(“一级目录”);
File file3 = new File(“目录A/目录B/目录C”);
要求:
(相对路径,可以相对于项目也可以相对于模块)
import java.io.IOException;
public class homeWork {
public static void main(String[] args) throws IOException {
File file1 = new File("test.txt");//相对路径
File file2 = new File("一级目录");
File file3 = new File("目录A/目录B/目录C");
if(!file1.exists())
file1.createNewFile();
method(file2);
method(file3);
}
public static void method(File file){
if(!file.exists()){
file.mkdirs();
}
}
}
题目3
请在D盘下创建一个目录“多级目录”,下面随意创建一些文件和目录。
请编写main()方法,创建以下File对象:
File file = new File(“D:\多级目录”);
要求:
遍历这个多级文件夹下的所有内容(包含子文件夹的内容),判断每个File对象是否文件
如果是文件,打印:文件名加后缀名
如果是目录,打印:目录名称
import java.io.File;
import java.io.IOException;
public class homeWork {
public static void main(String[] args) throws IOException {
File file = new File("D:\\TestFiles");
method(file);
}
public static void method(File file){
File[] files=file.listFiles();
for (File file1 : files) {
if(file1.isFile()){
System.out.println("文件名:"+file1.getName());
}else{
System.out.println("文件夹名:"+file1.getName());
method(file1);
}
}
}
}
1 简答题
1.1 简答题一
简述IO流的分类以及输入流和输出流作用?
答:
IO流分为字节流和字符流
字节流分为InputStream输入流、OutputStream输出流
字符流文卫Reader输入流、Writer输出流
1.2 简答题二
请说明如下程序执行完毕以后结果并说明原因?
答:
Exception in thread "main" java.io.FileNotFoundException: IOModule\JavaIOSpace (拒绝访问。)
原因:IOModule模块的JavaIOSpace 是个文件夹,不能够写入内容
1.3 简答题三
Java中的字节流是可以操作任意类型的数据(音频、视频、文本…),请简述字符流出现的意义?
答:
如果利用字节流,把文本文件中的中文读取到内存中,可能会出现乱码
如果利用字节流,把中文写到文本文件中,也有可能出现乱码
字符流的作用就是解决语言的乱码问题。
1.4 简答题四
请将如下程序在idea进行执行,分析输出结果的原因?
// 对"中国"进行编码
String s1 = "中国" ;
byte[] bytes = s1.getBytes();
// 对上述得到的字节数组进行编码
String s2 = new String(bytes , "UTF-8") ;
System.out.println(s2);
答:
控制台输出 中国
getBytes()使用平台默认的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中。
IDEA默认为UTF-8,代码中对应的解码也是UTF-8,所以不会乱码。
1 简答题
1.1 简答题一
如下程序执行完毕以后,a.txt文件中的内容是什么并说明原因?
FileWriter fw= new FileWriter("a.txt");
fw.write("你好世界");
答:
a.txt文件中没有任何内容
原因:使用字符流写数据并并不是直接讲数据写入到磁盘中,而是先写入到了缓冲区中,而代码中没有对缓冲区进行刷新或者关闭,数据就没有写入到磁盘中。
1.2 简答题二
简述flush方法和close方法的区别?
答:
flush()刷新流,之后还可以继续写数据。
close()关闭流,释放资源,但是在关闭之前会先写出数据。一旦关闭,就不能再写数据。
1.3 简答题三
请分析如下程序执行完毕以后a.txt文件的内容是什么并说明原因?如果需要在a.txt文件中保存所有数据应该怎么处理?
FileWriter fw1=new FileWriter("a.txt");
fw1.writer("你好");
fw1.close();
FileWriter fw2=new FileWriter("a.txt");
fw2.write("世界");
fw2.close();
答:
内容:传智播客
原因:一个参数的构造方法,文件存在就会清空内容
解决:FileWriter fw2=new FileWriter("a.txt",true);//追加续写
1.4 简答题四
运行下述程序会出现什么错误?请说明出现该错误的原因以及如何解决该错误?
答:
User类的对象想要能被序列化,必须要实现一个接口Serializable.
1.5 简答题五
请分析产生如下错误的原因以及对应的解决方案?
Exception in thread "main" java.io.InvalidClassException: com.itheima.io.obj.User; local class incompatible: stream classdesc serialVersionUID = 4001622083751882644, local class serialVersionUID = 6175241864707791838
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1883)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1749)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2040)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1571)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at com.itheima.io.obj.Demo01.main(User.java:21)
答:
方法1:重新序列化
方法2:给对象所属的类加一个serialVersionUID ,不让虚拟机计算
1 简答题
1.1 简答题一
简述一下并发和并行的区别?
答:
并发:在同一时刻,多个指令在单个cpu上交替执行
并行:在同一时刻,多个指令在多个cpu上同时执行
1.2 简答题二
简述什么是线程,什么是进程?
答:
线程:是进程中的单个顺序控制流,是程序中的一条执行路径,是cpu调度和分派的基本单位
进程:是正在运行的程序,是操作系统进行资源分配和调度的一个独立单位
1.3 简答题三
简述启动线程使用的是什么方法以及start方法和run方法的区别?
答:
start方法:用来启动线程,只能调用一次
run方法:其中封装的是需要线程执行的代码,可以被多次调用
1.4 简答题四
简述创建多线程常见方式以及它们之间的优缺点?
答:
创建线程的3中方式:
1.继承Thread类,重写run方法
2.实现Runnable接口,并重写改接口中的run方法
3.实现Callable接口,重写call方法
优缺点:
1.实现Runnable和实现Callable接口接口方式:
优点:扩展性强,实现该接口的同时还能继承其他类
缺点:编程相对复杂,不能直接使用Thread类中的方法
2.继承继承Thread类方式:
优点:编程相对简单,可以直接使用Thread类中的方法
缺点:扩展性差,不能再继承其他类
1.5 简答题五
某程序是模拟电影票的买票,是通过三个窗口(3个线程)共出售100张票。 现在运行该程序出现了如下所示情况:
窗口三在买票,还剩下7张票
窗口一在买票,还剩下4张票
窗口三在买票,还剩下4张票
窗口二在买票,还剩下3张票
窗口二在买票,还剩下2张票
窗口一在买票,还剩下0张票
窗口三在买票,还剩下1张票
请简述出现该问题的原因对应的解决方案?
答:
程序的运行结果说明出现了线程安全问题。
产生原因:
多个线程同时对共享数据进行操作(增删改)时,由于 CPU的调度问题,导致单个线程无法一次性完成对共享资源的操作,出现了数据不一致的问题。
解决方案:
1.从程序设计的角度考虑,尽量不要让多个线程去操作共享数据
2.使用同步技术(synchronize或lock),时得同一时刻只能由一个线程对共享数据进行操作
1.6 简答题六
简述通过ThreadPoolExecutor创建线程池时,构造方法对应的7个参数分别表示什么意思?并说明常见的任务的拒绝策略都有哪些?
答:
参数一:核心线程数量(不能被销毁)
参数二:最大线程数
参数三:空闲线程最大存活时间
参数四:时间单位(TimeUnit(工具类).SECONDS)
参数五:任务队列
参数六:创建线程工厂
参数七:任务的拒绝策略
ThreadPoolExecutor.AbortPolicy: 丢弃任务并抛出 RejectedExecutionException异常。是默认的策略。
ThreadPoolExecutor.DiscardPolicy: 丢弃任务,但是不抛出异常 这是不推荐的做法。
ThreadPoolExecutor.DiscardOldestPolicy: 抛弃队列中等待最久的任务 然后把当前任务加入队列中。
ThreadPoolExecutor.CallerRunsPolicy: 调用任务的run()方法绕过线程池直接执行
1.1 简答题一
简述网络编程三要素以及它们的含义?
答:
IP:设备在网络中的唯一标识
端口号:应用程序在设备中的唯一标识
协议:数据在传输过程中要遵守的协议
1.2 简答题二
简述ipv4和ipv6的组成规则?
答:
ipv4:
给每个连接在网络上的主机分配一个32bit地址。按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,也就是4个字节。ip地址写成十进制的形式,中间使用符号“.”分隔不同的字节
ipv6:
采用128位地址长度,每16个字节一组,分成8组十六进制数,这样就解决了网络地址资源数量不够的问题
1.3 简答题三
简述UDP协议的特点?
答:UDP协议:面向无连接的通信规则,速度快,大小限制64k,不安全,容易丢失数据
1.4 简答题四
简述TCP协议的特点?
答:
1.TCP协议是一种面向连接的协议
2.TCP协议是一种可靠的协议
3.TCP协议是基于IO流进行的数据传输,传输数据无大小限制
4.TCP协议的通信效率比较低
1.5 简答题五
简述三次握手过程?
答:第一次握手,客户端向服务器端发出连接请求,等待服务器确认
第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求
第三次握手,客户端再次向服务器端发送确认信息,确认连接
1.6 简答题六
简述四次挥手过程?
答:客户端向服务器发送取消请求
服务器反馈客户端表示收到取消请求
服务器向客户端确认取消请求
客户端向服务器发送确认取消请求
1.7 简答题七
简述日志和输出语句的区别?
答:
输出语句:
取消日志:需要修改代码,灵活性比较差
输出位置:只能是控制台
多线程:和业务代码处于一个线程中
日志技术:
取消日志:不需要修改代码,灵活性比较好
输出位置:可以将日志信息写入到文件或者数据库中
多线程:多线程方式记录日志,不影响业务代码的性能
1 简答题
1.1 简答题一
简述类的加载过程?
答:1、加载,通过包名+类名,获取这个类,用流进行传输,加载完成之后创建一个class对象
2、链接,验证Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全。准备,初始化静态变量。解析,本类中如果用到了其他类,此时就需要找到对应的类
3、初始化,静态变量赋值以及初始化其他资源
1.2 简答题二
简述类加载器的分类以及双亲委派模型?
答:分类
Bootstrap class loader:虚拟机的内置类加载器,通常表示为null ,并且没有父null
Platform class loader:平台类加载器,负责加载JDK中一些特殊的模块
System class loader:系统类加载器,负责加载用户类路径上所指定的类库
如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式
1.3 简答题三
简述您对反射的理解以及使用反射的思想步骤?
答:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意属性和方法;
这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
获取Class类对象,通过调用相应的方法获取类中的构造方法,成员变量,成员方法
1.4 简答题四
简述获取一个类的字节码文件对象存在哪几种方式?
答:
Class.forName(全类名)方法
类名.class属性
对象名.getClass()方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。