JavaSE面試題之基本IO流及面試官寫了個雙冒號考試答案[圖]
一、JavaSE面試題之基本IO流
今天這篇是JavaSE系列的第十四篇,主要總結了Java中的IO流的問題,IO流分為兩篇來講,這篇是第一篇,主要是基本IO流,第二篇主要為網路IO流,在後續,會沿著第一篇開篇的知識線路一直總結下去,做到日更!如果我能做到百日百更,希望你也可以跟著百日百刷,一百天養成一個好習慣。
Q:
什麼是IO流?
它是一種資料的流從源頭流到目的地。比如檔案拷貝,輸入流和輸出流都包括了。輸入流從檔案中讀取資料儲存到程式(process)中,輸出流從程式中讀取資料然後寫入到目標檔案。
Q:
Java中有幾種型別的流?
按照流的方向:
輸入流(inputStream)
輸出流(outputStream)。
按照實現功能分:
節點流(可以從或向一個特定的地方(節點)讀寫資料。如FileReader)
處理流(是對一個已存在的流的連線和封裝,通過所封裝的流的功能呼叫實現資料讀寫。如BufferedReader。處理流的構造方法總是要帶一個其他的流物件做引數。一個流物件經過其他流的多次包裝,稱為流的連結。)
按照處理資料的單位:
位元組流
字元流
位元組流繼承於InputStream和OutputStream
字元流繼承於InputStreamReader和OutputStreamWriter
字元流.png
位元組流.png
Q:
位元組流和字元流的區別?
位元組流在JDK1.0中就被引進了,用於操作包含ASCII字元的檔案。JAVA也支援其他的字元如Unicode,為了讀取包含Unicode字元的檔案,JAVA語言設計者在JDK1.1中引入了字元流。ASCII作為Unicode的子集,對於英語字元的檔案,可以可以使用位元組流也可以使用字元流。
Q:
位元組流有了為什麼還要有字元流?
字元流是由Java虛擬機器將位元組轉換得到的,問題就出在這個過程還算是非常耗時,並且,如果我們不知道編碼型別就很容易出現亂碼問題。所以,I/O流就乾脆提供了一個直接操作字元的介面,方便我們平時對字元進行流操作。如果音訊檔案、圖片等媒體檔案用位元組流比較好,如果涉及到字元的話使用字元流比較好。
Q:
FileInputStream和FileOutputStream是什麼?
這是在拷貝檔案操作的時候,經常用到的兩個類。在處理小檔案的時候,它們效能表現還不錯,在大檔案的時候,最好使用BufferedInputStream(或BufferedReader)和BufferedOutputStream(或BufferedWriter)
Q:
Files的常用方法都有哪些?
Files.size():檢視檔案個數。
Files.read():讀取檔案。
Files.write():寫入檔案。
Files.exists():檢測檔案路徑是否存在。
Files.createFile():建立檔案。
Files.createDirectory():建立資料夾。
Files.delete():刪除一個檔案或目錄。
Files.copy():複製檔案。
Files.move():移動檔案。
Q:
什麼是java序列化,如何實現java序列化?
序列化:
是一種用來處理物件流的機制,所謂物件流也就是將物件的內容進行流化。可以對流化後的物件進行讀寫操作,也可將流化後的物件傳輸於網路之間。序列化是為了解決在對物件流進行讀寫操作時所引發的問題。
序列化的實現:
將需要被序列化的類實現
Serializable
介面,該介面沒有需要實現的方法,implementsSerializable只是為了標註該物件是可被序列化的,然後使用一個輸出流(如:FileOutputStream)來構造一個ObjectOutputStream(物件流)物件,接著,作文(https://www.isanxia.com)使用ObjectOutputStream物件的writeObject(Objectobj)方法就可以將引數為obj的物件寫出(即儲存其狀態),要恢復的話則用輸入流。
Q:
如何將一個java物件序列化到檔案裡?
在java中能夠被序列化的類必須先實現
Serializable
介面,該介面沒有任何抽象方法只是起到一個標記作用。
Q:
如何實現物件克隆?
兩種方式:
實現Cloneable介面並重寫Object類中的clone()方法;
實現Serializable介面,通過物件的序列化和反序列化實現克隆,可以實現真正的深度克隆。
注意:基於序列化和反序列化實現的克隆不僅僅是深度克隆,更重要的是通過泛型限定,可以檢查出要克隆的物件是否支援序列化,這項檢查是編譯器完成的,不是在執行時丟擲異常,這種是方案明顯優於使用Object類的clone方法克隆物件。讓問題在編譯的時候暴露出來總是好過把問題留到執行時。
二、Java面試官寫了個雙冒號
一:簡潔
方法引用分為三種,方法引用通過一對雙冒號::來表示,方法引用是一種函式式介面的另一種書寫方式
靜態方法引用,通過類名::靜態方法名,如Integer::parseInt
例項方法引用,通過例項物件::例項方法,如str::substring
構造方法引用,通過類名::new,如User::new
二:方法引用
publicfinalclassInteger{
publicstaticintparseInt(Strings)throwsNumberFormatException{
returnparseInt(s,10);
}
}
通過方法引用,可以將方法的引用賦值給一個變數,通過賦值給Function,說明方法引用也是一種函式式介面的書寫方式,Lambda表示式也是一種函式式介面,Lambda表示式一般用於自己提供方法體,而方法引用一般直接引用現成的方法。
publicclassUser{
privateStringusername;
privateIntegerage;
publicUser(){
}
publicUser(Stringusername,Integerage){
this.username=username;
this.age=age;
}
@Override
publicStringtoString(){
return"User{"+
"username='"+username+'\''+
",age="+age+
'}';
}
//Getter&Setter
}
publicstaticvoidmain(String[]args){
//使用雙冒號::來構造靜態函式引用
Function<String,Integer>fun=Integer::parseInt;
Integervalue=fun.apply("123");
System.out.println(value);
//使用雙冒號::來構造非靜態函式引用
Stringcontent="HelloJDK8";
Function<Integer,String>func=content::substring;
Stringresult=func.apply(1);
System.out.println(result);
//建構函式引用
BiFunction<String,Integer,User>biFunction=User::new;
Useruser=biFunction.apply("mengday",28);
System.out.println(user.toString());
//函式引用也是一種函式式介面,所以也可以將函式引用作為方法的引數
sayHello(String::toUpperCase,"hello");
}
//方法有兩個引數,一個是
privatestaticvoidsayHello(Function<String,String>func,Stringparameter){
Stringresult=func.apply(parameter);
System.out.println(result);
}
三:Optional可選值
在GoogleGuava中就有Optional,在Swift語言中也有這樣類似的語法,在Swift中將可選值作為一種資料型別,地位和基本型別平齊平做,地位非常高。
packagejava.util;
importjava.util.function.Consumer;
importjava.util.function.Function;
importjava.util.function.Predicate;
importjava.util.function.Supplier;
/**
*@since1.8
*/
publicfinalclassOptional<T>{
privatestaticfinalOptional<?>EMPTY=newOptional<>();
privatefinalTvalue;
privateOptional(){
this.value=null;
}
//返回一個空的Optional例項
publicstatic<T>Optional<T>empty(){
@SuppressWarnings("unchecked")
Optional<T>t=(Optional<T>)EMPTY;
returnt;
}
privateOptional(Tvalue){
this.value=Objects.requireNonNull(value);
}
//返回具有Optional的當前非空值的Optional
publicstatic<T>Optional<T>of(Tvalue){
returnnewOptional<>(value);
}
//返回一個Optional指定值的Optional,如果非空,則返回一個空的Optional
publicstatic<T>Optional<T>ofNullable(Tvalue){
returnvalue==null?empty():of(value);
}
//如果Optional中有一個值,返回值,否則丟擲NoSuchElementException。
publicTget(){
if(value==null){
thrownewNoSuchElementException("Novaluepresent");
}
returnvalue;
}
//返回true如果存在值,否則為false
publicbooleanisPresent(){
returnvalue!=null;
}
//如果存在值,則使用該值呼叫指定的消費者,否則不執行任何操作。
publicvoidifPresent(Consumer<?superT>consumer){
if(value!=null)
consumer.accept(value);
}
//如果一個值存在,並且該值給定的謂詞相匹配時,返回一個Optional描述的值,否則返回一個空的Optional
publicOptional<T>filter(Predicate<?superT>predicate){
Objects.requireNonNull(predicate);
if(!isPresent())
returnthis;
else
returnpredicate.test(value)?this:empty();
}
//如果存在一個值,則應用提供的對映函式,如果結果不為空,則返回一個Optional結果的Optional。
public<U>Optional<U>map(Function<?superT,?extendsU>mapper){
Objects.requireNonNull(mapper);
if(!isPresent())
returnempty();
else{
returnOptional.ofNullable(mapper.apply(value));
}
}
//如果一個值存在,應用提供的Optional對映函式給它,返回該結果,否則返回一個空的Optional。
public<U>Optional<U>flatMap(Function<?superT,Optional<U>>mapper){
Objects.requireNonNull(mapper);
if(!isPresent())
returnempty();
else{
returnObjects.requireNonNull(mapper.apply(value));
}
}
//如果值存在,就返回值,不存在就返回指定的其他值
publicTorElse(Tother){
returnvalue!=null?value:other;
}
publicTorElseGet(Supplier<?extendsT>other){
returnvalue!=null?value:other.get();
}
public<XextendsThrowable>TorElseThrow(Supplier<?extendsX>exceptionSupplier)throwsX{
if(value!=null){
returnvalue;
}else{
throwexceptionSupplier.get();
}
}
}
關於of方法,現在好像很流行,就是提供一個static方法,方法名稱叫of,方法的返回值返回當前類,並且把建構函式設定為私有private,用靜態of方法來代替建構函式。
publicclassUser{
privateStringusername;
privateIntegerage;
privateUser(){
}
publicstaticUserof(){
returnnewUser();
}
privateUser(Stringusername,Integerage){
this.username=username;
this.age=age;
}
publicstaticUserof(Stringusername,Integerage){
returnnewUser(username,age);
}
}
Main
publicstaticvoidmain(String[]args){
//Optional類已經成為Java8類庫的一部分,在Guava中早就有了,可能Oracle是直接拿來使用了
//Optional用來解決空指標異常,使程式碼更加嚴謹,防止因為空指標NullPointerException對程式碼造成影響
Stringmsg="hello";
Optional<String>optional=Optional.of(msg);
//判斷是否有值,不為空
booleanpresent=optional.isPresent();
//如果有值,則返回值,如果等於空則拋異常
Stringvalue=optional.get();
//如果為空,返回else指定的值
Stringhi=optional.orElse("hi");
//如果值不為空,就執行Lambda表示式
optional.ifPresent(opt->System.out.println(opt));
}
相關文章
- 面試官寫了個雙冒號::問我是什麼語法,Java中有這玩意麼?面試Java
- 面試官寫了個雙冒號: : 問我這是什麼語法?Java中有這玩意?面試Java
- 100道JAVA面試題+JAVA面試題參考答案Java面試題
- SQL崗位30個面試題,SQL面試問題及答案SQL面試題
- Web前端經典面試試題及答案(參考連結)Web前端面試
- 2020年全網最全的自動化測試面試題及答案--吊打面試官就靠它了!面試題
- JavaSE面試題:反射Java面試題反射
- 【週刊-1】三年大廠面試官-面試題精選及答案面試題
- 面試過了,總結測試工程師面試題(含答案)工程師面試題
- Java併發程式設計40道面試題及答案——面試穩了Java程式設計面試題
- 24個Jvm面試題總結及答案JVM面試題
- Linux面試題,淺析常見Linux命令面試題及答案Linux面試題
- 30 道 Dubbo 面試題及答案面試題
- Java初中級面試題及答案Java面試題
- Java高階面試題及答案Java面試題
- 常見AI面試題及答案AI面試題
- Selenium 高頻面試題及答案面試題
- 碼農面試智力題及答案面試
- 40個Java集合面試問題和答案,面試奇葩問題,你掌握了嗎?Java面試
- 【Java面試】Java常見IO面試題!Java面試題
- 面試必備,Linux面試題和答案!Linux面試題
- 面試題-JAVA IO面試題Java
- 面試題:web程式設計技術考試題庫(含答案)面試題Web程式設計
- 詢問面試官的面試問題面試
- 【面試】社招中級前端筆試面試題總結-答案及擴充前端筆試面試題
- 一份多執行緒面試題及參考答案執行緒面試題
- 雲端計算面試題及答案,AWS雲端計算面試題面試題
- 2018年最新Java面試題及答案Java面試題
- 阿里Jvm必問面試題及答案阿里JVM面試題
- 這15道MySQL面試題,解決了90%的面試官MySql面試題
- 測試面試題集錦(六)| 軟素質篇與反問面試官篇(附答案)面試題
- 面試寶典:15道MyBatis 常見面試題彙總及答案MyBatis面試題
- 高階Java開發面試解答,Java開發面試題及答案Java面試題
- 12個iOS技術面試題及答案總結iOS面試題
- 雲端計算面試題及答案,常見的Shell指令碼面試題面試題指令碼
- 自己寫的面試題,自己想的答案面試題
- 楊老師課堂之JavaSe部分面試題Java面試題
- JavaSE-Java基礎面試題Java面試題