自动化之Java面试

1.重写与重载的区别

重载规则:
重载是指在同一个类中,定义了多个同名方法,但同名方法的参数类型或参数个数不同就是方法重载,节约词汇,例如driver.switchTo().frame(index/nameOrId/frameElement),方法重载的经典使用场景是 String 类型的 valueOf 方法,valueOf 方法重载有 9 种实现
java的重载(overload) 最重要的应用场景就是构造器的重载,目的是对方法(构造器)进行功能扩展,以应对多业务场景的不同使用需求。提高程序的健壮性和扩展性

重写规则:
建立在继承关系上,子类和父类的方法名称,参数类型、参数个数全部相同,不仅可以得到父类的东西,同时也加入了自己的东西,重用性,扩展性,复用性,用@override关键字修饰,比较经典的是 Object 类中的 equals 方法。 Object 是所有类的父类
简单总结:
总结
方法重写(Override)和方法重载(Overload)都是面向对象编程中,多态特性的不同体现,方法重写描述的是父类和子类的方法关系,而方法重载描述的是同一个类中多个同名方法的方法关系。除此之外方法重写和方法重载还有:Override 关键字、参数类型和参数个数、返回类型、抛出异常和权限控制符等不同点。
生活例子:
你想吃一碗面,我给你提供了拉面,炒面,刀削面,担担面供你选择,这是重载;
你想吃一碗面,我不但给你端来了面,还给你加了青菜,加了鸡蛋,这个是重写;
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

2.==“和equals方法究竟有什么区别

"和equals方法究竟有什么区别?
==:用于基本类型数据的比较,比较的是值
用于引用数据类型的比较所指向的对象的地址
equals:不能用于基本类型的数据的比较
用于引用类型的比较:
如果没有对equals进行重写,比较的是引用类型的变量所指向的对象的地址
如果对equals进行重写,比较的是所指向的对象的内容(String/Date)又可分为两种情况:
hashcode进行重写:
如果相同,equals()方法返回值不能确定,可能为true,也可能为false
不相同,用equals()方法判断返回的一定是false
不对hashcode进行重写,用equals()方法判断返回的一定是true

3.static的基本用法

static:表示“全局”或“静态”的意思,修饰类的成员方法和成员变量,也可以编写static代码块优化程序性能

a.static修饰的成员方法
一般称为“静态方法”,它不依赖于任何对象就能进行访问,可以使用“ 类名.方法名”的方式操作方法,避免了先要new出对象的
繁琐和资源消耗,它也没有this和super关键字,静态方法中不能访问非静态成员变量和非静态成员方法,因为非静态成员变量和
非静态成员方法必须依赖具体的对象才能够被调用,但是对于非静态成员方法是可以访问静态成员方法和静态变量的。
b.static修饰的变量
一般称为“静态变量”或“类变量”,静态变量与非静态变量的区别是:静态变量所在的类的所有对象共享这一个属性(不同的类中不共享),
在内存中只有一个副本,它当且仅当在类初始加载时才会被初始化,非静态变量是对象所拥有的,在创建对象时被初始化,存在多个副本,
各个对象拥有的副本相互不影响,可以用“类名.静态变量”或“对象.静态变量”进行访问,但“类名.静态变量”更能体现出static的作用。
局部变量不能声明为静态变量。static变量进行初始化时有默认值,final static初始化时必须有初始值
以下两种情况使用static变量:(1)静态变量所在的类的所有对象直接共享数据(2)访问变量时
c.static代码块
一般称为“静态代码块”,可放在类中的任何地方,类中可有多个static代码块,在类初次被加载时会按照static代码块顺序来执行每个static
代码块并且只会执行一次,静态代码块不能放在任何方法的内部

**总结:**static的基本作用:方便在没有创建对象情况下调用方法/变量

4.接口和抽象类的区别

接口是对行为的抽象,接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现
特点:
接口中可以含有变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。
从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。
如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。对于遵循某个接口的抽象类,可以不实现该接口中的抽象方法。

抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中没有任何意义,必须根据子类的实际需求来进行
特点:
abstract修饰的类为抽象类,此类不能有对象,(无法对此类进行实例化); abstract修饰的方法为抽象方法,是抽象方法,此方法不能有方法体(为空),包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

在接口和抽象类的选择上,必须遵守这样一个原则:
行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能

