二维码
找好货

扫一扫关注

当前位置: 首页 » 资讯 » 专题 » 正文

还在等什么!手把手教你用Android复习Java基础,你又会哪些呢?(学完java怎么开发android)

放大字体  缩小字体 发布日期:2022-07-31 15:14:09    作者:life    浏览次数:5130    评论:0
导读

1.重载和重写的区别重写是一般是用于子类在继承父类时,重写(重新实现)父类中的方法。重载是一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。2.接口是否可继承接口?抽象类是否可实现接口?抽象类是否可继承具体类?接口可

1.重载和重写的区别
  • 重写是一般是用于子类在继承父类时,重写(重新实现)父类中的方法。
  • 重载是一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。
2.接口是否可继承接口?抽象类是否可实现接口?抽象类是否可继承具体类?

接口可以继承接口,而且支持多重继承抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。

3.访问修饰符 public,private,protected,以及不写(默认)时的区别4.String 是最基本的数据类型吗?

不是。java 中的基本数据类型只有 8 个 :byteshort、int、long、float、double、charboolean;除了基本类型(primitive type),剩下的都是引用类型(referencetype),Java 5 以后引入的枚举类型也算是一种比较特殊的引用类型。

5.是否可以继承 String 类

String 类是 final 类,不可以被继承。

补充:继承 String 本身就是一个错误的行为,对 String 类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)

6.String 和 StringBuilderStringBuffer 的区别?

String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。

  • String 只读不写,不可被继承
  • StringBuilder 可读可写,线程不安全的,速度快。
  • StringBuffer 可读可写,线程安全的,速度慢。


7.char 型变量中能不能存贮一个中文汉字,为什么?

char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个 char 类型占 2 个字节(16 比特),所以放一个中文是没问题的。

8.String s = new String(“xyz”);创建了几个字符串对象?

两个对象,一个是静态区的”xyz”,一个是用 new 创建在堆上的对象。

9.Java 中的 final 关键字有哪些用法?
  1. 修饰类:表示该类不能被继承;
  2. 修饰方法:表示方法不能被重写;
  3. 修饰变量:表示变量只能一次赋值以后值不能被修改(常量)。
10.阐述 final、finally、finalize 的区别。
  • final:修饰符(关键字)有三种用法:如果一个类被声明为 final,意味着它不能再派生出新的子类,即不能被继承,因此它和 abstract 是反义词。将变量声明为 final,可以保证它们在使用中不被改变,被声明为 final 的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为 final 的方法也同样只能使用,不能在子类中被重写。
  • finally:通常放在 try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要 JVM 不关闭都能执行,可以将释放外部资源的代码写在 finally 块中.
  • finalize:Object 类中定义的方法,Java 中允许使用 finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写 finalize()方法可以整理系统资源或者执行其他清理工作。
11.List、Set、Map 是否继承自 CollectIOn 接口,它们的区别?

List、Set 是 ,Map 不是。Map 是键值对映射容器,与 List 和 Set 有明显的区别:

  • Set无序、不能重复
  • List有序,可以重复
  • Map无序,Key不能重复,Value能重复
12.Collection 和 Collections 的区别?

Collection 是一个接口,它是 Set、List 等容器的父接口;Collections 是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等。

13.ArrayList、Vector、linkedList 的区别?
  • ArrayList 数组结构,非线程安全,内存利用率差,查找快,增删慢;
  • Vector 数组结构,线程安全,内存利用率差,查找快,增删慢;
  • linkedList 双向链表结构,非线程安全的,内存的利用率更高,查找慢,增删快;
14.创建线程的方式
  1. 继承Thread类,重写run()方法
  2. 实现Runnable接口,并实现该接口的run()方法
  3. 实现Callable接口,重写call()方法

Callable接口实际是属于Executor框架中的功能类,Callable接口与Runnable接口的功能类似,但提供了比Runnable更强大的功能:

