stringbuilder寻找字符串位置可能存在多个 java_【面试题系列】——Java基础
本文主要包括Java基礎(chǔ)及面向?qū)ο笙嚓P(guān)面試題。
1,Java科普1.1 為什么安裝包要分JDK和JRE?1.2 為什么Java語(yǔ)言是跨平臺(tái)的?1.3 為什么安裝完JDK后要設(shè)置環(huán)境變量?1.4 Java和C++區(qū)別2,數(shù)據(jù)類(lèi)型&變量2.1 boolean占幾個(gè)字節(jié)?2.2 為什么long可以自動(dòng)轉(zhuǎn)換為float?2.3 包裝類(lèi)型和基本數(shù)據(jù)類(lèi)型的區(qū)別2.4 String,StringBuffer,StringBuilder的區(qū)別2.5 String s = "Hello";s = s + "world!";這兩行代碼執(zhí)行后,原始的String對(duì)象中的內(nèi)容到底變了沒(méi)有?2.6 String str =“i”;和 String str = new String("i");有區(qū)別嗎?2.7 如何將字符串反轉(zhuǎn)?2.8 Java有幾種變量?2.9 引用數(shù)據(jù)類(lèi)型包含哪幾種?3,運(yùn)算符3.1 ==和equals的區(qū)別3.2 &和&&區(qū)別(|和||同理)4,面向?qū)ο?.1 什么是面向?qū)ο?#xff1f;4.2 封裝相關(guān)4.3 繼承相關(guān)4.4 多態(tài)相關(guān)4.5 關(guān)鍵詞static4.6 關(guān)鍵詞final4.7 接口和抽象類(lèi)的區(qū)別?4.8 為什么重寫(xiě)equals必須重寫(xiě)hashCode?
1,Java科普
1.1 為什么安裝包要分JDK和JRE?
JRE主要包含JVM,用于運(yùn)行Java程序。 JDK包含了JRE,除此之外,包含了比如像javac等程序開(kāi)發(fā)需要用到的工具。先來(lái)說(shuō)說(shuō)什么是JDK,JRE。
JDK:Java Development Kit Java開(kāi)發(fā)工具包【開(kāi)發(fā)Java程序用】
JRE:Java Runtiome Environment Java運(yùn)行環(huán)境【運(yùn)行Java程序用】
【注:下載的JDK包是包含了JDK和JRE的,JDK和JRE是邏輯上的區(qū)分,兩者在JDK下載的包中都有】
JDK與JRE的關(guān)系:以Java代碼運(yùn)行為例,編寫(xiě)好Java代碼之后,通過(guò)javac將java源文件編譯成class字節(jié)碼文件,然后通過(guò)java命令,運(yùn)行字節(jié)碼文件。那么運(yùn)行字節(jié)碼的環(huán)境就是JRE。(JRE的核心就是JVM)
了解完JDK和JRE是什么之后,再聊聊為什么開(kāi)發(fā)者當(dāng)時(shí)要把一個(gè)安裝包分成兩部分呢?
平常使用的軟件都是一鍵安裝的,但JDK需要安裝兩次。JDK的發(fā)明者不會(huì)這么無(wú)聊,故意給開(kāi)發(fā)者增加麻煩。
【我想】:這應(yīng)該跟生產(chǎn)環(huán)境的部署問(wèn)題有關(guān),關(guān)于生產(chǎn)環(huán)境部署JDK還是JRE一直飽受爭(zhēng)議,具體情況根據(jù)項(xiàng)目而定。
出于對(duì)性能的考慮,盡可能的使服務(wù)器輕,能少裝一個(gè)軟件就少裝一個(gè),這樣生產(chǎn)環(huán)境部署JRE就OK了。【又省了資源】
除了這個(gè)方面之外,還有一種可能。JDK的開(kāi)發(fā)也有可能是分團(tuán)隊(duì)的,JDK和JRE可能是交由不同團(tuán)隊(duì)開(kāi)發(fā),JDK和JRE的耦合也可能因此而減小,從而加快JDK的迭代版本。(畢竟現(xiàn)在JDK一年更新兩次)
1.2 為什么Java語(yǔ)言是跨平臺(tái)的?
JVM有兩個(gè)功能 - 將class字節(jié)碼轉(zhuǎn)換為機(jī)器碼 - 兼容不同的操作系統(tǒng)跨平臺(tái)和Java 虛擬機(jī)有關(guān)。
JVM有兩個(gè)主要的功能:
- 適配不同的操作系統(tǒng)的指令集(兼容不同的操作系統(tǒng))
- 翻譯字節(jié)碼文件為機(jī)器碼執(zhí)行
(Oracle官網(wǎng)上下載JDK,不同操作系統(tǒng)的JDK是不一樣的,對(duì)應(yīng)不同的虛擬機(jī))
1.3 為什么安裝完JDK后要設(shè)置環(huán)境變量?
在解決這個(gè)問(wèn)題之前,先來(lái)了解一些環(huán)境變量是干嘛的:
環(huán)境變量是在操作系統(tǒng)中一個(gè)具有特定名字的對(duì)象,它包含了一個(gè)或者多個(gè)應(yīng)用程序所將使用到的信息。例如Windows和DOS操作系統(tǒng)中的path環(huán)境變量,當(dāng)要求系統(tǒng)運(yùn)行一個(gè)程序而沒(méi)有告訴它程序所在的完整路徑時(shí),系統(tǒng)除了在當(dāng)前目錄下面尋找此程序外,還應(yīng)到path中指定的路徑去找。用戶(hù)通過(guò)設(shè)置環(huán)境變量,來(lái)更好的運(yùn)行進(jìn)程。簡(jiǎn)單來(lái)說(shuō),運(yùn)行一個(gè)程序(命令),操作系統(tǒng)會(huì)從當(dāng)前目錄尋找,或者從環(huán)境變量中尋找。
換句話說(shuō),如果在java,javac的目錄下執(zhí)行這個(gè)兩個(gè)命令,是沒(méi)有問(wèn)題的。但是如果更換了目錄,系統(tǒng)在當(dāng)前目錄找不到,就會(huì)去環(huán)境變量中尋找。所以設(shè)置環(huán)境變量的根本目的是在電腦的任何一個(gè)文件夾下都可以編譯運(yùn)行Java程序。
1.4 Java和C++區(qū)別
題外話,Java和C++有什么區(qū)別?(據(jù)說(shuō)有些面試官老愛(ài)干這種事)- C++支持多繼承,Java支持單繼承
- Java有垃圾回收機(jī)制
- Java不支持指針,更加安全
2,數(shù)據(jù)類(lèi)型&變量
2.1 boolean占幾個(gè)字節(jié)?
表示變量:4個(gè)字節(jié)(轉(zhuǎn)換為int存儲(chǔ)) 表示byte數(shù)組:1個(gè)字節(jié)2.2 為什么long可以自動(dòng)轉(zhuǎn)換為float?
float,double采用指數(shù)方式存儲(chǔ),能表示的數(shù)比long更大 System.out.println(Long.MAX_VALUE); System.out.println(Float.MAX_VALUE); System.out.println(Double.MAX_VALUE);System.out.println(Float.MAX_VALUE>Long.MAX_VALUE); ? ? 9223372036854775807 3.4028235E38 1.7976931348623157E308 truefloat和double使用指數(shù)表示,取值范圍在
-3.4*10^38 - 3.4*10^38順便看看float和double的精度:7位和16位。
2.3 包裝類(lèi)型和基本數(shù)據(jù)類(lèi)型的區(qū)別
初始值:包裝類(lèi)型的初始值為null,基本數(shù)據(jù)類(lèi)型的初始值基本上是0,char是'u000' 存儲(chǔ)方式:包裝類(lèi)型存在堆里,基本數(shù)據(jù)類(lèi)型存在棧中2.4 String,StringBuffer,StringBuilder的區(qū)別
- 可變性 String底層使用fina修飾的數(shù)組實(shí)現(xiàn),是不可變的,StringBuffer和StringBuilder是可變的 - 安全性 String不可變,自然線程安全,StringBuffer使用synchronized同步鎖實(shí)現(xiàn)線程安全,StringBuilder是線程不安全的- 可變性
String是不可變的,StringBuffer和StringBuilder是可變的
String string1 = "111";
string1 = "222";
System.out.println(string1);
string1指向222時(shí),創(chuàng)建了一個(gè)新的對(duì)象并指向它
String 底層使用final修飾的數(shù)組實(shí)現(xiàn),故是不變的
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[]; - 安全性
StringBuffer和String是線程安全的,,StringBuilder是線程不安全的。
String 中的對(duì)象是不可變的,也就可以理解為常量,線程安全。
StringBuffer 對(duì)方法加了synchronized同步鎖所以是線程安全的。 - 對(duì)于三者使用的總結(jié)
2.5 String s = "Hello";s = s + "world!";這兩行代碼執(zhí)行后,原始的String對(duì)象中的內(nèi)容到底變了沒(méi)有?
沒(méi)有,只是指向了另外一個(gè)對(duì)象。
因?yàn)镾tring被設(shè)計(jì)成不可變(immutable)類(lèi)(final修飾),所以它的所有對(duì)象都是不可變對(duì)象。
在這段代碼中,s原先指向一個(gè)String對(duì)象,內(nèi)容是 "Hello",然后對(duì)s進(jìn)行了+操作
這時(shí),s不指向原來(lái)那個(gè)對(duì)象了,而指向了另一個(gè) String對(duì)象,內(nèi)容為"Hello world!"
原來(lái)那個(gè)對(duì)象還存在于內(nèi)存之中,只是s這個(gè)引用變量不再指向它了。
2.6 String str =“i”;和 String str = new String("i");有區(qū)別嗎?
前者會(huì)被JVM分配到常量池中,常量池中沒(méi)有重復(fù)的元素,如果再次創(chuàng)建一個(gè)字符串變量等于i的話,就會(huì)直接指向常量池中的i。
后者是new了一個(gè)對(duì)象,堆中是允許對(duì)象重復(fù)的。
前者會(huì)被JVM分配到常量池中,常量池中沒(méi)有重復(fù)的元素。
String str1 =“i”; String str2 =“i”;str2不會(huì)重新創(chuàng)建一個(gè)常量,而是指向str1。
String str1 = new String("i"); String str2 = new String("i");str1會(huì)在堆內(nèi)存中創(chuàng)建對(duì)象
str2還是會(huì)再次創(chuàng)建一個(gè)新的對(duì)象
2.7 如何將字符串反轉(zhuǎn)?
使用StringBuilder或者StringBuffer的reverse()方法。
StringBuffer str1 = new StringBuffer("12345");StringBuffer str2 = str1.reverse();System.out.println(str2);543212.8 Java有幾種變量?
- 類(lèi)變量
獨(dú)立于方法之外,必須用static修飾 - 實(shí)例變量
獨(dú)立于方法之外,不用static修飾 - 局部變量
方法中的變量
2.9 引用數(shù)據(jù)類(lèi)型包含哪幾種?
- 類(lèi)
- 接口
- 數(shù)組
3,運(yùn)算符
3.1 ==和equals的區(qū)別
equals用于比較內(nèi)容是否相同(源自O(shè)bject類(lèi),通常被重寫(xiě))
==對(duì)于基本數(shù)據(jù)類(lèi)型比較值相同,對(duì)于引用數(shù)據(jù)類(lèi)型比較內(nèi)存地址是否相同(是否是同一個(gè)對(duì)象)
知乎上非常形象的一張圖:
3.2 &和&&區(qū)別(|和||同理)
& : 兩邊都為true時(shí)才為true
|:兩邊有一個(gè)為false即為false
短路邏輯運(yùn)算符
&&:左邊為fasle直接返回flase(不計(jì)算右邊)
||:左邊為true直接返回true(不計(jì)算右邊)
就是為了簡(jiǎn)化計(jì)算量
^表示異或,相同為false,不同為true4,面向?qū)ο?/h2>4.1 什么是面向?qū)ο?#xff1f;
如果摒棄軟件開(kāi)發(fā)的范疇,這是一種通過(guò)明確社會(huì)分工而提高效率的方法。
在軟件開(kāi)發(fā)的范圍內(nèi),就是通過(guò)抽象出系統(tǒng)功能而實(shí)現(xiàn)最大化代碼復(fù)用的開(kāi)發(fā)模式。
4.2 封裝相關(guān)
- 什么是封裝
通過(guò)隱藏實(shí)現(xiàn),暴露接口,一來(lái)實(shí)現(xiàn)代碼解耦,二來(lái)通過(guò)訪問(wèn)修飾符保證數(shù)據(jù)安全。
4.3 繼承相關(guān)
- 繼承的作用?
實(shí)現(xiàn)代碼復(fù)用 - 繼承的規(guī)則?
- 子類(lèi)繼承父類(lèi)非private的屬性和方法
- 子類(lèi)可以擴(kuò)展自己的屬性和方法
- 構(gòu)造器是否會(huì)被繼承?
- 構(gòu)造器不會(huì)被繼承,但子類(lèi)對(duì)象初始化時(shí)會(huì)調(diào)用父類(lèi)無(wú)參構(gòu)造器
【為什么。子類(lèi)和父類(lèi)有最基本的依賴(lài)關(guān)系,比如說(shuō)數(shù)據(jù)依賴(lài)】 - 當(dāng)父類(lèi)顯式寫(xiě)了有參構(gòu)造器,且沒(méi)有無(wú)參構(gòu)造器。子類(lèi)繼承父類(lèi)的時(shí)候必須顯式的調(diào)用父類(lèi)的有參構(gòu)造器。調(diào)用的方式可以使用super(a,b)來(lái)調(diào)用。
- 構(gòu)造器不會(huì)被繼承,但子類(lèi)對(duì)象初始化時(shí)會(huì)調(diào)用父類(lèi)無(wú)參構(gòu)造器
- 子類(lèi)父類(lèi)的初始化順序
原則:靜態(tài)優(yōu)于非靜態(tài),父類(lèi)優(yōu)于子類(lèi)
?
- 父類(lèi)靜態(tài)變量,靜態(tài)語(yǔ)句塊
- 子類(lèi)靜態(tài)變量,靜態(tài)語(yǔ)句塊
?
- 父類(lèi)非靜態(tài)代碼塊,構(gòu)造器
- 子類(lèi)非靜態(tài)代碼塊,構(gòu)造器
4.4 多態(tài)相關(guān)
- 什么是多態(tài)?
一類(lèi)事物的多種表現(xiàn)形態(tài)。(比如手機(jī)有各種各樣的品牌,但都屬于手機(jī)這一類(lèi)事物) - 如何體現(xiàn)多態(tài)?
方法重載:針對(duì)本類(lèi)的不同方法而言,方法名相同,參數(shù)不同(個(gè)數(shù),順序)【返回類(lèi)型隨意】
方法重寫(xiě):針對(duì)繼承而言,除了方法體可以自定義外,其他必須與父類(lèi)保持一致(方法名,返回類(lèi)型,參數(shù)) - 向上轉(zhuǎn)型&向下轉(zhuǎn)型
up:子類(lèi)轉(zhuǎn)換為父類(lèi),目的是訪問(wèn)父類(lèi)的公共方法,實(shí)現(xiàn)代碼的復(fù)用和簡(jiǎn)潔(比如100個(gè)類(lèi)把公共方法寫(xiě)在父類(lèi)中,就不需要每個(gè)類(lèi)都寫(xiě)一遍了)
down:父類(lèi)轉(zhuǎn)換為子類(lèi),據(jù)說(shuō)是為了調(diào)用子類(lèi)的擴(kuò)展方法。(為啥不直接new一個(gè)對(duì)象,已提交知乎問(wèn)答)
4.5 關(guān)鍵詞static
- 修飾變量
稱(chēng)為靜態(tài)變量,類(lèi)變量,全局變量
可直接通過(guò)類(lèi)名.變量名訪問(wèn)
- 修飾方法
稱(chēng)為靜態(tài)方法,類(lèi)方法
可通過(guò)類(lèi)名.方法名直接訪問(wèn)- 非static方法可以訪問(wèn)static方法,static方法不能訪問(wèn)非static方法
4.6 關(guān)鍵詞final
- 修飾類(lèi)不能被繼承
- 修飾方法不能被重寫(xiě)
- 修飾變量則變量變?yōu)槌A?/li>
4.7 接口和抽象類(lèi)的區(qū)別?
- 繼承與實(shí)現(xiàn)
類(lèi)只能單繼承,但可以實(shí)現(xiàn)多接口 - 方法是否能實(shí)現(xiàn)
抽象類(lèi)不僅可以做方法聲明,也可以做方法實(shí)現(xiàn)。(接口只能做方法聲明) - 修飾符
接口的變量都默認(rèn)采用final修飾,方法采用public修飾。
抽象類(lèi)可自定義。
4.8 為什么重寫(xiě)equals必須重寫(xiě)hashCode?
equals和hashCode位于Object類(lèi)中,所有的類(lèi)都會(huì)繼承Object類(lèi)。
equals通常被用來(lái)比較對(duì)象的內(nèi)容是否相同,hashCode是用來(lái)返回對(duì)象Hash值的一種方法。
如果不重寫(xiě)hashCode會(huì)導(dǎo)致,equals相同但hashCode不相同,equals不相同但hashCode相同。
重寫(xiě)的目的一來(lái)為了避免hash沖突,二來(lái)提高對(duì)象訪問(wèn)速度。
總結(jié)
以上是生活随笔為你收集整理的stringbuilder寻找字符串位置可能存在多个 java_【面试题系列】——Java基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 百度统计 java 实现思路_2019社
- 下一篇: 无法分配更多的internet句柄怎么回