5.深拷贝和浅拷贝的区别是什么?

浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象

深拷贝:被复制对象的所有变量都含有与原来的对象相同的值.而那些引用其他对象的变量将指向被复制过的新对象.而不再是原有的那些被引用的对象.换言之.深拷贝把要复制的对象所引用的对象都复制了一遍.

6.文件读取

FileInputstream / FileOutputstream
FileReader / FileWriter

7.List,Set,Map三者的区别

List(对付顺序的好帮手): List接口存储一组不唯一(可以有多个元素引用相同的对象),有序
的对象
Set(注重独一无二的性质): 不允许重复的集合。不会有多个元素引用相同的对象。
Map(用Key来搜索的专家): 使用键值对存储。Map会维护与Key有关联的值。两个Key可以引用相同的对象,但Key不能重复,典型的Key是String类型,但也可以是任何对象

8.创建对象有几种方式

new、反射、clone 拷贝、反序列化。

9.String、String StringBuffer 和 StringBuilder 的区别是什么

String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的字符数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的String对象。
StringBuffer和StringBuilder他们两都继承了AbstractStringBuilder抽象类,从AbstractStringBuilder抽象类中我们可以看到, 他们的底层都是可变的字符数组,所以在进行频繁的字符串操作时,建议使用StringBuffer和StringBuilder来进行操作。 另外StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。

10.反射的基础应用

概述:反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个属性和方法,这种能够动态获取信息以及动态调用对象的方法的功能称为Java的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象,而解剖使用的就是Class类中的方法,所以先要获得
每一个字节码文件对应的Class类型的对象。反射就是把Java类中的各种成分映射成一个个的Java对象
一.Class类:代表一个类
Field类:代表类的成员变量(类的属性)
Method类:代表类的方法
Construtor类:代表类的构造方法
Arrary类:提供了动态创建数组以及访问数组的元素的静态方法
要想操作反射,必须先拿到反射的入口
获取Class对象的三种方式
* 1 Object ——> getClass();//对象都有了还要反射干什么
* 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性//需要导入类的包,依赖太强,不导包就抛编译错误
* 3 通过Class类的静态方法:forName(String className)(常用)//,一个字符串可以传入也可写在配置文件中等多种方法
二.通过Class对象获取类中的获取单个的"公有的"构造方法
1、public Constructor getConstructor(Class… parameterTypes):获取单个的"公有的"构造方法
parameterTypes:构造方法中的形参类型,例如String.class
2.调用构造方法
Constructor–>newInstance(Object… initargs)
initargs:形参的具体值
三.通过Class对象获取类中的“公有”的方法
1.public Method getMethod(String name,Class<?>… parameterTypes):
name : 方法名;
Class … : 形参的Class类型对象
举例:
//获取公有的构造方法
Constructor con = clazz.getConstructor(String.class);
con.newInstance(“曹心情构造方法”);
2.调用方法
Method --> public Object invoke(Object obj,Object… args)
obj : 要调用方法的对象;
args:调用方式时所传递的实参;
注意:要调用方法的对象obj需要用到构造方法,实例化一个对象
Object obj = clazz.getConstructor().newInstance();
另外如果方法是静态的,obj可以省略,直接写null
举例:
//获取公有的setName()方法
Method m = clazz.getMethod(“setName”, String.class);
Object obj = clazz.getConstructor().newInstance();
m2.invoke(obj, “曹普通方法”);

11.fastjson基本使用

一.Json格式
1.1 JSON对象:
{
“name”: “张三”,
“age”: 24
}
1:数据在花括号中
2:数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象)
3:每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号)
1.2:JSON对象数组

[
{“name”: “张三”, “age”: 24},
{ “name”: “王五”, “age”: 22}
]
1:数据在方括号中(可理解为数组)
2:方括号中每个数据以json对象形式出现
3:每两个数据以逗号分隔(最后一个无需逗号)

1.3:两种形式的结合