public class TestCallable { //创建线程类 public static class MyTestCallable implements Callable { public String call() throws Exception { retun "Hello World"; } } public static void main(String[] args) { MyTestCallable mMyTestCallable= new MyTestCallable(); ExecutorService mExecutorService = Executors.newSingleThreadPool(); Future mfuture = mExecutorService.submit(mMyTestCallable); try { //等待线程结束,并返回结果 System.out.println(mfuture.get()); } catch (Exception e) { e.printStackTrace(); } } } 复制代码15.线程的状态

  1. 新建状态(New):新创建了一个线程对象。
  2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
  3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
  4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
  • 等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
  • 同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
  • 其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  1. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
16.sleep和wait的区别
  1. sleep是线程中的方法,但是wait是Object中的方法。
  2. sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
  3. sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
  4. sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。
17.Synchronized同步方法和同步代码块
  • 同步方法的锁对象是this
  • 同步静态方法的锁对象是类.class

对象锁: synchronized(object) 锁住的是对象,每个对象自己拥有一个锁
类锁: synchronized(Class) 锁住的是类,也就是同一个类的实例,任意时刻只会有一个线程能获得资源

18.Java 中 ++ 操作符是线程安全的吗?

不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储回内存,这个过程可能会出现多个线程交差。

19.a = a + b 与 a += b 的区别

+= 隐式的将加操作的结果类型强制转换为持有结果的类型。如果两这个整型相加,如 byte、short 或者 int,首先会将它们提升到 int 类型,然后在执行加法操作。如果加法操作的结果比 a 的最大值要大,则 a+b 会出现编译错误,但是

byte a = 127; byte b = 127; b = a + b; // error : cannot convert from int to byte b += a; // ok 复制代码

(译者注:这个地方应该表述的有误,其实无论 a+b 的值为多少,编译器都会报错,因为 a+b 操作会将 a、b 提升为 int 类型,所以将 int 类型赋值给 byte就会编译出错)

20.int 和 Integer 哪个会占用更多的内存?

Integer 对象会占用更多的内存。Integer 是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少。

21.“a==b”和”a.equals(b)”有什么区别?

如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比较,所以通常需要重写该方法来提供逻辑一致性的比较。例如,String 类重写 equals() 方法,所以可以用于两个不同对象,但是包含的字母相同的比较。

22.a.hashCode() 有什么用?与 a.equals(b) 有什么关系?

hashCode() 方法是相应对象整型的 hash 值。它常用于基于 Hash 的集合类,如 HashtableHashMaplinkedHashMap 等等。它与 equals() 方法关系特别紧密。根据 Java 规范,两个使用 equal() 方法来判断相等的对象,必须具有相同的 hash code

  • 两个obj,如果equals()相等,hashCode()一定相等。
  • 两个obj,如果hashCode()相等,equals()不一定相等(Hash散列值有冲突的情况,虽然概率很低)。
23.浅拷贝和深拷贝的区别?
  • 浅拷贝:在拷贝一个对象时,对对象的基本数据类型的成员变量进行拷贝,但对引用类型的成员变量只进行引用的传递,并没有创建一个新的对象,当对引用类型的内容修改会影响被拷贝的对象。

实现浅拷贝的方法:

java中clone方法是一个浅拷贝,引用类型依然在传递引用

