卷妹带你回顾Java基础(一)每日更新Day2
👩💻博客主页:京与旧铺的博客主页
✨欢迎关注🖱点赞🎀收藏⭐留言✒
🔮本文由京与旧铺原创,csdn首发!
😘系列专栏:java学习
👕参考网站:牛客网
💻首发时间:🎞2022年8月4日🎠
🎨你做三四月的事,八九月就会有答案,一起加油吧
🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦
🎧最后的话,作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲
💬推荐一款模拟面试、刷题神器👉
🛒导航小助手🎪
卷妹带你回顾Java基础(一)每日更新Day2🛒导航小助手🎪1.23 ==和equals()有什么区别?1.26 说一说String和StringBuffer有什么区别1.27 说一说StringBuffer和StringBuilder有什么区别1.24 String类有哪些方法?概念 1、进程线程与进程的区别:协程与线程的区别:1.29 说一说你对字符串拼接的理解
1.23 ==和equals()有什么区别?
参考答案
==运算符:
-
作用于基本数据类型时,是比较两个数值是否相等;
-
作用于引用数据类型时,是比较两个对象的内存地址是否相同,即判断它们是否为同一个对象;
equals()方法:
-
没有重写时,Object默认以 == 来实现,即比较两个对象的内存地址是否相同;
-
进行重写后,一般会按照对象的内容来进行比较,若两个对象内容相同则认为对象相等,否则认为对象不等。
1.26 说一说String和StringBuffer有什么区别
参考答案
String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。
StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。
1.27 说一说StringBuffer和StringBuilder有什么区别
参考答案
StringBuffer、StringBuilder都代表可变的字符串对象,它们有共同的父类 AbstractStringBuilder,并且两个类的构造方法和成员方法也基本相同。不同的是,StringBuffer是线程安全的,而StringBuilder是非线程安全的,所以StringBuilder性能略高。一般情况下,要创建一个内容可变的字符串,建议优先考虑StringBuilder类。
1.24 String类有哪些方法?
参考答案
String类是Java最常用的API,它包含了大量处理字符串的方法,比较常用的有:
-
char charAt(int index):返回指定索引处的字符;
-
String substring(int beginIndex, int endIndex):从此字符串中截取出一部分子字符串;
-
String[] split(String regex):以指定的规则将此字符串分割成数组;
-
String trim():删除字符串前导和后置的空格;
-
int indexOf(String str):返回子串在此字符串首次出现的索引;
-
int lastIndexOf(String str):返回子串在此字符串最后出现的索引;
-
boolean startsWith(String prefix):判断此字符串是否以指定的前缀开头;
-
boolean endsWith(String suffix):判断此字符串是否以指定的后缀结尾;
-
String toUpperCase():将此字符串中所有的字符大写;
-
String toLowerCase():将此字符串中所有的字符小写;
-
String replaceFirst(String regex, String replacement):用指定字符串替换第一个匹配的子串;
-
String replaceAll(String regex, String replacement):用指定字符串替换所有的匹配的子串。
注意事项
String类的方法太多了,你没必要都记下来,更不需要一一列举。面试时能说出一些常用的方法,表现出对这个类足够的熟悉就可以了。另外,建议你挑几个方法仔细看看源码实现,面试时可以重点说这几个方法。
概念
1、进程
进程是具有一定独立功能的程序关于某个合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来通信。由于进程比较重量,占据独立的内存,所以上下文进程间的切换开销(栈、寄存器、虚拟内存、文件句柄等)比较大,但相对比较稳定安全。
2、线程
线程是指进程内的一个执行单元,也是进程内的可调度实体。线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。线程间通信主要通过共享内存,上下文切换很快,资源开销较少,但相比进程不够稳定容易丢失数据。
3、
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。从技术的角度来说,“协程就是你可以暂停执行的函数”。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
线程与进程的区别:
\1) 地址空间:线程是进程内的一个执行单元,进程内至少有一个线程,它们共享进程的地址空间,而进程有自己独立的地址空间 \2) 资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源 \3) 线程是处理器调度的基本单位,但进程不是 \4) 二者均可并发执行
\5) 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制
协程与线程的区别:
\1) 一个线程可以多个协程,一个进程也可以单独拥有多个协程。
\2) 线程进程都是同步机制,而协程则是异步。
\3) 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。
4)线程是抢占式,而协程是非抢占式的,所以需要用户自己释放使用权来切换到其他协程,因此同一时间其实只有一个协程拥有运行权,相当于单线程的能力。
5)协程并不是取代线程, 而且抽象于线程之上, 线程是被分割的CPU资源, 协程是组织好的代码流程, 协程需要线程来承载运行, 线程是协程的资源, 但协程不会直接使用线程, 协程直接利用的是执行器(Interceptor), 执行器可以关联任意线程或线程池, 可以使当前线程, UI线程, 或新建新程.。
6)线程是协程的资源。协程通过Interceptor来间接使用线程这个资源。
1.29 说一说你对字符串拼接的理解
参考答案
拼接字符串有很多种方式,其中最常用的有4种,下面列举了这4种方式各自适合的场景。
-
+ 运算符:如果拼接的都是字符串直接量,则适合使用 + 运算符实现拼接;
-
StringBuilder:如果拼接的字符串中包含变量,并不要求线程安全,则适合使用StringBuilder;
-
StringBuffer:如果拼接的字符串中包含变量,并且要求线程安全,则适合使用StringBuffer;
-
String类的concat方法:如果只是对两个字符串进行拼接,并且包含变量,则适合使用concat方法;
扩展阅读
采用 + 运算符拼接字符串时:
-
如果拼接的都是字符串直接量,则在编译时编译器会将其直接优化为一个完整的字符串,和你直接写一个完整的字符串是一样的,所以效率非常的高。
-
如果拼接的字符串中包含变量,则在编译时编译器采用StringBuilder对其进行优化,即自动创建StringBuilder实例并调用其append()方法,将这些字符串拼接在一起,效率也很高。但如果这个拼接操作是在循环中进行的,那么每次循环编译器都会创建一个StringBuilder实例,再去拼接字符串,相当于执行了 new StringBuilder().append(str),所以此时效率很低。
采用StringBuilder/StringBuffer拼接字符串时:
-
StringBuilder/StringBuffer都有字符串缓冲区,缓冲区的容量在创建对象时确定,并且默认为16。当拼接的字符串超过缓冲区的容量时,会触发缓冲区的扩容机制,即缓冲区加倍。
-
缓冲区频繁的扩容会降低拼接的性能,所以如果能提前预估最终字符串的长度,则建议在创建可变字符串对象时,放弃使用默认的容量,可以指定缓冲区的容量为预估的字符串的长度。
采用String类的concat方法拼接字符串时:
-
concat方法的拼接逻辑是,先创建一个足以容纳待拼接的两个字符串的字节数组,然后先后将两个字符串拼到这个数组里,最后将此数组转换为字符串。
-
在拼接大量字符串的时候,concat方法的效率低于StringBuilder。但是只拼接2个字符串时,concat方法的效率要优于StringBuilder。并且这种拼接方式代码简洁,所以只拼2个字符串时建议优先选择concat方法。
面向对象的三大特性:封装、继承和多态。 说到面向对象的话,一定要说到它的三大特性。
面向对象的第一大特性:封装 什么是封装呢?
通过访问修饰符(如 private)来修饰成员变量和成员方法,将不需要对外提供的内容都隐藏起来,提供公共方法对其访问。
封装的好处是:
隐藏实现细节,提供公共的访问方式
提高了代码的复用性
提高安全性
封装的意义在于,将内部的实现细节隐藏起来,对外部的调用者来说是透明的,调用者也不用关心它内部是怎么实现的,只需要知道这个方法是干什么的就好。
面向对象的第二大特性:继承 什么是继承呢?
在 Java 中子类使用关键词 extend 去继承父类的关系。
继承主要用途是将子类存在共性的东西,把它抽取出来放到父类里面,比如将共同拥有的属性和方法抽取出来放到父类里面。
继承的好处:
想要使用这些属性和方法的时候,可以直接去使用父类的,而不需要自己再重新去定义,更大程度的实现代码复用。
我们不需要写很多的冗余的代码,把共性的全部抽到父类,可以直接调用,如果需要个性化自定义子类的方法时,去重写父类的方法即可。
面向对象的第三大特性:多态 什么是多态呢?
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作
多态的理解稍微有点抽象,解释一下:
多态是和继承一脉相承的,多态存在的需要有三个必要条件:继承、重写、父类引用指向子类对象。
用个案例再补充解释一下:
比如说打印机,它属于一个父类,有一台彩色打印机,属于子类,有一台黑白打印机,也属于子类。
打印机的关系
用这个案例来解释一下多态,以及多态存在的三个必要条件:
继承,彩色打印机和黑白打印机都继承自打印机这个父类;
重写,打印机有一个打印的方法,彩色打印机和黑白打印机会重写父类的打印的方法,效果就是,彩色打印机打印出来的效果是彩色,而黑白打印机打印出来的效果是黑白的。
父类引用指向子类对象,例如:Parent p = new Child() ;对应到打印机的案例,new 一个对象的时候,父类打印机的引用会指向具体的对象,彩色打印机或者黑白打印机。
多态的好处:
便于接口的维护和拓展,可以将某一个子类切换成其他的子类,代码不需要做任何的改变,具有可替换性。
多态的弊端:
- 点赞
- 收藏
- 关注作者
评论(0)