{
“部门名称”:“研发部”,
“部门成员”:[
{“name”: “张三”, “age”: 24},
{“name”: “王五”, “age”: 22}],
“部门位置”:“xx楼21号”
}
1.4:JSON字符串
1:它必须是一个字符串,由" "或者’ '包裹数据,支持字符串的各种操作
2:里面的数据格式应该要满足其中一个格式,可以是json对象,也可以是json对象数组或者是两种基本形式的组合变形
总结:json可以简单的分为基本形式:json对象,json对象数组。两种基本格式组合变形出其他的形式,但其本质还是json对象或者json对象数组中的一种。json对象或对象数组可以转化为json字符串,使用于不同的场合。
注意点:在封装json数据的时候,很容易出现错误,比如粗心的在最后一条数据的末尾加上了逗号等等,这里我提供一个在线验证工具,方便大家验证json数据格式的正确性
http://www.bejson.com/
二:fastJson的使用
JSONObject和JSONArray继承JSON,JSON代表JSONObject和JSONArray的转化,JSON类主要是实现转化用的,最后的数据获取,还是要通过上面的JSONObject和JSONArray来实现
JSONObject代表json对象,底层操作是由Map实现的,通过"键:值"对中的键来获取其对应的值,通过各种形式的get()方法可以获取json对象中的数据
JSONArray代表json对象数组,底层操作由List实现的,因为JSONArray代表json对象数组,json数组对象中存储的是一个个json对象,所以类中的方法主要用于直接操作json对象
1.JSON类之toJSONString()方法,实现json对象转化为json字符串和javabean对象转化为json 字符串
2.JSON类之parseObject()方法,实现json字符串转换为json对象或javabean对象:
Student stu1=JSON.parseObject(jsonstr,Student.class);
3.parseArray()将json字符串转化为json对象数组或转化成包含泛型的List
三.举例使用
public class Student {
private String name;
private int 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;
}
@Override
public String toString() {
return “Student [name=” + name + “, age=” + age + “]”;
}
}
public class StudentGroup {
private String username;
private List stus = new ArrayList();
public StudentGroup(){}
public StudentGroup(String username, List stus) {
this.username = username;
this.stus = stus;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List getStus() {
return stus;
}
public void setStus(List stus) {
this.stus = stus;
}
@Override
public String toString() {
return “StudentGroup [username=” + username + “, stus=” + stus + “]”;
}

}
public class FastJson {
public static void main(String[] args) {
List stus = new ArrayList();
Student student1=new Student(“bob”,24);
Student student2=new Student(“lily”, 23);
stus.add(student1);
stus.add(student2);
System.out.println(“简单java类转json字符串”);
String str1=JSON.toJSONString(student1);
System.out.println(str1);
System.out.println();
System.out.println(“List转json字符串”);
System.out.println(JSON.toJSONString(stus));
System.out.println();
System.out.println(“复杂java类转json字符串”);
StudentGroup group = new StudentGroup(“StudentGroup”, stus);
String GroupJson = JSON.toJSONString(group);
System.out.println(GroupJson);
System.out.println();
/**
* json字符串转java对象
* 注:字符串中使用双引号需要转义 (" --> “),这里使用的是单引号
/
/
json字符串转简单java对象
* 字符串:{“password”:“123456”,“username”:“dmego”}/
System.out.println(“json字符串转简单java对象”);
String jsonStr1 = “{‘name’:‘曹新晴’,‘age’:‘30’}”;
Student student = JSON.parseObject(jsonStr1, Student.class);
System.out.println(student.toString());
System.out.println();
/

* json字符串转List对象
* 字符串:对象数组[{“age”:24,“name”:“bob”},{“age”:23,“name”:“lily”}]
* 如果字符串是 对象,比如 {‘name’:‘曹新晴’,‘age’:‘30’}”,就需要先转换成Map,再转换成List
*/
System.out.println(“json字符串转List对象”);
String jsonStr2 = “[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]”;
List students = JSON.parseArray(jsonStr2, Student.class);
System.out.println(students.toString());
System.out.println();
System.out.println(“json字符串转复杂java对象”);
String jsonStr3 = “{‘username’:‘StudentGroup’,‘stus’:[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]}”;
StudentGroup studentGroup = JSON.parseObject(jsonStr3, StudentGroup.class);
System.out.println(studentGroup);
String jsonStr4 = “[{‘username’:‘StudentGroup’,‘stus’:[{‘age’:24,‘name’:‘bob’},{‘age’:23,‘name’:‘lily’}]},{‘username’:‘StudentGroup2’,‘stus’:[{‘age’:34,‘name’:‘bob2’},{‘age’:33,‘name’:‘lily2’}]}]”;
List parseArray = JSON.parseArray(jsonStr4, StudentGroup.class);
System.out.println(“parseArray:”+parseArray);
System.out.println();
System.out.println(“json字符串转Map对象”);
String jsonStr5 =“{‘mobilephone’:‘13517315120’,‘pwd’:‘315120’}”;
Map<String, String> map = JSON.parseObject(jsonStr5, Map.class);
}
}

12.内存分配

堆内存

用来存放由new创建的对象实例和数组。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。访问对象需靠引用变量(栈中创建),常量池存在于堆中。

栈内存

栈用于存储程序运行时在方法中声明的所有局部变量(栈主要存储方法中的局部变量)包括:1.用来保存基本数据类型的值。特点:栈内存的数据用完就释放

方法区(静态区)

用于存放类的各种信息(包括方法)都在方法区存储。(将类的成员都加载到方法区)和static变量

13.数据类型

1. 基本数据类型
a) 数字
i. 整数:byte(1个字节) short(2个字节) int(4个字节,整型常量默认该类型) long(8个字节)
ii. 浮点数:float(4个字节) double(8个字节,浮点常量默认为该类型)
b) 字符 char(2个字节)
c) 布尔 boolean(1位)
2.引用类型(4个字节)
接口、对象、类、数组、字符串String、集合等
1:java开发过程中整型用int、小数用double、布尔用boolean;
2:类型转换都是小范围向大范围转换,大范围往小范围转化需要用到强制转换