  • 深拷贝:在拷贝一个对象时,除了对基本数据类型的成员变量进行拷贝,对引用类型的成员变量进行拷贝时,创建一个新的对象来保存引用类型的成员变量。

实现深拷贝有两种方法:

(1)序列化该对象,然后反序列化回来,就能得到一个新的对象了。
序列化:将对象写入到IO流中; 反序列化:从IO流中恢复对象 序列化机制允许将实现序列化的java对象转化为字节序列,这些字节序列可以保存到磁盘或者网络传输上,以达到以后恢复成原来的对象,序列化机制使得对象可以脱离程序的运行而独立存在。

(2)继续利用clone()方法,对该对象的引用类型变量再实现一次clone()方法。

24.Java四种引用

引用



强引用(Strongly Re-ference)

不会被回收

正常编码使用

软引用(Soft Reference)

内存不够了,被GC

可作为缓存

弱引用(Weak Reference)

GC发生时

可作为缓存(WeakHashMap)

虚引用(Phantom Reference)

任何时候

监控对象回收,记录日志

25.ArrayList扩容机制

//我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍, int newCapacity = oldCapacity + (oldCapacity >> 1); 复制代码26.为什么会设计String类

字符串常量池:

String 不可变的第一个好处是可以使用字符串常量。在 Java 中有字符串常量池的概念,比如两个字符串变量的内容一样,那么就会指向同一个对象,而不需创建第二个同样内容的新对象,例如:

String s1 = "lagou";

String s2 = "lagou";

其实 s1 和 s2 背后指向的都是常量池中的同一个“lagou”,如下图所示:

在图中可以看到,左边这两个引用都指向常量池中的同一个“lagou”,正是因为这样的机制,再加上 String 在程序中的应用是如此广泛,我们就可以节省大量的内存空间

用作 HashMap 的 key:

String 不可变的第二个好处就是它可以很方便地用作 HashMap (或者 HashSet) 的 key。通常建议把不可变对象作为 HashMap的 key,比如 String 就很合适作为 HashMap 的 key。

缓存 HashCode:

String 不可变的第三个好处就是缓存 HashCode

在 Java 中经常会用到字符串的 HashCode,在 String 类中有一个 hash 属性,代码如下:

private int hash; 复制代码

这是一个成员变量,保存的是 String 对象的 HashCode。因为 String 是不可变的,所以对象一旦被创建之后,HashCode 的值也就不可能变化了,我们就可以把 HashCode 缓存起来。

这样的话,以后每次想要用到 HashCode 的时候,不需要重新计算,直接返回缓存过的 hash 的值就可以了,因为它不会变,这样可以提高效率,所以这就使得字符串非常适合用作 HashMap 的 key。

而对于其他的不具备不变性的普通类的对象而言,如果想要去获取它的 HashCode ,就必须每次都重新算一遍,相比之下,效率就低了。

线程安全:

String 不可变的第四个好处就是线程安全,因为具备不变性的对象一定是线程安全的,我们不需要对其采取任何额外的措施,就可以天然保证线程安全。

由于 String 是不可变的,所以它就可以非常安全地被多个线程所共享,这对于多线程编程而言非常重要,避免了很多不必要的同步操作。

27.装箱和拆箱

装箱:把基本数据类型转为包装类对象。

转为包装类的对象,是为了使用专门为对象设计的API和特性

拆箱:把包装类对象拆为基本数据类型。

转为基本数据类型,一般是因为需要运算,Java中的大多数运算符是为基本数据类型设计的。比较、算术等


装箱: 基本数值---->包装对象

Integer obj1 = new Integer(4);//使用构造函数函数 Integer obj2 = Integer.valueOf(4);//使用包装类中的valueOf方法 复制代码

拆箱: 包装对象---->基本数值

Integer obj = new Integer(4); int num1 = obj.intValue(); 复制代码28.为什么要进行拆箱和装箱?

Java是一种完全面向对象的语言。因此,包括数字、字符、日期、布尔值等等在内的一切,都是对象。似乎只需要一种方式来对待这些对象就可以了。对于CPU来说,处理一个完整的对象,需要很多的指令,对于内存来说,又需要很多的内存。如果连整数都是对象,那么性能自然很低。

于是创造了这样一种机制,使得这些基本类型在一般的编程中被当作非对象的简单类型处理,在另一些场合,又允许它们被视作是一个对象。

这就是装箱和拆箱。

作用:为了保证通用性和提高系统性能

一种最普通的场景是调用一个包含类型为Object的参数的函数(方法),该Object可支持任意 类型,以便通用。当你需要将一个值类型传入容器时,就需要装箱了。

另一种的用法,就是一个泛型 的容器,同样是为了保证通用,而将元素定义为Object类型的,将值类型的值加入该容器时,需要装箱。


原文:https://juejin.cn/post/7124247720688091150

 
关键词: lagou
(文/life)
打赏
免责声明
• 
本文为life原创作品,作者: life。欢迎转载,转载请注明原文出处:https://www.114618.com/news/119981.html 。本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们。
0相关评论
 

(c)2008-2018 找好货 B2B SYSTEM All Rights Reserved

京ICP备2022008976号-2