牛客網(題目的回答大多數來自他人見解,少部分個人領悟)
阿新 • • 發佈:2019-02-15
2017.11.4
1.一個檔案中的字元要寫到另一個檔案中,首先需要( )
使用標準輸出流System.out.println()。
建立檔案字元輸出流。
建立檔案字元輸入流。
標準輸入流System.in.read()。網友回答的:一個檔案中的字元要寫到另一個檔案中,首先要讀出來,然而對計算機而言,input就是讀進來(外面送進來),out就是寫出去(裡面往外面寫),一個檔案寫到另外一個檔案,所以我們需要先讀取這個檔案,也就是建立字元輸入流。
package com.te; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; public class InPutcopy { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub File file=new File("C:\\Users\\絕影\\Desktop\\桌面.txt");//建立一個新的file例項 //讀出對應輸入流 InputStream input = null; OutputStream out = null; InputStreamReader inp=null; OutputStreamWriter inp1=null; BufferedReader reader=null; BufferedWriter write=null; try { input = new FileInputStream(file); FileReader filer=new FileReader(file); inp=new InputStreamReader(input);//位元組流字元流轉化的橋樑 reader = new BufferedReader(filer);//緩衝讀取字元 將位元組流封裝成BufferedReader物件 File fi=new File("C:\\Users\\絕影\\Desktop\\7777.txt"); //寫入對應輸出流 out=new FileOutputStream(fi);//建立檔案位元組輸出流 FileWriter filer1=null; try { filer1 = new FileWriter(fi); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } inp1=new OutputStreamWriter(out);//位元組流字元流轉化的橋樑 write=new BufferedWriter(filer1);//緩衝寫入字元 將位元組流封裝成BufferedReader物件 char a[]=new char[21]; byte b[]=new byte[21]; input.read(b);//放入位元組陣列 //位元組陣列的read方法的原始碼,下面可知input.read(b)不會導致陣列越界,就是擔心檔案內容放不了進入陣列的情況,因為這個read方法本身 //陣列放入多少是已經固定的,並非將檔案內容一下子全部放入,所以不會有越界情況 /*public int read(byte b[]) throws IOException { return read(b, 0, b.length); } * */ reader.read(a);//放入字元陣列,同理不會因為檔案裡面的字元大於陣列長度越界 String line=""; while((line=reader.readLine()) != null){//一個檔案內容讀入到另外一個 //write.write(line); write.write(line); //使用緩衝區中的方法將資料寫入到緩衝區中。 //write.flush(); 如何finally中沒有關閉流這裡沒有這一句會造成檔案沒有寫入 System.out.println(line);//這裡也只是輸出後半句 } for(int i=0;i<21;i++) { System.out.println(b[i]);//48---57 System.out.println(a[i]);//這裡不懂,BufferedReader中的引數換inp前面的部分字元沒有輸出 } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { reader.close(); write.close();//這裡把輸出流關閉也會和write.flush()一樣的效果,有點類似資料庫的事務提交 } } }
2.以下多執行緒對int型變數x的操作,哪個不需要進行同步()
++x
x=y
x++
x=1
ABC不是原子性操作,例如想x++,先獲取x的值,自增一,然後再把值賦給x,三步,中間任何一步執行時都可能被其他執行緒訪問或者修改。所以需要同步。
package com.te; public class Multiplythread extends Thread{ static int i=0;//多執行緒呼叫 static int j=0; @Override public void run() { System.out.println(this); ++i; } public void runn() { ++j; } public static void main(String[] args) { // TODO Auto-generated method stub for(int i=0;i<1000;i++) { Multiplythread th=new Multiplythread();//執行緒1 th.start(); th.runn(); // System.out.println(i); } /* * 輸出結果不確定(因為對於++i這一步不是原子操作,實際上分為了三步, 每個java執行緒都有一份自己的工作記憶體,執行緒訪問變數的時候,不能直接訪問主記憶體中的變數,而是先把主記憶體的變數複製到自己的工作記憶體,然後操作自己工作記憶體裡的變數,最後再同步給主記憶體。 現在就可以解釋為什麼5個執行緒執行a++最後結果不一定是5了,因為a++可以分解為3步操作: 1.把主記憶體裡的a複製到執行緒的工作記憶體 2.執行緒對工作記憶體裡的a執行a=a+1 3.把執行緒工作記憶體裡的a同步回主記憶體,由於在這過程中執行緒是同步的,沒有先後執行順序),這裡需要上面執行緒多一點效果才明顯 */ //我們理想輸出的是1000,但是會出現不同結果.因為假設執行緒1先執行,當它執行完1,2時,到第二個執行緒開始跑,第二個執行緒成功執行完1,2,3然後執行緒1獲得cpu,繼續執行第三把自己工作記憶體裡的變數,再同步給主記憶體 //同步過去i的值是1,而執行緒2執行同步的值也是1,此時類變數i就是1,而不是我們想要的結果2 System.out.println("我是來看看終極i的值是:"+Multiplythread.i); //不受執行緒控制的變數j就是輸出1000 System.out.println("我是來看看終極j的值是:"+Multiplythread.j); } }
3.關於匿名內部類敘述正確的是? ( )
正確答案: B 你的答案: A (錯誤)
匿名內部類可以繼承一個基類,不可以實現一個介面
匿名內部類不可以定義構造器
匿名內部類不能用於形參
以上說法都不正確網友答案: 匿名內部類的建立格式為: new 父類構造器(引數列表)|實現介面(){ //匿名內部類的類體實現 }
- 使用匿名內部類時,必須繼承一個類或實現一個介面
- 匿名內部類由於沒有名字,因此不能定義建構函式
- 匿名內部類中不能含有靜態成員變數和靜態方法
A.建構函式可以省略,省略建構函式則new物件例項時,所有的資料型別賦值為0,bool型別賦值為FALSE,引用型別賦值為NULL。 B.建構函式必須與類同名,而且不能有返回型別。而方法是可以與類同名的,但是必須宣告返回資料型別。 C.正確,當new物件是首先呼叫靜態初始資料塊(可省略),然後呼叫父類建構函式(不是子類則不呼叫),最後呼叫自己的建構函式(一定呼叫),這樣才能生成一個物件的例項。 D.建構函式是可以過載的,過載的要求是引數不同。 4.下面不是面向物件的基本原則的是?
正確答案: C 你的答案: E (錯誤)
單一職責原則(Single-Resposibility Principle)
開放封閉原則(Open-Closed principle)
抽象類原則(Abstract-Class principle)
依賴倒置原則(Dependecy-Inversion Principle)
介面隔離原則(Interface-Segregation Principle)
s( Single-Resposibility Principle ): 單一職責原則 o( Open-Closed principle ): 開放封閉原則 l( Liskov-Substituion Principle ): 里氏原則 i( Interface-Segregation Principle ): 介面隔離原則 d( Dependecy-Inversion Principle ): 依賴倒置原則 一個單詞:立方體(solid),很好記!!!
單一職責原則(Single-Resposibility Principle):一個類,最好只做一件事,只有一個引起它的變化。單一職責原則可以看做是低耦合、高內聚在面向物件原則上的引申,將職責定義為引起變化的原因,以提高內聚性來減少引起變化的原因。
開放封閉原則(Open-Closed principle):軟體實體應該是可擴充套件的,而不可修改的。也就是,對擴充套件開放,對修改封閉的。
Liskov替換原則(Liskov-Substituion Principle):子類必須能夠替換其基類。這一思想體現為對繼承機制的約束規範,只有子類能夠替換基類時,才能保證系統在執行期內識別子類,這是保證繼承複用的基礎。
依賴倒置原則(Dependecy-Inversion Principle):依賴於抽象。具體而言就是高層模組不依賴於底層模組,二者都同依賴於抽象;抽象不依賴於具體,具體依賴於抽象。
介面隔離原則(Interface-Segregation Principle):使用多個小的專門的介面,而不要使用一個大的總介面
下列哪個說法是正確的()
正確答案: D 你的答案: B (錯誤)
ConcurrentHashMap使用synchronized關鍵字保證執行緒安全
HashMap實現了Collction介面
Array.asList方法返回java.util.ArrayList物件
SimpleDateFormat是執行緒不安全的
A選項中,ConcurrentHashMap 使用segment來分段和管理鎖,segment繼承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock來保證執行緒安全。
B中,HashMap定義規則如下:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, SerializableC中,應該是Arrays.asList(),其將一個數組轉化為一個List物件,這個方法會返回一個ArrayList型別的物件, 這個ArrayList類並非java.util.ArrayList類,而是Arrays類的內部類: A、ConcurrentHashMap實際上時 HashTable的升級版,使用segment來分段和管理鎖,並不是synchronized; B、 HashMap實現的介面有:Serializable, Cloneable, Map<K,V> ,沒有實現Cllectio C、Arrays.asList()方法返回的列表是Arrays.ArrayList型別的,並不是java.util.ArrayList;
JAVA反射機制主要提供了以下哪些功能?
正確答案: A B C D 你的答案: A B C (錯誤)
在執行時判斷一個物件所屬的類
在執行時構造一個類的物件
在執行時判斷一個類所具有的成員變數和方法
在執行時呼叫一個物件的方法普通的java物件是通過new關鍵字把對應類的位元組碼檔案載入到記憶體,然後建立該物件的。 反射是通過一個名為Class的特殊類,用Class.forName("className");得到類的位元組碼物件,然後用newInstance()方法在虛擬機器內部構造這個物件(針對無參建構函式)。 也就是說反射機制讓我們可以先拿到java類對應的位元組碼物件,然後動態的進行任何可能的操作, 包括
- 在執行時判斷任意一個物件所屬的類
- 在執行時構造任意一個類的物件
- 在執行時判斷任意一個類所具有的成員變數和方法
- 在執行時呼叫任意一個物件的方法
關於ThreadLocal類 以下說法正確的是
正確答案: D E 你的答案: A B C E (錯誤)
ThreadLocal繼承自Thread
ThreadLocal實現了Runnable介面
ThreadLocal重要作用在於多執行緒間的資料共享
ThreadLocal是採用雜湊表的方式來為每個執行緒都提供一個變數的副本
ThreadLocal保證各個執行緒間資料安全,每個執行緒的資料不會被另外執行緒訪問和破壞1、ThreadLocal的類宣告: public class ThreadLocal<T> 可以看出ThreadLocal並沒有繼承自Thread,也沒有實現Runnable介面。所以AB都不對。 2、ThreadLocal類為每一個執行緒都維護了自己獨有的變數拷貝。每個執行緒都擁有了自己獨立的一個變數。 所以ThreadLocal重要作用並不在於多執行緒間的資料共享,而是資料的獨立,C選項錯。 由於每個執行緒在訪問該變數時,讀取和修改的,都是自己獨有的那一份變數拷貝,不會被其他執行緒訪問, 變數被徹底封閉在每個訪問的執行緒中。所以E對。 3、ThreadLocal中定義了一個雜湊表用於為每個執行緒都提供一個變數的副本: static class ThreadLocalMap { static class Entry extends WeakReference<ThreadLocal> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal k, Object v) { super(k); value = v; } } /** * The table, resized as necessary. * table.length MUST always be a power of two. */ private Entry[] table; }