14.字符串的常用操作

● charAt(i) 获取指定位置的字符
● length() 字符串长度,字符的数量
● indexof()找第一个子串出现的初始位置,找不到返回-1
● indexof(子串,start)从执行位置向后找
● lastIndexof(子串) 从后向前找
● subString(start)截取start到末尾
● subString[start,end )截取[start,end )范围
● trim()去除两端的空白字符
● matches()用来判断是否匹配正则表达式
Java中的 split 函数是用于按指定字符(串)或正则去分割某个字符串,结果以字符串数组形式返回;
StringBuilder: 可变的字符序列,封装char[]数组,提供了一组方法,可以对内部封装的字符进行修改,常用来代替字符串做高效的字符串连接
● append() 追加字符内容,内部数组默认初始容量16,放满后翻倍+2;

15.集合

1.List特点
元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引;
允许使用重复元素,可以通过索引来访问指定位置的集合元素;
默认按元素的添加顺序设置元素的索引。
相关实现类:ArrayList基于数组结构实现,使用在查询比较多的场合下,基本操作如下:
add(E e)添加元素
add(int index, E element)添加元素到指定位置,ArrayList元素下标从0开始
size()获取ArrayList长度
get(int index)获取指定位置的元素
addAll(Collection<? extends E> c)添加另外一个集合
addAll(int index,Collection<? extends E> c)添加另外一个集合到指定位置
clear()清空
set(int index, E element)设置某个位置的元素
contains(Object o)判断集合中是否包含某个元素
remove(int index)删除指定位置的元素
remove(Object o)删除特定元素
indexOf(Object o)返回元素的索引
遍历:
//通过下标遍历集合
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//通过增强for循环
for (String Str : list) {
System.out.println(Str);
}
//通过迭代器遍历集合
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
2.Set特点
无序且不可重复
HashSet是Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类
3.Map特点
所有的key构成的集合是Set:无序的、不可重复的
HashMap是Map接口使用频率最高的实现类
常用方法:
添加、删除、修改操作
put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
putAll(Map m):将m中的所有key-value对存放到当前map中
remove(Object key):移除指定key的key-value对,并返回value
clear():清空当前Map中的所有数据
查询操作
get(Object key):获取指定key对应的value
containsKey(Object key):是否包含指定的key
containsValue(Object value):是否包含指定的value
size():返回map中key-value对的个数
isEmpty():判断当前map是否为空
equals(Object obj):判断当前map和参数对象obj是否相等
其他操作
keySet():返回所有key构成的Set集合
Set set = map.keySet();//遍历map所有的key
for (String s : set) {
System.out.println(s);
}
values():返回所有value构成的Collection集合
Collection values = map.values(); //遍历map所有的value
for (String value : values) {
System.out.println(value);
}
entrySet():返回所有key-value对构成的Set集合
Set keys = map.keySet();// 遍历map所有的键值对
for (String k : keys) {
String v = map.get(k);
System.out.println(k + “:” + v);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值