java面試題大合集(開發者必看)

weixin_33724059發表於2018-03-07

前言

本文來自百度網路的一篇文章,由於沒有答案,現在整理了一些比較好的回答和好的部落格,可以自己擴充套件思路,如果大家有一下面試題的更好的答案,歡迎在評論區留言。以上全部來自網路!

基本概念

1、作業系統中 heap 和 stack 的區別

堆:堆空間一般由程式設計師來分配,可以由垃圾回收機制來回收。一般用來存放new建立的物件和陣列。
棧:棧是“後進先出”的儲存空間,一般用來儲存基本型別的資料和物件的引用。

2、什麼是基於註解的切面實現

用註解的方式實現的面向切面程式設計(AOP),可以在某個方法的執行前或者執行後插入一些程式碼(例如日誌功能的程式碼)。

3、什麼是 物件/關係 對映整合模組

物件/關係對映(ORM):是指將程式中的物件自動持久化到關係型資料庫中

4、什麼是 Java 的反射機制

反射機制:是指程式可以在執行時 訪問 或 修改 它本身狀態和方法的這種能力。

5、什麼是 ACID

A:atom 原子性
C:consistency 一致性
I:isolation 隔離性
D:durability 永續性

6、BS與CS的聯絡與區別

C/S(Client/Server):是指需要安裝的客戶端應用程式。
B/S(Brower/Server):是指可以用瀏覽器直接訪問的應用程式。

7、Cookie 和 Session 的區別

Cookie:是把資料儲存在瀏覽器本地,並隨著每一次請求傳送到伺服器。
Session:是把使用者資料儲存在伺服器端。

8、fail-fast 與 fail-safe 機制有什麼區別

fail-fast(快速失敗):快速失敗機制在遍歷一個集合時,如果集合內容被修改,會丟擲ConcurrentModificationException異常。
fail-safe(安全失敗):安全失敗機制對集合的任何修改都會在一個複製的集合上進行,因此不會丟擲異常。

9、get 和 post請求的區別

get:
1、請求的引數會附加在URL之後,多個引數用 & 連線。
2、因為URL的長度限制,get 方式傳輸的資料大小有所限制。
3、安全性低,因為傳輸的資料會顯示在請求的URL中。
post:
1、將請求引數放置在 HTTP 資料包,傳送給伺服器。
2、傳送的資料量比較大
3、安全性較高

10、Interface 與 abstract 類的區別

1、介面(Interface)需要被實現,抽象類(abstract類)需要被繼承。
2、一個類可以實現多個介面,但一個類只能繼承一個抽象類。
3、介面裡面的方法全部是抽象的,抽象類裡面可以有非抽象的方法。

11、IoC的優點是什麼

IoC(控制反轉)的優點是:我們需要使用一個物件的時候無需自己建立,可以從IoC容器中直接獲取一個物件,然後直接使用。

12、IO 和 NIO 的區別,NIO的優點

1、IO是面向流的,NIO是面向緩衝區的。
2、IO是阻塞的,NIO是非阻塞的。
3、NIO有選擇器機制,可以讓一個執行緒來監視多個IO通道。
NIO的優點:
1、不需要使用 read() 或者 write() 就可以處理檔案內容。
2、NIO的處理效率很快。

13、Java 8 / Java 7 為我們提供了什麼新功能

Java7 新特性:

1、switch裡面的case條件可以使用字串了
2、運用 List<String> tempList = new ArrayList<>(); 即泛型例項化型別自動推斷
Java8 新特性:
1、Java8 允許我們給介面新增一個非抽象的方法實現,只需要使用 default 關鍵字即可
2、lambda 表示式

14、什麼是競態條件?舉個例子說明。

當兩個執行緒競爭同一資源時,如果對資源的訪問順序敏感,就稱存在競態條件。

15、JRE、JDK、JVM 及 JIT 之間有什麼不同

JVM(java 虛擬機器):JVM 處理位元組碼檔案,讓 java 語言實現跨平臺。
JRE(java執行時環境):JRE 是 JVM 的一個超集。
JDK(java開發工具箱):JDK 包含了 JRE 和 Java的開發環境。
JIT(即時編譯器):即時編譯器是種特殊的編譯器,它通過把位元組碼變成機器碼來提高JVM的效率。

16、MVC 的各個部分都用哪些技術來實現?如何實現?

Model層:可以用普通的 JavaBean 來實現。
View層:可以用 JSP 或者 JS 來實現。
Controller層:可以用 Struts2 或者 Spring MVC 來實現。

17、RPC 通訊 和 RMI 區別

RPC(remote procedure call),即遠端過程呼叫。
RMI(remote method invocation),即遠端方法呼叫。
兩者的實質都是呼叫遠端的服務,只不過RPC是用程式導向的語言如C語言實現,而RMI是用物件導向的語言如Java實現。

18、什麼是 Web Service(Web服務)

Web Service 就是通過網路呼叫其他網站的資源。

19、JSWDL 開發包的介紹。JAXP、JAXM的解釋。SOAP、UDDI、WSDL解釋。

JAXP:(Java API for XML Parsing) 定義了在Java中使用DOM, SAX, XSLT的通用的介面。這樣在你的程式中你只要使用這些通用的介面,當你需要改變具體的實現時候也不需要修改程式碼。
JAXM:(Java API for XML Messaging) 是為SOAP通訊提供訪問方法和傳輸機制的API。
SOAP:即簡單物件訪問協議(Simple Object Access Protocol),它是用於交換XML編碼資訊的輕量級協議。
UDDI:UDDI的目的是為電子商務建立標準;UDDI是一套基於Web的、分散式的、為Web Service提供的、資訊註冊中心的實現標準規範,同時也包含一組使企業能將自身提供的Web Service註冊,以使別的企業能夠發現的訪問協議的實現標準。
WSDL:是一種 XML 格式,用於將網路服務描述為一組端點,這些端點對包含面向文件資訊或程式導向資訊的訊息進行操作。這種格式首先對操作和訊息進行抽象描述,然後將其繫結到具體的網路協議和訊息格式上以定義端點。相關的具體端點即組合成為抽象端點(服務)。

20、WEB容器主要有哪些功能?並請列出一些常見的WEB容器名字。

WEB容器的功能:通訊支援、管理servlet的生命週期、多執行緒支援、jsp支援(將jsp翻譯成java)
常見的WEB容器:Tomcat、WebLogic、WebSphere

21、一個”.java”原始檔中是否可以包含多個類(不是內部類)?有什麼限制

可以,一個“.java”原始檔裡面可以包含多個類,但是隻允許有一個public類,並且類名必須和檔名一致。

22、簡單說說你瞭解的類載入器。是否實現過類載入器

類載入器負責載入Java類的位元組碼到Java虛擬機器中。
自己實現類載入器一般需要繼承 java.lang.ClassLoader ,覆寫 findClass(String name)方法。

23、解釋一下什麼叫AOP(面向切面程式設計)

AOP(Aspect Oriented Programming),即面向切面程式設計,它利用一種稱為"橫切"的技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,並將其命名為"Aspect",即切面。所謂"切面",簡單說就是將那些與業務無關,卻為業務模組所共同呼叫的邏輯封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。

24、請簡述 Servlet 的生命週期及其相關的方法

①例項化階段:伺服器對Servlet進行例項化,呼叫Servlet的構造方法
②初始化階段:伺服器呼叫Servlet的init方法進行初始化(只在第一次請求時呼叫)。
③請求處理階段:伺服器呼叫Servlet的service方法,然後根據請求方式呼叫相應的doXXX方法。
④服務終止階段:伺服器呼叫Servlet的destroy方法銷燬Servlet例項

25、請簡述一下 Ajax 的原理及實現步驟

Ajax 即“Asynchronous Javascript And XML”(非同步 JavaScript 和 XML),通過在後臺與伺服器進行少量資料交換,可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。
原理:HTTP協議的非同步通訊
實現步驟:
1、建立一個XMLHttpRequest物件
2、呼叫該物件的open方法
3、設定回撥函式

26、簡單描述 Struts 的主要功能

1、獲取表單內容,並組織生成引數物件
2、根據請求的引數轉發請求給適當的控制器
3、在控制器中呼叫業務介面
4、將業務介面返回的結果包裝起來傳送給指定的檢視,並由檢視完成處理結果的展現
5、做一些簡單的校驗或是國際化工作

27、什麼是 N 層架構

N層架構是一種軟體抽象的層次結構,是對複雜軟體的一種縱向切分,每一層次中完成同一型別的操作,以便將各種程式碼根據其完成的使命來進行分割,以降低軟體的複雜度,提高其可維護性。一般來說,層次之間是向下依賴的,下層程式碼未確定其介面前,上層程式碼是無法開發的,下層程式碼介面的變化將使上層的程式碼一起變化。

28、什麼是 CORBA?用途是什麼

CORBA(Common Object Request Broker Architecture 公共物件請求代理體系結構)是由OMG組織制訂的一種標準的物件導向應用程式體系規範。
用途:
1、存取來自現行桌面應用程式的分佈資訊和資源;
2、使現有業務資料和系統成為可供利用的網路資源;
3、為某一特定業務用的定製的功能和能力來增強現行桌面工具和應用程式;
4、改變和發展基於網路的系統以反映新的拓撲結構或新資源;

29、什麼是 Java虛擬機器?為什麼Java被稱作是“平臺無關的程式語言”

Java虛擬機器是執行位元組碼檔案(.class)的虛擬機器程式。
因為不同的平臺裝有不同的Java虛擬機器,它們能夠將相同的.class檔案,解釋成不同平臺所需要的機器碼。所以Java被稱為平臺無關的程式語言。

30、什麼是正規表示式?用途是什麼?哪個包使用正規表示式來實現模式匹配

正規表示式:是對字串操作的一種邏輯公式,就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字串”,用這個“規則字串”來表達對字串的過濾邏輯。
用途包括:
1、字串匹配
2、指定字串替換
3、指定字串查詢
4、字串分割
正規表示式的包:java.util.regex包

31、什麼是懶載入(Lazy Loading)

懶載入:即為延遲載入,顧名思義就是在需要的時候才載入,這樣做效率會比較低,但是佔用記憶體低。

32、什麼是尾遞迴,為什麼需要尾遞迴

如果一個函式中所有遞迴形式的呼叫都出現在函式的末尾,我們稱這個遞迴函式是尾遞迴的。
為什麼需要尾遞迴:尾遞迴和普通遞迴的不同點在對記憶體的佔用,普通遞迴建立stack後記憶體減少,而尾遞迴只會佔用恆量的記憶體。

33、什麼是控制反轉(Inversion of Control)與依賴注入(Dependency Injection)

控制反轉:是指將建立物件的功能交給Spring容器,在我們需要使用物件的時候不需要自己建立,可以直接從容器中獲取。
依賴注入:動態的向某個物件提供它所依賴的其他物件。

關鍵字finalize

1、什麼是finalize() 方法

Java 可以使用 finalize() 方法在垃圾收集器將物件從記憶體中清除出去之前做一些必要的清理工作。

2、finalize()方法什麼時候被呼叫

這個方法是由垃圾收集器在確定這個物件沒有被引用時對這個物件呼叫的。

3、解構函式(finalization) 的目的是什麼

解構函式的目的是:在清除物件前,完成一些清理工作,比如:釋放記憶體等。

4、final 和 finalize 的區別

final關鍵字可以用於類、方法、變數前,用來表示該類、方法、變數具有不可變的特性。

finalize方法用於回收資源,可以為任何一個類新增finalize方法。該方法將在垃圾回收器清除物件之前呼叫。

注意:

關於以下java基礎、io、集合、多執行緒、虛擬機器、設計模式等的文章和原始碼解析,可以到我的微信公眾號獲取,每日分享!

final

1、final關鍵字有哪些用法

2、final 與 static 關鍵字可以用於哪裡?它們的作用是什麼

3、final, finally, finalize的區別

4、final、finalize 和 finally 的不同之處?

5、能否在執行時向 static final 型別的賦值

6、使用final關鍵字修飾一個變數時,是引用不能變,還是引用的物件不能變

7、一個類被宣告為final型別,表示了什麼意思

8、throws, throw, try, catch, finally分別代表什麼意義

9、Java 有幾種修飾符?分別用來修飾什麼

volatile

1、volatile 修飾符有過什麼實踐

2、volatile 變數是什麼?volatile 變數和 atomic 變數有什麼不同

3、volatile 型別變數提供什麼保證?能使得一個非原子操作變成原子操作嗎

4、能建立 volatile 陣列嗎?

5、transient變數有什麼特點

6、super什麼時候使用

7、public static void 寫成 static public void會怎樣

8、說明一下public static void main(String args[])這段宣告裡每個關鍵字的作用

9、請說出作用域public, private, protected, 以及不寫時的區別

10、sizeof 是Java 的關鍵字嗎

static

1、static class 與 non static class的區別

2、static 關鍵字是什麼意思?Java中是否可以覆蓋(override)一個private或者是static的方法

3、靜態型別有什麼特點

4、main() 方法為什麼必須是靜態的?能不能宣告 main() 方法為非靜態

5、是否可以從一個靜態(static)方法內部發出對非靜態(non-static)方法的呼叫

6、靜態變數在什麼時候載入?編譯期還是執行期?靜態程式碼塊載入的時機呢

7、成員方法是否可以訪問靜態變數?為什麼靜態方法不能訪問成員變數

switch

1、switch 語句中的表示式可以是什麼型別資料

2、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上

3、while 迴圈和 do 迴圈有什麼不同

操作符

1、&操作符和&&操作符有什麼區別?

2、a = a + b 與 a += b 的區別?

3、邏輯操作符 (&,|,^)與條件操作符(&&,||)的區別

4、3*0.1 == 0.3 將會返回什麼?true 還是 false?

5、loat f=3.4; 是否正確?

6、short s1 = 1; s1 = s1 + 1;有什麼錯?

資料結構

基礎型別(Primitives)

1、基礎型別(Primitives)與封裝型別(Wrappers)的區別在哪裡

2、簡述九種基本資料型別的大小,以及他們的封裝類

3、int 和 Integer 哪個會佔用更多的記憶體? int 和 Integer 有什麼區別?parseInt()函式在什麼時候使用到

4、float和double的預設值是多少

5、如何去小數四捨五入保留小數點後兩位

6、char 型變數中能不能存貯一箇中文漢字,為什麼

型別轉換

1、怎樣將 bytes 轉換為 long 型別

2、怎麼將 byte 轉換為 String

3、如何將數值型字元轉換為數字

4、我們能將 int 強制轉換為 byte 型別的變數嗎?如果該值大於 byte 型別的範圍,將會出現什麼現象

5、能在不進行強制轉換的情況下將一個 double 值賦值給 long 型別的變數嗎

6、型別向下轉換是什麼

陣列

1、如何權衡是使用無序的陣列還是有序的陣列

2、怎麼判斷陣列是 null 還是為空

3、怎麼列印陣列? 怎樣列印陣列中的重複元素

4、Array 和 ArrayList有什麼區別?什麼時候應該使用Array而不是ArrayList

5、陣列和連結串列資料結構描述,各自的時間複雜度

6、陣列有沒有length()這個方法? String有沒有length()這個方法

佇列

1、佇列和棧是什麼,列出它們的區別

2、BlockingQueue是什麼

3、簡述 ConcurrentLinkedQueue LinkedBlockingQueue 的用處和不同之處。

4、ArrayList、Vector、LinkedList 的儲存效能和特性?

5、String 和 StringBuffer 的區別?

6、ByteBuffer 與 StringBuffer 有什麼區別?

HashMap

1、HashMap的工作原理是什麼

2、內部的資料結構是什麼

3、HashMap 的 table的容量如何確定?loadFactor 是什麼? 該容量如何變化?這種變化會帶來什麼問題?

4、HashMap 實現的資料結構是什麼?如何實現

5、HashMap 和 HashTable、ConcurrentHashMap 的區別

6、HashMap的遍歷方式及效率

7、HashMap、LinkedMap、TreeMap的區別

8、如何決定選用HashMap還是TreeMap

9、如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦

10、HashMap 是執行緒安全的嗎?併發下使用的 Map 是什麼,它們內部原理分別是什麼,比如儲存方式、 hashcode、擴容、 預設容量等

HashSet

1、HashSet和TreeSet有什麼區別

2、HashSet 內部是如何工作的

3、WeakHashMap 是怎麼工作的?

Set

1、Set 裡的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用 == 還是 equals()? 它們有何區別?

2、TreeMap:TreeMap 是採用什麼樹實現的?TreeMap、HashMap、LindedHashMap的區別。TreeMap和TreeSet在排序時如何比較元素?Collections工具類中的sort()方法如何比較元素?

3、TreeSet:一個已經構建好的 TreeSet,怎麼完成倒排序。

4、EnumSet 是什麼

Hash演算法

1、Hashcode 的作用

2、簡述一致性 Hash 演算法

3、有沒有可能 兩個不相等的物件有相同的 hashcode?當兩個物件 hashcode 相同怎麼辦?如何獲取值物件

4、為什麼在重寫 equals 方法的時候需要重寫 hashCode 方法?equals與 hashCode 的異同點在哪裡

5、a.hashCode() 有什麼用?與 a.equals(b) 有什麼關係

6、hashCode() 和 equals() 方法的重要性體現在什麼地方

7、Object:Object有哪些公用方法?Object類hashcode,equals 設計原則? sun為什麼這麼設計?Object類的概述

8、如何在父類中為子類自動完成所有的 hashcode 和 equals 實現?這麼做有何優劣。

9、可以在 hashcode() 中使用隨機數字嗎?

LinkedHashMap

1、LinkedHashMap 和 PriorityQueue 的區別是什麼
List

1、List, Set, Map三個介面,存取元素時各有什麼特點

2、List, Set, Map 是否繼承自 Collection 介面

3、遍歷一個 List 有哪些不同的方式

LinkedList

1、LinkedList 是單向連結串列還是雙向連結串列

2、LinkedList 與 ArrayList 有什麼區別

3、描述下 Java 中集合(Collections),介面(Interfaces),實現(Implementations)的概念。LinkedList 與 ArrayList 的區別是什麼?

4、插入資料時,ArrayList, LinkedList, Vector誰速度較快?

ArrayList

1、ArrayList 和 HashMap 的預設大小是多數

2、ArrayList 和 LinkedList 的區別,什麼時候用 ArrayList?

3、ArrayList 和 Set 的區別?

4、ArrayList, LinkedList, Vector的區別

5、ArrayList是如何實現的,ArrayList 和 LinkedList 的區別

6、ArrayList如何實現擴容

7、Array 和 ArrayList 有何區別?什麼時候更適合用Array

8、說出ArraList,Vector, LinkedList的儲存效能和特性

Map

1、Map, Set, List, Queue, Stack

2、Map 介面提供了哪些不同的集合檢視

3、為什麼 Map 介面不繼承 Collection 介面

Collections

1、介紹Java中的Collection FrameWork。集合類框架的基本介面有哪些

2、Collections類是什麼?Collection 和 Collections的區別?Collection、Map的實現

3、集合類框架的最佳實踐有哪些

4、為什麼 Collection 不從 Cloneable 和 Serializable 介面繼承

5、說出幾點 Java 中使用 Collections 的最佳實踐?

6、Collections 中 遺留類 (HashTable、Vector) 和 現有類的區別

7、什麼是 B+樹,B-樹,列出實際的使用場景

介面

1、Comparator 與 Comparable 介面是幹什麼的?列出它們的區別

物件拷貝(clone)

1、如何實現物件克隆

2、深拷貝和淺拷貝區別

3、深拷貝和淺拷貝如何實現啟用機制

4、寫clone()方法時,通常都有一行程式碼,是什麼

比較

1、在比較物件時,”==” 運算子和 equals 運算有何區別

2、如果要重寫一個物件的equals方法,還要考慮什麼

3、兩個物件值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對

構造器

1、構造器鏈是什麼

2、建立物件時構造器的呼叫順序

不可變物件

1、什麼是不可變象(immutable object)

2、為什麼 Java 中的 String 是不可變的(Immutable)

3、如何構建不可變的類結構?關鍵點在哪裡

4、能建立一個包含可變物件的不可變物件嗎

5、如何對一組物件進行排序

方法

1、構造器(constructor)是否可被重寫(override)

2、方法可以同時即是 static 又是 synchronized 的嗎

3、abstract 的 method是否可同時是 static,是否可同時是 native,是否可同時是synchronized

4、Java支援哪種引數傳遞型別

5、一個物件被當作引數傳遞到一個方法,是值傳遞還是引用傳遞

6、當一個物件被當作引數傳遞到一個方法後,此方法可改變這個物件的屬性,並可返回變化後的結果,那麼這裡到底是值傳遞還是引用傳遞

7、我們能否過載main()方法

8、如果main方法被宣告為private會怎樣
GC

概念

1、GC是什麼?為什麼要有GC

2、什麼時候會導致垃圾回收

3、GC是怎麼樣執行的

4、新老以及永久區是什麼

5、GC 有幾種方式?怎麼配置

6、什麼時候一個物件會被GC? 如何判斷一個物件是否存活

7、System.gc() Runtime.gc()會做什麼事情? 能保證 GC 執行嗎

8、垃圾回收器可以馬上回收記憶體嗎?有什麼辦法主動通知虛擬機器進行垃圾回收?

9、Minor GC 、Major GC、Young GC 與 Full GC分別在什麼時候發生

10、垃圾回收演算法的實現原理

11、如果物件的引用被置為null,垃圾收集器是否會立即釋放物件佔用的記憶體?

12、垃圾回收的最佳做法是什麼

GC收集器有哪些

1、垃圾回收器的基本原理是什麼?

2、序列(serial)收集器和吞吐量(throughput)收集器的區別是什麼

3、Serial 與 Parallel GC之間的不同之處

4、CMS 收集器 與 G1 收集器的特點與區別

5、CMS垃圾回收器的工作過程

6、JVM 中一次完整的 GC 流程是怎樣的? 物件如何晉升到老年代

7、吞吐量優先和響應優先的垃圾收集器選擇

GC策略

1、舉個實際的場景,選擇一個GC策略

2、JVM的永久代中會發生垃圾回收嗎

收集方法

1、標記清除、標記整理、複製演算法的原理與特點?分別用在什麼地方

2、如果讓你優化收集方法,有什麼思路

JVM引數

1、說說你知道的幾種主要的jvm 引數

2、-XX:+UseCompressedOops 有什麼作用

類載入器(ClassLoader)

1、Java 類載入器都有哪些

2、JVM如何載入位元組碼檔案

記憶體管理

1、JVM記憶體分哪幾個區,每個區的作用是什麼

2、一個物件從建立到銷燬都是怎麼在這些部分裡存活和轉移的

3、解釋記憶體中的棧(stack)、堆(heap)和方法區(method area)的用法

4、JVM中哪個引數是用來控制執行緒的棧堆疊小

5、簡述記憶體分配與回收策略

6、簡述重排序,記憶體屏障,happen-before,主記憶體,工作記憶體

7、Java中存在記憶體洩漏問題嗎?請舉例說明

8、簡述 Java 中軟引用(SoftReferenc)、弱引用(WeakReference)和虛引用

9、記憶體對映快取區是什麼

10、jstack,jstat,jmap,jconsole怎麼用

11、32 位 JVM 和 64 位 JVM 的最大堆記憶體分別是多數?32 位和 64 位的 JVM,int 型別變數的長度是多數?

12、怎樣通過 Java 程式來判斷 JVM 是 32 位 還是 64 位

13、JVM自身會維護快取嗎?是不是在堆中進行物件分配,作業系統的堆還是JVM自己管理堆

14、什麼情況下會發生棧記憶體溢位

15、雙親委派模型是什麼

多執行緒基本概念

1、什麼是執行緒

2、多執行緒的優點

3、多執行緒的幾種實現方式

4、用 Runnable 還是 Thread

5、什麼是執行緒安全

6、Vector, SimpleDateFormat 是執行緒安全類嗎

7、什麼 Java 原型不是執行緒安全的

8、哪些集合類是執行緒安全的

9、多執行緒中的忙迴圈是什麼

10、如何建立一個執行緒

11、編寫多執行緒程式有幾種實現方式

12、什麼是執行緒區域性變數

13、執行緒和程式有什麼區別?程式間如何通訊,執行緒間如何通訊

14、什麼是多執行緒環境下的偽共享(false sharing)

15、同步和非同步有何異同,在什麼情況下分別使用他們?舉例說明

Current

1、ConcurrentHashMap 和 Hashtable的區別

2、ArrayBlockingQueue, CountDownLatch的用法

3、ConcurrentHashMap的併發度是什麼

4、CyclicBarrier 和 CountDownLatch有什麼不同?各自的內部原理和用法是什麼

5、Semaphore的用法

Thread

1、啟動一個執行緒是呼叫 run() 還是 start() 方法?start() 和 run() 方法有什麼區別

2、呼叫start()方法時會執行run()方法,為什麼不能直接呼叫run()方法

3、sleep() 方法和物件的 wait() 方法都可以讓執行緒暫停執行,它們有什麼區別

4、yield方法有什麼作用?sleep() 方法和 yield() 方法有什麼區別

5、Java 中如何停止一個執行緒

6、stop() 和 suspend() 方法為何不推薦使用

7、如何在兩個執行緒間共享資料

8、如何強制啟動一個執行緒

9、如何讓正在執行的執行緒暫停一段時間

10、什麼是執行緒組,為什麼在Java中不推薦使用

11、你是如何呼叫 wait(方法的)?使用 if 塊還是迴圈?為什麼

生命週期

1、有哪些不同的執行緒生命週期

2、執行緒狀態,BLOCKED 和 WAITING 有什麼區別

3、畫一個執行緒的生命週期狀態圖

4、ThreadLocal 用途是什麼,原理是什麼,用的時候要注意什麼

ThreadPool

1、執行緒池是什麼?為什麼要使用它

2、如何建立一個Java執行緒池

3、ThreadPool用法與優勢

4、提交任務時,執行緒池佇列已滿時會發會生什麼

5、newCache 和 newFixed 有什麼區別?簡述原理。建構函式的各個引數的含義是什麼,比如 coreSize, maxsize 等

6、執行緒池的實現策略

7、執行緒池的關閉方式有幾種,各自的區別是什麼

8、執行緒池中submit() 和 execute()方法有什麼區別?

執行緒排程

1、Java中用到的執行緒排程演算法是什麼

2、什麼是多執行緒中的上下文切換

3、你對執行緒優先順序的理解是什麼

4、什麼是執行緒排程器 (Thread Scheduler) 和時間分片 (Time Slicing)

執行緒同步

1、請說出你所知的執行緒同步的方法

2、synchronized 的原理是什麼

3、synchronized 和 ReentrantLock 有什麼不同

4、什麼場景下可以使用 volatile 替換 synchronized

5、有T1,T2,T3三個執行緒,怎麼確保它們按順序執行?怎樣保證T2在T1執行完後執行,T3在T2執行完後執行

6、同步塊內的執行緒丟擲異常會發生什麼

7、當一個執行緒進入一個物件的 synchronized 方法A 之後,其它執行緒是否可進入此物件的 synchronized 方法B

8、使用 synchronized 修飾靜態方法和非靜態方法有什麼區別

9、如何從給定集合那裡建立一個 synchronized 的集合

1、Java Concurrency API 中 的 Lock 介面是什麼?對比同步它有什麼優勢

2、Lock 與 Synchronized 的區別?Lock 介面比 synchronized 塊的優勢是什麼

3、ReadWriteLock是什麼?

4、鎖機制有什麼用

5、什麼是樂觀鎖(Optimistic Locking)?如何實現樂觀鎖?如何避免ABA問題

6、解釋以下名詞:重排序,自旋鎖,偏向鎖,輕量級鎖,可重入鎖,公平鎖,非公平鎖,樂觀鎖,悲觀鎖

7、什麼時候應該使用可重入鎖

8、簡述鎖的等級方法鎖、物件鎖、類鎖

9、Java中活鎖和死鎖有什麼區別?

10、什麼是死鎖(Deadlock)?導致執行緒死鎖的原因?如何確保 N 個執行緒可以訪問 N 個資源同時又不導致死鎖

11、死鎖與活鎖的區別,死鎖與飢餓的區別

12、怎麼檢測一個執行緒是否擁有鎖

13、如何實現分散式鎖

14、有哪些無鎖資料結構,他們實現的原理是什麼

15、讀寫鎖可以用於什麼應用場景

16、Executors類是什麼? Executor和Executors的區別

17、什麼是Java執行緒轉儲(Thread Dump),如何得到它

18、如何在Java中獲取執行緒堆疊

19、說出 3 條在 Java 中使用執行緒的最佳實踐

20、線上程中你怎麼處理不可捕捉異常

21、實際專案中使用多執行緒舉例。你在多執行緒環境中遇到的常見的問題是什麼?你是怎麼解決它的

22、請說出與執行緒同步以及執行緒排程相關的方法

23、程式中有3個 socket,需要多少個執行緒來處理

24、假如有一個第三方介面,有很多個執行緒去呼叫獲取資料,現在規定每秒鐘最多有 10 個執行緒同時呼叫它,如何做到

25、如何在 Windows 和 Linux 上查詢哪個執行緒使用的 CPU 時間最長

26、如何確保 main() 方法所在的執行緒是 Java 程式最後結束的執行緒

27、非常多個執行緒(可能是不同機器),相互之間需要等待協調才能完成某種工作,問怎麼設計這種協調方案

28、你需要實現一個高效的快取,它允許多個使用者讀,但只允許一個使用者寫,以此來保持它的完整性,你會怎樣去實現它

異常

基本概念

1、Error 和 Exception有什麼區別

2、UnsupportedOperationException是什麼

3、NullPointerException 和 ArrayIndexOutOfBoundException 之間有什麼相同之處

4、什麼是受檢查的異常,什麼是執行時異常

5、執行時異常與一般異常有何異同

6、簡述一個你最常見到的runtime exception(執行時異常)

finally

1、finally關鍵詞在異常處理中如何使用

2、如果執行finally程式碼塊之前方法返回了結果,或者JVM退出了,finally塊中的程式碼還會執行嗎

3、try裡有return,finally還執行麼?那麼緊跟在這個try後的finally {}裡的code會不會被執行,什麼時候被執行,在return前還是後

4、在什麼情況下,finally語句不會執行

5、throw 和 throws 有什麼區別?

6、OOM你遇到過哪些情況?你是怎麼搞定的?

7、SOF你遇到過哪些情況?

8、既然我們可以用RuntimeException來處理錯誤,那麼你認為為什麼Java中還存在檢查型異常

9、當自己建立異常類的時候應該注意什麼

10、導致空指標異常的原因

11、異常處理 handle or declare 原則應該如何理解

12、怎麼利用 JUnit 來測試一個方法的異常

13、catch塊裡別不寫程式碼有什麼問題

14、你曾經自定義實現過異常嗎?怎麼寫的

15、什麼是 異常鏈

16、在try塊中可以丟擲異常嗎

JDBC

1、通過 JDBC 連線資料庫有哪幾種方式

2、闡述 JDBC 運算元據庫的基本步驟

3、JDBC 中如何進行事務處理

4、什麼是 JdbcTemplate

5、什麼是 DAO 模組

6、使用 JDBC 運算元據庫時,如何提升讀取資料的效能?如何提升更新資料的效能

7、列出 5 個應該遵循的 JDBC 最佳實踐

IO

File

1、File型別中定義了什麼方法來建立一級目錄

2、File型別中定義了什麼方法來判斷一個檔案是否存在

1、為了提高讀寫效能,可以採用什麼流

2、Java中有幾種型別的流

3、JDK 為每種型別的流提供了一些抽象類以供繼承,分別是哪些類

4、對文字檔案操作用什麼I/O流

5、對各種基本資料型別和String型別的讀寫,採用什麼流

6、能指定字元編碼的 I/O 流型別是什麼

序列化

1、什麼是序列化?如何實現 Java 序列化及注意事項

2、Serializable 與 Externalizable 的區別

Socket

1、socket 選項 TCP NO DELAY 是指什麼

2、Socket 工作在 TCP/IP 協議棧是哪一層

3、TCP、UDP 區別及 Java 實現方式

4、說幾點 IO 的最佳實踐

5、直接緩衝區與非直接緩衝器有什麼區別?

6、怎麼讀寫 ByteBuffer?ByteBuffer 中的位元組序是什麼

7、當用System.in.read(buffer)從鍵盤輸入一行n個字元後,儲存在緩衝區buffer中的位元組數是多少

8、如何使用掃描器類(Scanner Class)令牌化

物件導向程式設計(OOP)

1、解釋下多型性(polymorphism),封裝性(encapsulation),內聚(cohesion)以及耦合(coupling)

2、多型的實現原理

3、封裝、繼承和多型是什麼

4、物件封裝的原則是什麼?

1、獲得一個類的類物件有哪些方式

2、過載(Overload)和重寫(Override)的區別。過載的方法能否根據返回型別進行區分?

3、說出幾條 Java 中方法過載的最佳實踐

抽象類

1、抽象類和介面的區別

2、抽象類中是否可以有靜態的main方法

3、抽象類是否可實現(implements)介面

4、抽象類是否可繼承具體類(concrete class)

匿名類(Anonymous Inner Class)

1、匿名內部類是否可以繼承其它類?是否可以實現介面

內部類

1、內部類分為幾種

2、內部類可以引用它的包含類(外部類)的成員嗎

3、請說一下 Java 中為什麼要引入內部類?還有匿名內部類

繼承

1、繼承(Inheritance)與聚合(Aggregation)的區別在哪裡

2、繼承和組合之間有什麼不同

3、為什麼類只能單繼承,介面可以多繼承

4、存在兩個類,B 繼承 A,C 繼承 B,能將 B 轉換為 C 麼?如 C = (C) B

5、如果類 a 繼承類 b,實現介面c,而類 b 和介面 c 中定義了同名變數,請問會出現什麼問題

介面

1、介面是什麼

2、介面是否可繼承介面

3、為什麼要使用介面而不是直接使用具體類?介面有什麼優點

泛型

1、泛型的存在是用來解決什麼問題

2、泛型的常用特點

3、List能否轉為List

工具類

日曆

1、Calendar Class的用途

2、如何在Java中獲取日曆類的例項

3、解釋一些日曆類中的重要方法

4、GregorianCalendar 類是什麼

5、SimpleTimeZone 類是什麼

6、Locale類是什麼

7、如何格式化日期物件

8、如何新增小時(hour)到一個日期物件(Date Objects)

9、如何將字串 YYYYMMDD 轉換為日期

Math

1、Math.round()什麼作用?Math.round(11.5) 等於多少?Math.round(-11.5)等於多少?

XML

1、XML文件定義有幾種形式?它們之間有何本質區別?解析XML文件有哪幾種方式?DOM 和 SAX 解析器有什麼不同?

2、Java解析XML的方式

3、用 jdom 解析 xml 檔案時如何解決中文問題?如何解析

4、你在專案中用到了 XML 技術的哪些方面?如何實現

動態代理

1、描述動態代理的幾種實現方式,分別說出相應的優缺點

設計模式

1、什麼是設計模式(Design Patterns)?你用過哪種設計模式?用在什麼場合

2、你知道哪些商業級設計模式?

3、哪些設計模式可以增加系統的可擴充套件性

單例模式

1、除了單例模式,你在生產環境中還用過什麼設計模式?

2、寫 Singleton 單例模式

3、單例模式的雙檢鎖是什麼

4、如何建立執行緒安全的 Singleton

5、什麼是類的單例模式

6、寫出三種單例模式實現

介面卡模式

1、介面卡模式是什麼?什麼時候使用

2、介面卡模式和代理模式之前有什麼不同

3、介面卡模式和裝飾器模式有什麼區別

4、什麼時候使用享元模式

5、什麼時候使用組合模式

6、什麼時候使用訪問者模式

7、什麼是模板方法模式

8、請給出1個符合開閉原則的設計模式的例子

注意:

關於以上java基礎、io、集合、多執行緒、虛擬機器、設計模式等的文章和原始碼解析,可以到我的微信公眾號獲取,每日分享!

開放問題(看你的了)

1、用一句話概括 Web 程式設計的特點

2、Google是如何在一秒內把搜尋結果返回給使用者

3、哪種依賴注入方式你建議使用,構造器注入,還是 Setter方法注入

4、樹(二叉或其他)形成許多普通資料結構的基礎。請描述一些這樣的資料結構以及何時可以使用它們

5、某一項功能如何設計

6、線上系統突然變得異常緩慢,你如何查詢問題

7、什麼樣的專案不適合用框架

8、新浪微博是如何實現把微博推給訂閱者

9、簡要介紹下從瀏覽器輸入 URL 開始到獲取到請求介面之後 Java Web 應用中發生了什麼

10、請你談談SSH整合

11、高併發下,如何做到安全的修改同一行資料

12、12306網站的訂票系統如何實現,如何保證不會票不被超賣

13、網站效能優化如何優化的

14、聊了下曾經參與設計的伺服器架構

15、請思考一個方案,實現分散式環境下的 countDownLatch

16、請思考一個方案,設計一個可以控制快取總體大小的自動適應的本地快取

17、在你的職業生涯中,算得上最困難的技術挑戰是什麼

18、如何寫一篇設計文件,目錄是什麼

19、大寫的O是什麼?舉幾個例子

20、程式設計中自己都怎麼考慮一些設計原則的,比如開閉原則,以及在工作中的應用

21、解釋一下網路應用的模式及其特點

22、設計一個線上文件系統,文件可以被編輯,如何防止多人同時對同一份文件進行編輯更新

23、說出資料連線池的工作機制是什麼

24、怎麼獲取一個檔案中單詞出現的最高頻率

25、描述一下你最常用的程式設計風格

26、如果有機會重新設計你們的產品,你會怎麼做

27、如何搭建一個高可用系統

28、如何啟動時不需輸入使用者名稱與密碼

29、如何在基於Java的Web專案中實現檔案上傳和下載

30、如何實現一個秒殺系統,保證只有幾位使用者能買到某件商品。

31、如何實現負載均衡,有哪些演算法可以實現

32、如何設計一個購物車?想想淘寶的購物車如何實現的

33、如何設計一套高併發支付方案,架構如何設計

34、如何設計建立和保持 100w 的長連線

35、如何避免瀏覽器快取。

36、如何防止快取雪崩

37、如果AB兩個系統互相依賴,如何解除依

38、如果有人惡意建立非法連線,怎麼解決

39、如果有幾十億的白名單,每天白天需要高併發查詢,晚上需要更新一次,如何設計這個功能

40、如果系統要使用超大整數(超過long長度範圍),請你設計一個資料結構來儲存這種超大型數字以及設計一種演算法來實現超大整數加法運算)

41、如果要設計一個圖形系統,請你設計基本的圖形元件(Point,Line,Rectangle,Triangle)的簡單實現

42、如果讓你實現一個併發安全的連結串列,你會怎麼做

43、應用伺服器與WEB 伺服器的區別?應用伺服器怎麼監控效能,各種方式的區別?你使用過的應用伺服器優化技術有哪些

44、大型網站在架構上應當考慮哪些問題

45、有沒有處理過線上問題?出現記憶體洩露,CPU利用率標高,應用無響應時如何處理的

46、最近看什麼書,印象最深刻的是什麼

47、描述下常用的重構技巧

48、你使用什麼版本管理工具?分支(Branch)與標籤(Tag)之間的區別在哪裡

49、你有了解過存在哪些反模式(Anti-Patterns)嗎

50、你用過的網站前端優化的技術有哪些

51、如何分析Thread dump

52、你如何理解AOP中的連線點(Joinpoint)、切點(Pointcut)、增強(Advice)、引介(Introduction)、織入(Weaving)、切面(Aspect)這些概念

53、你是如何處理記憶體洩露或者棧溢位問題的

54、你們線上應用的 JVM 引數有哪些

55、怎麼提升系統的QPS和吞吐量

知識面

1、解釋什麼是 MESI 協議(快取一致性)

參考:http://blog.csdn.net/zxp_cpinfo/article/details/53523697

2、談談 reactor 模型

參考:https://www.jianshu.com/p/2461535c38f3

3、Java 9 帶來了怎樣的新功能

參考:http://blog.csdn.net/u013322876/article/details/76610029

4、Java 與 C++ 對比,C++ 或 Java 中的異常處理機制的簡單原理和應用

參考:http://blog.sina.com.cn/s/blog_c065adec0101eu98.html

5、簡單講講 Tomcat 結構,以及其類載入器流程

參考:http://blog.csdn.net/lai1365266/article/details/45271985

6、虛擬記憶體是什麼

參考:http://blog.csdn.net/guoweimelon/article/details/50849710

7、闡述下 SOLID 原則

參考:https://www.cnblogs.com/OceanEyes/p/overview-of-solid-principles.html

8、請簡要講一下你對測試驅動開發(TDD)的認識

參考:https://www.cnblogs.com/OlderBird/p/4322925.html

9、CDN實現原理

參考:https://www.cnblogs.com/losbyday/p/5843960.html

10、Maven 和 ANT 有什麼區別

參考:http://blog.csdn.net/yangkai_hudong/article/details/12554983

11、UML中有哪些常用的圖

參考:http://blog.csdn.net/suxinpingtao51/article/details/8011335

Linux

1、Linux 下 IO 模型有幾種,各自的含義是什麼。

參考:http://www.jb51.net/article/94783.htm

2、Linux 系統下你關注過哪些核心引數,說說你知道的

參考:http://www.jb51.net/LINUXjishu/335549.html

3、Linux 下用一行命令檢視檔案的最後五行

cat filename | tail -n +3000 | head -n 1000

4、平時用到哪些 Linux 命令

參考:https://www.cnblogs.com/bugutian/p/4528650.html

5、用一行命令輸出正在執行的 Java 程式

參考:https://www.cnblogs.com/bugutian/p/4528650.html

6、使用什麼命令來確定是否有 Tomcat 例項執行在機器上

7、什麼是 N+1 難題

參考:https://www.cnblogs.com/yzlpersonal/p/5077392.html

8、什麼是 paxos 演算法

參考:http://blog.csdn.net/21aspnet/article/details/50700123

9、什麼是 restful,講講你理解的 restful

參考:http://www.ruanyifeng.com/blog/2011/09/restful.html

10、什麼是 zab 協議

參考:https://www.cnblogs.com/jian-xiao/p/5821675.html

11、什麼是領域模型(domain model)?貧血模型(anaemic domain model) 和充血模型(rich domain model)有什麼區別

參考:https://www.cnblogs.com/feng9exe/p/5611992.html

12、什麼是領域驅動開發(Domain Driven Development)

參考:http://blog.csdn.net/johnstrive/article/details/16805121

13、介紹一下了解的 Java 領域的 Web Service 框架

參考:http://blog.csdn.net/apicescn/article/details/42965785/

14、Web Server、Web Container 與 Application Server 的區別是什麼

參考:https://www.cnblogs.com/vipyoumay/p/5853694.html

15、微服務(MicroServices)與巨石型應用(Monolithic Applications)之間的區別在哪裡

16、描述 Cookie 和 Session 的作用,區別和各自的應用範圍,Session工作原理

參考:http://blog.csdn.net/yanghaitao_1990/article/details/51723066

17、你常用的持續整合(Continuous Integration)、靜態程式碼分析(Static Code Analysis)工具有哪些

18、簡述下資料庫正則化(Normalizations)

19、KISS,DRY,YAGNI 等原則是什麼含義

參考:http://blog.csdn.net/zj_show/article/details/8078447

20、分散式事務的原理,優缺點,如何使用分散式事務?

參考:http://blog.csdn.net/a291382932/article/details/52567094

21、布式叢集下如何做到唯一序列號

參考:https://www.cnblogs.com/yelongsan/p/6306418.html

網路

1、HTTPS 的加密方式是什麼,講講整個加密解密流程

參考:http://blog.csdn.net/shw372029857/article/details/52687906

2、HTTPS和HTTP的區別

參考:https://www.cnblogs.com/wqhwe/p/5407468.html

3、HTTP連線池實現原理

參考:https://www.cnblogs.com/likaitai/p/5431246.html

4、HTTP叢集方案

參考:http://aokunsang.iteye.com/blog/2053719

5、Nginx、lighttpd、Apache三大主流 Web伺服器的區別

參考:http://blog.csdn.net/u013404872/article/details/70799420

6、是否看過框架的一些程式碼

7、持久層設計要考慮的問題有哪些?你用過的持久層框架有哪些

所謂"持久"就是將資料儲存到可掉電式儲存裝置中以便今後使用,簡單的說,就是將記憶體中的資料儲存到關係型資料庫、檔案系統、訊息佇列等提供持久化支援的裝置中。持久層就是系統中專注於實現資料持久化的相對獨立的層面。

持久層設計的目標包括:

  • 資料儲存邏輯的分離,提供抽象化的資料訪問介面。
  • 資料訪問底層實現的分離,可以在不修改程式碼的情況下切換底層實現。
  • 資源管理和排程的分離,在資料訪問層實現統一的資源排程(如快取機制)。
  • 資料抽象,提供更物件導向的資料操作。

持久層框架有:

  • Hibernate
  • MyBatis
  • TopLink
  • Guzz
  • jOOQ
  • Spring Data
  • ActiveJDBC

8、數值提升是什麼

參考:http://blog.csdn.net/yangcheng33/article/details/76408580

9、你能解釋一下里氏替換原則嗎

參考:http://blog.csdn.net/xingyunlost/article/details/53169283

10、你是如何測試一個應用的?知道哪些測試框架

參考:https://www.cnblogs.com/fnng/p/3653793.html

11、傳輸層常見程式設計協議有哪些?並說出各自的特點

傳輸層位於OSI七層網路模型中的第四層,協議有TCP · UDP · TLS · DCCP · SCTP ·RSVP · PPTP。OSI(Open System Interconnection,開放系統互連)七層網路模型稱為開放式系統互聯參考模型 ,是一個邏輯上的定義,一個規範,它把網路從邏輯上分為了7層。每一層都有相關、相對應的物理裝置,比如路由器,交換機。建立七層模型的主要目的是為解決異種網路互連時所遇到的相容性問題,其最主要的功能就是幫助不同型別的主機實現資料傳輸。它的最大優點是將服務、介面和協議這三個概念明確地區分開來,通過七個層次化的結構模型使不同的系統不同的網路之間實現可靠的通訊。

程式設計題

計算加班費

加班10小時以下加班費是時薪的1.5倍。加班10小時或以上,按4元/時算。提示:(一個月工作26天,一天正常工作8小時)

1、計算1000月薪,加班9小時的加班費

2、計算2500月薪,加班11小時的加班費

3、計算1000月薪,加班15小時的加班費

賣東西

一家商場有紅蘋果和青蘋果出售。(紅蘋果5元/個,青蘋果4元/個)。

1、模擬一個進貨。紅蘋果跟青蘋果各進200個。

2、模擬一個出售。紅蘋果跟青蘋果各買出10個。每賣出一個蘋果需要進行統計。

提示:一個蘋果是一個單獨的實體。

日期提取

有這樣一個時間字串:2008-8-8 20:08:08 , 請編寫能夠匹配它的正規表示式,並編寫Java程式碼將日期後面的時分秒提取出來,即:20:08:08
執行緒

1、設計4個執行緒,其中兩個執行緒每次對j增加1,另外兩個執行緒對j每次減少1。寫出程式。

2、用Java寫一個多執行緒程式,如寫四個執行緒,二個加1,二個對一個變數減一,輸出

3、wait-notify 寫一段程式碼來解決生產者-消費者問題

數字

1、判斷101-200之間有多少個素數,並輸出所有素數

package C;

public class Sushu {

    public static void main(String[] args) {
        int sum=0;
        for (int i = 101; i < 201; i++) 
        {
            for (int j = 2; j <=i; j++)
            {
                if(j==i)
                {
                    System.out.println(j);
                }
                else if(i%j==0)
                {
                    sum++;
                    break;
                }

            }
            
        }
        System.out.println("總共有"+(100-sum)+"個素數");

    }

}

2、用最有效率的方法算出2乘以17等於多少

17>>1

3、有 1 億個數字,其中有 2 個是重複的,快速找到它,時間和空間要最優

4、2 億個隨機生成的無序整數,找出中間大小的值

public class Test2
{

public static void main(String [] srgs)
{
int i=(int)(Math.random()*900)+100;
//int i= new java.util.Random().nextInt(900)+100;也可以
System.out.println(i);

}
}

5、10 億個數字裡裡面找最小的 10 個

package com.yuzhiyun;

import java.util.Arrays;

/**
 * 求一億個數裡面最小的10個數
 * 首先建立節點個數為10的最大堆,然後考慮每一個新的值,讓他和堆頂比較,比堆頂大的元素直接拋棄,如果比堆頂小的數字,讓他替換堆頂,然後調整堆。
 */
public class MaxTenNumber {
    public static void main(String[] args) {
        /**第一個元素0不參與,只是用於佔位置,這樣的話,只要array[k]>array[2k] && array[k]>array[2k+1]那就是最大堆了,
         * 此外,這裡暫時用20個數代替1億個
         */
        int[] array={0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,6,5};
        //建立建立節點個數為10的最大堆
        for(int i=10/2;i>=1;i--){
            adjustHeap(array, i, 10);
        }
        //System.out.println(Arrays.toString(array));
        for(int i=11;i<array.length;i++){
            //如果這個元素小於堆頂,和堆頂交換,然後重新調整堆
            if(array[i]<array[1]){
                swap(array, i, 1);
                adjustHeap(array, 1, 10);
            }

        }
        System.out.println(Arrays.toString(array));
        System.out.println("最小的10個數字為:");
        for(int i=1;i<=10;i++){
            System.out.print(array[i]+" ");
        }
    }

    /**
     * 交換
     * @param array
     * @param i
     * @param j
     */
    private static void swap(int[] array, int i, int j) {
        int tem=array[i];
        array[i]=array[j];
        array[j]=tem;
    }

    /**
     * 在以array[head]為根的左右子樹是最大堆的前提下把以array[head]為根的樹調整為最大堆
     * @param array
     * @param head
     * @param tail
     */
    static void adjustHeap(int[] array,int head,int tail){
        int root=array[head];
        int i=2*head;
        while(i<=tail){
            int max=array[i];
            if(i+1<=tail)
                if(array[i+1]>array[i]){
                    max=array[i+1];
                    i++;
                }
            if(root>max)
                //別手抖寫成了return;
                break;
            else{
                array[i/2]=array[i];        
            }
            i*=2;
        }
        array[i/2]=root;
    }
}

6、1到1億的自然數,求所有數的拆分後的數字之和,如286 拆分成2、8、6,如1到11拆分後的數字之和 => 1 + ... + 9 + 1 + 0 + 1 + 1

7、一個數如果恰好等於它的因子之和,這個數就稱為 “完數“。例如6=1+2+3.程式設計 找出1000以內的所有完數

package a;

public class Wanshu {

    public static void main(String[] args) {
        
        for (int i = 1; i <= 1000; i++)
        {
            int sum=0;
            for (int j = 1; j < i; j++)
            {
            if(i%j==0)
            {
                sum+=j;
            }
                
            }
            if(i==sum)
            {
                System.out.println(i);
            }
        }

    }

}

8、一個陣列中所有的元素都出現了三次,只有一個元素出現了一次找到這個元素

    int singleNumber(int A[], int n) {  
        int result=0;  
        for(int i=0;i<32;i++){  
            int bit=0;  
            for(int j=0;j<n;j++){  
                bit+=(A[j]>>i)&1;  
            }  
            result |= (bit%3)<<i;  
        }  
        return result;  
    }  

9、一球從100米高度自由落下,每次落地後反跳回原高度的一半;再落下,求它在 第10次落地時,共經過多少米?第10次反彈多高?

package lianxi;

public class Qiu {

    public static void main(String[] args) {
        double sum1 = 0, sum2 = 0, hight = 100.0;

        for (int i = 0; i < 10; i++)
        {
            sum1 = sum1 + hight;
            // 顯示了一下高度的變化
            // System.out.print(hight);
            hight = hight / 2;
            // System.out.print(" "+hight);
            //System.out.println();
            if (i < 9)

            {
                sum2 = sum2 + hight;
            }
        }
        System.out.println("第10次落地時,共經過" + (sum1 + sum2) + "米");
        System.out.println("第十次反彈高度為" + hight + "米");
        
    }

}

10、求100-1000內質數的和

public class TestZhiShu {

public static void main(String[] args) {

    /**
     * 求100-1000之內的質數的數量
     */
    int count=0;
     for (int i = 102; i <= 1000; i++) { // 質數
            for (int k = 2; k <= i; k++) { // 除數
                // 排除所有在 i=k 之前 能被k整除(餘數為0)的數
                if (i % k == 0 && i != k) {
                    break;
                }
                // 輸出所有在 i=k 且 i%k=0的數
                if (i % k == 0 && i == k) {
                    //System.out.println(i);
                    count++;
                }
            }
        }
     System.out.println(count);
    }
    }

11、求1到100的和的平均數

12、求s=a+a+aaa+aaaa+aa…a的值,其中a是一個數字。例如2+22+222+2222+22222(此時共有5個數相加),幾個數相加有鍵盤控制。 求出1到100的和

package com.liron.p1;

import java.io.IOException;
import java.util.Scanner;

/**
 * 求s=a+aa+aaa+aaaa+aa...a的值,其中a是一個數字。
 * 例如2+22+222+2222+22222(此時共有5個數相加),幾個數相
 * 加有鍵盤控制。
 */
public class Topic18 {
    public static void main(String[] args) throws IOException  
    {  
        Scanner sc = new Scanner(System.in);
        System.out.println("用哪個數迴圈?:");
        int _temp = sc.nextInt();  
        System.out.println("迴圈相加多少次?:");
        int temp = sc.nextInt();
   
        int newNumber = 0; // 每次生成的新數  
        int total = 0; // 計算結果  
        for (int i = 0; i < temp; i++)  
        {  
            newNumber = newNumber * 10 + _temp;  
            System.out.println(newNumber);  
            total = total + newNumber;  
        }  
        System.out.println("計算結果:" + total);  
    }
}

13、算出1到40的質數,放進陣列裡

① 顯示放組裡的數

② 找出第[5]個數

③ 刪除第[9]個數,再顯示刪除後的第[9]個

14、有 3n+1 個數字,其中 3n 箇中是重複的,只有 1 個是不重複的,怎麼找出來。

15、有一組數1.1.2.3.5.8.13.21.34。寫出程式隨便輸入一個數就能給出和前一組數字同規律的頭5個數

16、計算指定數字的階乘

public class CalculatingFactorial {
    public static void main(String args[]) {
        for (int counter = 0; counter <= 10; counter++) {
            System.out.printf("%d! = %d\n", counter, factorial(counter));
        }
    }

    public static long factorial(long number) {
        if (number <= 1)
            return 1;
        else
            return number * factorial(number - 1);
    }
}

17、開發 Fizz Buzz

參考:https://www.cnblogs.com/webary/p/6507413.html

18、給定一個包含 N 個整數的陣列,找出丟失的整數

    import java.util.*;  
      
    public class Finder {  
        public int findMissing(int[][] numbers, int n) {  
            // write code here  
            int i = 0;  
            for(i=0; i<n; ++i){  
                if(i%2!=numbers[i][0]){  
                    break;  
                }  
            }  
            return i;  
        }  
          
    }  

19、一個排好序的陣列,找出兩數之和為m的所有組合

     public static void main(String[] args) throws UnsupportedEncodingException {  
            int[] ints = { 1, 3, 10, 12 , 13, 18, 22 ,58 };  
            int find = 23;  
      
            int start = 0;  
            int end = ints.length - 1;  
      
            while (ints[start] >= find) {  
                System.out.println("都比他-------------------------------大哦!");  
                return;  
            }  
      
      
            while (end > start) {  
                if (ints[start] + ints[end] == find) {  
                    System.out.println(ints[start] + " + " + ints[end] + " = "  
                            + find);  
                    end--;  
                    start++;  
      
                } else if (ints[start] + ints[end] < find) {  
                    start++;  
                } else if (ints[start] + ints[end] > find) {  
                    end--;  
                }  
                System.out.println(start +"   "+end);  
            }  
      
        }  

20、將一個正整數分解質因數。例如:輸入90,列印出90=233*5。

    //【程式4】FenJie.java 題目:將一個正整數分解質因數。例如:輸入90,列印出90=2*3*3*5。  程式分析:對n進行分解質因數,  
    //應先找到一個最小的質數k,然後按下述步驟完成:  (1)如果這個質數恰等於n,則說明分解質因數的過程已經結束,列印出即可。  
    //(2)如果n<>k,但n能被k整除,則應列印出k的值,並用n除以k的商,作為新的正整數n,重複執行第一步。   
    //(3)如果n不能被k整除,則用k+1作為k的值,重複執行第一步。  
    //任何一個正整數都可以分解為其由多個質數相乘。。  
    import java.io.*;  
    import java.util.*;  
    public class FenJieApp {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) {  
            // TODO Auto-generated method stub  
      
                
              System.out.println("請輸入數字:");  
              Scanner scanner = new Scanner(System.in);  
              int parm=scanner.nextInt();  
                
              System.out.print(parm+"=");  
                
              for(int i=2;i<=parm;i++)  
              {  
                while(parm!=i)  
                  {  
                      if(parm%i==0)  
                    {   
                        System.out.print(i+"*");  
                        parm=parm/i;  
                    }  
                     else  
                        break;  
                }  
              }  
              System.out.print(parm);  
        }  
    }  

21、列印出所有的 “水仙花數 “,所謂 “水仙花數 “是指一個三位數,其各位數字立方和等於該數本身。例如:153是一個 “水仙花數 “,因為153=1的三次方+5的三次方+3的三次方

package com.hanqi;

public class Text4 {

    public static void main(String[] args) {

        for (int num=100;num<1000;num++)
        {
            int gw=num%10;
            int sw=num/10%10;
            int bw=num/100%10;
            if (gw*gw*gw+sw*sw*sw+bw*bw*bw==num)
            {
                System.out.println(num);
            }
        }
    }

}

22、原地交換兩個變數的值

參考:https://www.cnblogs.com/Brad-Lee/p/5808299.html

23、找出4位元組整數的中位數

參考:http://blog.csdn.net/randyjiawenjie/article/details/6968591

24、找到整數的平方根

參考:https://www.cnblogs.com/Matrix_Yao/archive/2009/07/28/1532883.html

25、實現斐波那契

參考:http://blog.csdn.net/duhacker/article/details/48295807

網路

1、用Java Socket程式設計,讀伺服器幾個字元,再寫入本地顯示

反射

1、反射機制提供了什麼功能?

得到該物件所屬的類:
Class ownerClass = owner.getClass()
在執行時構造一個類的物件:
Class newoneClass = Class.forName(className):第一步,得到要構造的例項的Class。Constructor cons = newoneClass.getConstructor(argsClass):得到構造子。cons.newInstance(args):新建例項。
在執行時判斷一個類所具有的成員變數和方法:
Class ownerClass = owner.getClass():得到該物件的Class。

Field field = ownerClass.getField(fieldName):通過Class得到類宣告的屬性。

Object property = field.get(owner):通過物件得到該屬性的例項,如果這個屬性是非公有的,這裡會報IllegalAccessException。
在執行時呼叫一個物件的方法:
Method method = ownerClass.getMethod(methodName, argsClass):通過Method名和引數的Class陣列得到要執行的Method。

method.invoke(owner, args):執行該Method,invoke方法的引數是執行這個方法的物件,和引數陣列。返回值是Object,也既是該方法的返回值。

2、反射是如何實現的

所謂反射,是指在執行時狀態中,獲取類中的屬性和方法,以及呼叫其中的方法的一種機制。這種機制的作用在於獲取執行時才知道的類(Class)及其中的屬性(Field)、方法(Method)以及呼叫其中的方法,也可以設定其中的屬性值。
在Java中實現反射最重要的一步,也是第一步就是獲取Class物件,得到Class物件後可以通過該物件呼叫相應的方法來獲取該類中的屬性、方法以及呼叫該類中的方法。
Java中反射有如下幾種實現方式:
1、通過Class.forName()方法載入字串,就可以得到該字串做代表的Class物件。
例如:Class<?> clazz = Class.forName("java.lang.String")就可以得到String類的Class物件。值得注意的是,字串必須是類的全名,即包名+類名。
下邊的程式碼是Struts配置檔案struts.xml中的一個action的配置。

<action name="registe" class="cn.com.huixin.struts2.RegisteAction">
<result>/registeResult.jsp</result>
<result name="input">/registe2.jsp</result>
</action>

這裡的class屬性給出了一個類的全名的字串,伺服器是如何通過這個字串得到類物件的呢?就是通過反射機制RegisteAction物件的。然後再去呼叫這個類中的預設的execute()方法。
2、通過類名呼叫class屬性得到該類的Class物件。
例如:Class<?> clazz = String.class也可以得到String類的Class物件。
3、呼叫例項的getClass()方法。
例如:Date date = new Date();
Class<?> clazz = date.getClass();
通過上邊的兩句程式碼就可以得到date例項的Class物件。
4、如果是基本型別的包裝類,則可以通過呼叫包裝類的Type屬性來獲得該包裝類的Class物件。
例如:Class<?> clazz = Integer.TYPE;

3、哪裡用到反射機制

java的反射機制就是增加程式的靈活性,避免將程式寫死到程式碼裡,典型應用是Spring
例如: 例項化一個 person()物件, 不使用反射, new person(); 如果想變成 例項化 其他類, 那麼必須修改原始碼,並重新編譯。
使用反射: class.forName("person").newInstance(); 而且這個類描述可以寫到配置檔案中,如 **.xml, 這樣如果想例項化其他類,只要修改配置檔案的"類描述"就可以了,不需要重新修改程式碼並編譯。

4、反射中 Class.forName 和 ClassLoader 區別

參考:http://blog.csdn.net/qq_27093465/article/details/52262340

5、反射建立類例項的三種方式是什麼

參考:http://blog.csdn.net/u012110719/article/details/45226937

6、如何通過反射呼叫物件的方法

參考:blog.csdn.net/handsome_fan/article/details/54862873

7、如何通過反射獲取和設定物件私有欄位的值

參考:http://blog.csdn.net/u012726702/article/details/72027028

8、反射機制的優缺點

參考:http://blog.csdn.net/u010154380/article/details/78150251

資料庫

1、寫一段 JDBC 連Oracle的程式,並實現資料查詢

    package svn;  
      
    import java.sql.Connection;  
    import java.sql.DriverManager;  
    import java.sql.PreparedStatement;  
    import java.sql.ResultSet;  
      
      
    public class Main {  
        public static void main(String[] args) throws Exception {  
      
            // 1、載入驅動  
            Class.forName("com.mysql.jdbc.Driver");  
      
            // 2、建立資料庫連線物件  
            Connection conn = null;  
      
            conn = DriverManager  
                    .getConnection(  
                            "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8",  
                            "root", "123456");  
      
            // 3、建立資料庫命令執行物件  
      
            PreparedStatement psPreparedStatement = conn  
                    .prepareStatement("select * from t_user");  
            // Statement stmtStatement=conn.createStatement();  
      
            // 4、執行資料庫命令  
            ResultSet rSet = psPreparedStatement.executeQuery();  
            //ResultSet rs=stmtStatement.executeQuery("select * from t_user");  
            //5、處理執行結果  
            while(rSet.next()){  
                int id=rSet.getInt("id");  
                String usernameString=rSet.getString("username");  
                String passwordString=rSet.getString("password");  
            }  
            if(rSet!=null)  
                rSet.close();  
            if(psPreparedStatement!=null)  
                psPreparedStatement.close();  
            if(conn!=null)  
                conn.close();  
        }  
    }  

演算法

1、50個人圍坐一圈,當數到三或者三的倍數出圈,問剩下的人是誰,原來的位置是多少

 /*出圈演算法是一類比較典型的演算法面試題,它可以很好地考察求職者的程式設計功底。由於它是一種迴圈的邏輯,因此它比起一般的基礎演算法題會更難一些。本例在回答該問題的同時,詳細地講解出圈演算法的實現思路。

對於出圈的問題,它有一個比較大的困難點,就是它總是重複迴圈的,它的頭就是它的尾巴,所以,出圈問題的迴圈語句是比較難寫的。

該題目的圈的元素個數是50個,每次數到3或3的倍數的時候,就把當前元素出圈,並且繼續數數,直到再遇到3的倍數。這裡,如果下標從0開始,一直到一圈完成以後,它就會接到圈的首部,這應該如何處理呢?其實,最好的辦法就是使用取餘的辦法,就可以始終得到3個倍數,無論它的倍數是多少,也不管它的元素個數是多少。

由於每次去掉元素以後,元素的個數會少一個,因此下一個3的倍數其實只需要走兩步,在為其下標賦值的時候,需要減一,保持每次去掉的元素都是3的倍數。

說明:如果使用從0開始的下標開始計算,那麼初始化的時候應該使用-1,這樣就可以模擬元素已經減少一個了。

至於元素的儲存,可以使用陣列,也可以使用連結串列。陣列的元素去掉以後,它的下一個元素是不會自動往前移動的,不太好使用,但是也可以使用。這裡,最好是使用java.util.List連結串列來表示,它既有下標,又可以很方便地獲得元素的當前個數,儘管效率比陣列要稍微低一些,不過已經足夠了。*/
    import java.util.LinkedList;    
    import java.util.List;    
    //測試類    
    public class Cycle {      
        public static int cycle(int total, int k) {  //功能方法    
            List<Integer> dataList = new LinkedList<Integer>();//建立連結串列物件    
            for (int i = 0; i < total; i++)  //新增資料元素    
                dataList.add(new Integer(i + 1));      
            int index = -1;  //定義下標,模擬已經去掉一個元素,因此從-1開始  
        while (dataList.size() > 1) { //一直迴圈去除資料,直到只剩下一個元素   
                index = (index + k) % dataList.size();//得到應該出局的下標    
                dataList.remove(index--);  //去除元素    
            }      
            return ((Integer) dataList.get(0)).intValue();//返回它的值    
        }      
      //主方法    
        public static void main(String[] args) {      
            System.out.println("該數字原來的位置是:"+cycle(50, 3));     
        }      
    }  

2、實現一個電梯模擬器用

基本思路:

模擬電梯執行(為單一電梯,未考慮達到承載上限,最短等待時間等問題)

基本條件:

1、電梯有三種狀態:靜止,向上,向下。

2、每層的指示燈有三種狀態:向上、向下、到達(只開門)。

3、開門上人1秒,每上或下一層用0.1秒。

 

/*實現方案:

使用一個佇列(可看做時間優先)將所有按鈕事件依次入隊。

當電梯靜止時首先響應隊頭的按鈕事件,並根據按鈕樓層和當前樓層的位置確定移動方向; 當向上移動時,將移動到所有亮燈的按鈕所在樓層的最高層,當按鈕方向和電梯方向一致時或該樓層內部到達按鈕亮起時開門;向下移動類似。 當佇列中沒有按鈕事件時,電梯靜止。有些類似LOOK算數,但沒有按鈕事件時不會來回掃描。

使用主執行緒來控制電梯上下,需要注意同步“設定和獲取電梯按鈕最高層或按鈕最底層數的方法”。*/
while(true){
            if(!ele.getPushedFloor().isEmpty()){
                int nextFloor = ele.getPushedFloor().peek();
                if(nextFloor > 0){//向上的按鈕
                    if(ele.getCurFloor() - nextFloor <= 0){
                        ele.liftUp();
                    }else if(ele.getCurFloor() - nextFloor > 0){
                        ele.liftDown();
                    }
                }else{//向下的按鈕
                    if(ele.getCurFloor() + nextFloor < 0){
                        ele.liftUp();
                    }else if(ele.getCurFloor() + nextFloor >= 0){
                        ele.liftDown();
                    }
                }
            }else{
                ele.setStat(RunningStat.INIT);
            }
            Thread.sleep(100);
        }

3、寫一個氣泡排序

package sort;

public class BubbleSort {
    //第一種方法完全就是按照氣泡排序的定義來寫的
    //程式碼完全沒有經過優化
    public void Bubble1(int[]a,int n){
        int i,j;
        for(i=0;i<n-1;i++){
            for(j=1;j<n-i;j++){
                if(a[j-1]>a[j]){
                    swap(a,j-1,j);
                    //int k;
                    //k=a[j-1];
                    //a[j-1]=a[j];
                    //a[j]=k;
            }
        }
    }
   }
   //第二種方法程式碼優化一下 寫一個標誌位,如果一趟下來發生交換則標誌為true,如果未發生交換,為false
    //則代表排序已完成
    public void Bubble2(int[]a,int n){
        int u,v;
        boolean flag;
        flag=true;
        while(flag){
            flag=false;
            for(u=0;u<n-1;u++){
                for(v=1;v<n-u;v++){
                    if(a[v-1]>a[v])
                        swap(a,v-1,v);
                }
                flag=false;
            }
            }

    }
//第三種方法,如果有一個50個數的陣列,僅前面10個數是無序的,後面40個數是有序的,並且大於前面10個數,那麼
    //第一次排序後,最後發生交換的位置必小於10,且這個位置之後的資料必定是有序的,記錄下這個位置後,
    //以後遍歷就從頭到這個位置就可以了
    public void Bubble3(int[]a,int n){
        int p,q;
        int flag1=n;
        while(flag1>0){
            q=flag1;
            flag1=0;
            for(p=1;p<q;p++){
                if(a[p-1]>a[p])
                    swap(a,p-1,p);
                flag1=p;
            }
        }
    }
    public void swap(int a[],int p,int q ){
        int k;
        k=a[p];
     a[p]=a[q];
        a[q]=k;

    }  

   }

4、寫一個折半查詢

    import java.util.Comparator;  
       
    public class MyUtil {  
       
       public static <T extends Comparable<T>> int binarySearch(T[] x, T key) {  
          return binarySearch(x, 0, x.length- 1, key);  
       }  
       
       // 使用迴圈實現的二分查詢  
       public static <T> int binarySearch(T[] x, T key, Comparator<T> comp) {  
          int low = 0;  
          int high = x.length - 1;  
          while (low <= high) {  
              int mid = (low + high) >>> 1;  
              int cmp = comp.compare(x[mid], key);  
              if (cmp < 0) {  
                low= mid + 1;  
              }  
              else if (cmp > 0) {  
                high= mid - 1;  
              }  
              else {  
                return mid;  
              }  
          }  
          return -1;  
       }  
       
       // 使用遞迴實現的二分查詢  
       private static<T extends Comparable<T>> int binarySearch(T[] x, int low, int high, T key) {  
          if(low <= high) {  
            int mid = low + ((high -low) >> 1);  
            if(key.compareTo(x[mid])== 0) {  
               return mid;  
            }  
            else if(key.compareTo(x[mid])< 0) {  
               return binarySearch(x,low, mid - 1, key);  
            }  
            else {  
               return binarySearch(x,mid + 1, high, key);  
            }  
          }  
          return -1;  
       }  
    }  

5、隨機產生20個不能重複的字元並排序

import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;


public class bb {

    public static void main(String[] args) {
        
        Set noreapeat  =new TreeSet();
      
        
         Random rdm = new Random();  
        while (noreapeat.size()<20){
            
            int  bb =Math.abs(rdm.nextInt())%26+97;
            
             char cc =(char)bb;
            noreapeat.add(cc);
        }
        System.out.println(noreapeat);
        
        
        
        

    }

}

6、寫一個函式,傳入 2 個有序的整數陣列,返回一個有序的整數陣列

7、寫一段程式碼在遍歷 ArrayList 時移除一個元素

8、古典問題:有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第四個月後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少

9、約瑟芬環遊戲

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class No10 {
//約瑟芬環 遊戲:有n個人站成一個圈,標上號1-n:從第一個開始報數,數到m,就拖出去殺掉,下一位從一開始數,數到m殺掉,問最後一個人的標號是多少,
//下面有兩個方法
//方法2是正確的,方法只能滿足小資料,大一點的就異常了。求大神幫我改一下,看我的列印資訊就知道我的思路了。
public static void main(String[] args) {
// TODO Auto-generated method stub
//經測試,輸入: 6 3
//12 4都成功,輸入大了就不行了,比如54 12就報錯了,求幫我修改一下
Scanner scanner = new Scanner(System.in);

System.out.print("請輸入總人數:");

int totalNum = scanner.nextInt();

System.out.print("請輸入報數的大小:");

int cycleNum = scanner.nextInt();
yuesefu1(totalNum, cycleNum);

System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
yuesefu2(totalNum, cycleNum);

}

public static void yuesefu1(int t ,int p)
{
    //首先我把這些人給放到陣列裡面,方便操作

    List l = new ArrayList();
    for(int i=1;i<=t;i++)
    { 
        l.add(i);
    }
    System.out.println(l.size());

    int wei =p;
    while(l.size()>1)
    {
        if(l.size()==p)
        {
            System.out.println("等於p");
            System.out.println("刪掉"+l.get(p-1));
            l.remove(p-1);
        }if(l.size()<p)
        {
            System.out.println("小於p");
            System.out.println("刪掉"+l.get(p-l.size()-1));
            l.remove(l.get(p-l.size()-1));
            System.out.println("---------------------------------");
            for(int k = 0;k<l.size();k++)
            {
                System.out.print(l.get(k)+".");
            }
            System.out.println("---------------------------------");

        }
        else{
        //先刪除一個p位置的
        l.remove(p-1);
        //---------------------------------
        System.out.println("---------------------------------");
        for(int k = 0;k<l.size();k++)
        {
            System.out.print(l.get(k)+".");
        }
        System.out.println("---------------------------------");
        //---------------------------------
        for(int j=0;j<p-1;j++)
        {
            l.add(l.get(j));
        }
        //---------------------------------
        System.out.println("---------------------------------");
        for(int k = 0;k<l.size();k++)
        {
            System.out.print(l.get(k)+".");
        }
        System.out.println();
        System.out.println("---------------------------------");
        //---------------------------------
        for(int j=0;j<p-1;j++)
        {
            l.remove(0);
        }
        //---------------------------------
        System.out.println("---------------------------------");
        for(int k = 0;k<l.size();k++)
        {
            System.out.print(l.get(k)+".");
        }System.out.println();
        System.out.println("---------------------------------");
        }
    }

    System.out.println("最後的:"+l.get(0));
}

public static void yuesefu2(int t,int p)
{
    List list = new ArrayList();
    for(int i=1;i<=t;i++)
    {
        list.add(i);
    }
    int k=0;
    while(list.size()>0)
    {
        k = k+p; 
        k= k%(list.size())-1;
         System.out.print("k="+k+"值為:");
        if(k<0)
        {
            System.out.println(list.get(list.size()-1));
            list.remove(list.size()-1);
            k=0;
        }else
        {
            System.out.println(list.get(k));
            list.remove(k);
        }
    }

}

}

正則

1、請編寫一段匹配IP地址的正規表示式

之前一直不太會寫正規表示式,很多要用到正規表示式的都直接百度,像上次要用正規表示式驗證是否是合法的ip地址,然後就上網找,結果就是沒找到一個對的,今天就為大家貢獻一下,寫個對的,並做一下解析。(建議大家還是去看書去規範的學一下,不要直接百度,不然都是坑)。

iPv4的ip地址都是(1~255).(0~255).(0~255).(0~255)的格式

下面給出相對應的正規表示式:

"^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$"

上面的一個不漏就是正確的驗證ip的正規表示式,簡單的講解一下

\\d表示0~9的任何一個數字

{2}表示正好出現兩次

[0-4]表示0~4的任何一個數字

| 的意思是或者

( )上面的括號不能少,是為了提取匹配的字串,表示式中有幾個()就表示有幾個相應的匹配字串

1\\d{2}的意思就是100~199之間的任意一個數字

2[0-4]\\d的意思是200~249之間的任意一個數字

25[0-5]的意思是250~255之間的任意一個數字

[1-9]\\d的意思是10~99之間的任意一個數字

[1-9])的意思是1~9之間的任意一個數字

\\.的意思是.點要轉義(特殊字元類似,@都要加\\轉義)

說到這裡應該已經很清楚的知道了上面的正規表示式的意思。

2、寫出一個正規表示式來判斷一個字串是否是一個數字

public boolean isNumeric(String str){   
   Pattern pattern = Pattern.compile("[0-9]*");   
   Matcher isNum = pattern.matcher(str);  
   if( !isNum.matches() ){  
       return false;   
   }   
   return true;   
}  

字串

1、寫一個方法,入一個檔名和一個字串,統計這個字串在這個檔案中出現的次數。

/**
     * 寫入一個方法,輸入一個檔名和一個字串,統計這個字串在這個檔案中出現的次數。
     * @param fileName 檔名
     * @param str 查詢的字串
     * @return
     * @throws Exception
     */
    //方法一
    public static int funCount1(String fileName,String str) throws Exception {
        int count = 0;
        BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
        String line ;
        StringBuilder sb = new StringBuilder();
        while((line = bf.readLine() )!= null) {
            sb = sb.append(line);
        }
        int a = 0;
        while((a = sb.indexOf(str)) != -1) {
            sb = sb.delete(a, a + str.length());
            count++;
        }
        return count;
    }
    
    //方法二:正規表示式
    public static int funCount2(String fileName,String str) throws Exception {
        int count =0 ;
        BufferedReader bf = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
        String line ;
        StringBuilder sb = new StringBuilder();
        while((line = bf.readLine() )!= null) {
            sb = sb.append(line);
        }
        String pattern = ".*" + str + ".*";
        while(Pattern.matches(pattern, sb.toString())) {
            count ++;
            int a = sb.indexOf(str);
            sb.delete(a, a + str.length());
        }
        return count;
    }

2、寫一個程式找出所有字串的組合,並檢查它們是否是迴文串

public static void main(String[] args) {
  String text = "abccb";
  System.out.println(isHuiwen(text));
 }
 public static boolean isHuiwen(String text){
  int length = text.length();
  for(int i=0;i<length/2;i++){
   if(text.charAt(i)!=text.charAt(length-i-1)){
    return false;
   }
  }
  return true;
 }

3、寫一個字串反轉函式,輸入abcde轉換成edcba程式碼

import java.util.Scanner;

public class Test6 {

    /**
     * 6、將字串中進行反轉。abcde --> edcba
     * 分析:
     *      字串String 有索引  有最大長度
     *      通過for迴圈從最大長度lengrh-1  開始到0為止倒序遍歷
     */
    public static void main(String[] args) {
        //鍵盤錄入任意字串
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一串字串:");
        String line = sc.nextLine();
        //將字串倒序列印
        System.out.println("字串反轉後為:");
        //迴圈條件int i = line.length()-1;i >= 0;i--
        for(int i = line.length()-1;i >= 0;i--){
         //字串轉換成字元輸出
            System.out.print(line.charAt(i));
        }
    }

}

4、小遊戲,倒轉句子中的單詞

public static void reverseWord( char[ ] s,int start,int end  ){
      char temp;
      while(start < end){ 
          temp = s[start];
          s[start] = s[end];
           s[end] = temp;
     }    
}
 public static void reverseSentense(char[] s){
              int len = s.length;
               int start = 0,end = 0;
              reverseWord(s,0,len-1);
           while(start < len){
                    if(s[start] == '  ' ){
                                  start++;
                                  end++;
                                 continue;
                           
                      }else if(s[end] == '  ' || end == len ]){
                                       reverseWord(s,start,end-1);
                                       strat = end;
                       }else{
                                end++;}
 
                    }


}


5、將GB2312編碼的字串轉換為ISO-8859-1編碼的字串

String s2 = new String(s1.getBytes("GB2312"), "ISO-8859-1");  

6、請寫一段程式碼來計算給定文字內字元“A”的個數。分別用迭代和遞迴兩種方式

public class RecursiveCall {
 
    public int countA(String input) {
 
        // exit condition – recursive calls must have an exit condition
        if (input == null || input.length( ) == 0) {
            return 0;
        }
 
        int count = 0;
 
        //check first character of the input
        if (input.substring(0, 1).equals("A")) {
            count = 1;
        }
 
        //recursive call to evaluate rest of the input
        //(i.e.  2nd character onwards)
        return count + countA(input.substring(1));
    }
 
    public static void main(String[ ] args) {
        System.out.println(new RecursiveCall( ).countA("AAA rating"));  // Ans. 3
    }
}

7、編寫一個擷取字串的函式,輸入為一個字串和位元組數,輸出為按位元組擷取的字串。 但是要保證漢字不被截半個,如“我ABC”,應該截為“我AB”,輸入“我ABC漢DEF”,應該輸出為“我ABC”,而不是“我ABC+漢的半個”

一、需要分析

1、輸入為一個字串和位元組數,輸出為按位元組擷取的字串--------------》按照位元組[byte]擷取操作字串,先將String轉換成byte型別

2、漢字不可以截半----------------------------------------------------------------------------------------------------------》漢字截半的話對應位元組的ASC碼為小於0的數值

二、技術難點

1、知道漢字截半的話對應位元組的ASC碼為小於0的數值

2、對字串操作應該都要面對的一個問題,字串是否有效null, 字串的長度0,1這種邊界處理

程式碼實現

package com.itheima;

/**
 * 10、 編寫一個擷取字串的函式,輸入為一個字串和位元組數,輸出為按位元組擷取的字串。
 * 但是要保證漢字不被截半個,如“我ABC”4,應該截為“我AB”,輸入“我ABC漢DEF”,6,應該輸出為“我ABC”而不是“我ABC+漢的半個”。
 * 
 * @author 281167413@qq.com
 */

public class Test10 {

    public static void main(String[] args) {
        String srcStr1 = "我ABC";
        String srcStr2 = "我ABC漢DEF";

        splitString(srcStr1, 4);
        splitString(srcStr2, 6);
    }

    public static void splitString(String src, int len) {
        int byteNum = 0;

        if (null == src) {
            System.out.println("The source String is null!");
            return;
        }

        byteNum = src.length();
        byte bt[] = src.getBytes(); // 將String轉換成byte位元組陣列

        if (len > byteNum) {
            len = byteNum;
        }

        // 判斷是否出現了截半,截半的話位元組對於的ASC碼是小於0的值
        if (bt[len] < 0) {
            String subStrx = new String(bt, 0, --len);
            System.out.println("subStrx==" + subStrx);
        } else {
            String subStrx = new String(bt, 0, len);
            System.out.println("subStrx==" + subStrx);
        }
    }

}

8、給定 2 個包含單詞列表(每行一個)的檔案,程式設計列出交集

9、列印出一個字串的所有排列

import java.util.Scanner;
  
public class Demo001 {
      
    public static void main(String[] args) {
        String str = "";
          
        Scanner scan = new Scanner(System.in);
          
        str = scan.nextLine();
          
        permutation(str.toCharArray(), 0);
    }
  
    public static void permutation(char[] str, int i) {
        if (i >= str.length)
            return;
        if (i == str.length - 1) {
            System.out.println(String.valueOf(str));
        } else {
            for (int j = i; j < str.length; j++) {
                char temp = str[j];
                str[j] = str[i];
                str[i] = temp;
  
                permutation(str, i + 1);
  
                temp = str[j];
                str[j] = str[i];
                str[i] = temp;
            }
        }
    }
  
}

10、將一個鍵盤輸入的數字轉化成中文輸出(例如:輸入1234567,輸出:一百二拾三萬四千五百六拾七)

 public class Reader {
    private String strNum;
    private String strNumChFormat;
    private String strNumTemp;
    private int intNumLen;
    private String strBegin;
    public Reader(String strNum) {
        this.strNum = strNum;
    }
    public boolean check(String strNum) {
        boolean valid = false;
        if (strNum.substring(0,1).equals("0")){
            this.strNum = strNum.substring(1);
        }
        try {
            new Double(strNum);
            valid = true;
        }
        catch (NumberFormatException ex) {
            System.out.println("Bad number format!");
        }
        return valid;
    }
    public void init() {
        strNumChFormat = "";
        intNumLen = strNum.length();
        strNumTemp = strNum;
        strNumTemp = strNumTemp.replace('1', '一');
        strNumTemp = strNumTemp.replace('2', '二');
        strNumTemp = strNumTemp.replace('3', '三');
        strNumTemp = strNumTemp.replace('4', '四');
        strNumTemp = strNumTemp.replace('5', '五');
        strNumTemp = strNumTemp.replace('6', '六');
        strNumTemp = strNumTemp.replace('7', '七');
        strNumTemp = strNumTemp.replace('8', '八');
        strNumTemp = strNumTemp.replace('9', '九');
        strNumTemp = strNumTemp.replace('0', '零');
        strNumTemp = strNumTemp.replace('.', '點');
        strBegin = strNumTemp.substring(0, 1);
    }
    public String readNum() {
        if (check(strNum)) {
            init();
            try {
                for (int i = 1, j = 1, k = 1; i < intNumLen; i++) {
                    if (strNumTemp.charAt(intNumLen - 1) == '零' && i == 1) {
                        strNumChFormat = "位";
                    }
                    else if (strNumTemp.charAt(intNumLen - i) == '零' && j == 1) {
                        strNumChFormat = "位" + strNumChFormat;
                    }
                    else if (strNumTemp.charAt(intNumLen - i) == '點') {
                        j = 1;
                        k = 1;
                        strNumChFormat = strNumTemp.charAt(intNumLen - i) + strNumChFormat;
                        continue;
                   }
                   else {
                       strNumChFormat = strNumTemp.charAt(intNumLen - i) + strNumChFormat;
                    }
          if (strNumTemp.charAt(intNumLen - i - 1) != '位' &&
              strNumTemp.charAt(intNumLen - i - 1) != '零') {
            if (j == 1 && i < intNumLen) {
              strNumChFormat = '拾' + strNumChFormat;
            }
            else if (j == 2 && i < intNumLen) {
              strNumChFormat = '百' + strNumChFormat;
            }
            else if (j == 3 && i < intNumLen) {
              strNumChFormat = '千' + strNumChFormat;
            }
          }
          if (j == 4 && i < intNumLen) {
            j = 0;
          }
          if (k == 4 && i < intNumLen) {
            strNumChFormat = '萬' + strNumChFormat;
          }
          else if (k == 8 && i < intNumLen) {
            k = 0;
            strNumChFormat = '億' + strNumChFormat;
          }
          j++;
          k++;
        }
        while (strNumChFormat.indexOf("位") != -1) {
          strNumChFormat = strNumChFormat.replaceAll("位", " ");
        }
        if (strNumChFormat.substring(0, 2) == "一拾") {
          strNumChFormat = strNumChFormat.substring(1, strNumChFormat.length());
        }
        if (strNumChFormat.indexOf("點") >= 0) {
          String rebegin = strNumChFormat.substring(0,
              strNumChFormat.indexOf("點"));
          String relast = strNumChFormat.substring(strNumChFormat.indexOf("點"),
              strNumChFormat.length());
          for (int i = 1; i <= relast.length(); i++) {
            relast = relast.replaceAll("拾", "");
            relast = relast.replaceAll("百", "");
            relast = relast.replaceAll("千", "");
            relast = relast.replaceAll("萬", "");
            relast = relast.replaceAll("億", "");
          }
          strNumChFormat = rebegin + relast;
        }
      }
      catch (ArrayIndexOutOfBoundsException ex) {
        ex.printStackTrace();
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
      int off = strNumChFormat.indexOf("點");
      strNumChFormat = strBegin + strNumChFormat.substring(0);
    }
    else {
      strNumChFormat = "";
    }
    return strNumChFormat;
  }
  public static void main(String args[]) {
    try {
      String number = args[0].toString();
      System.out.println("The number is: " + number);
      Reader reader = new Reader(number);
      System.out.println("Output String: " + reader.readNum());
    }
    catch (Exception ex) {
      System.out.println("Please input like that: javac Reader <number>");
    }
  }
} 

11、在Web應用開發過程中經常遇到輸出某種編碼的字元,如從 GBK 到 ISO8859-1等,如何輸出一個某種編碼的字串

public String translate (String str) {
        
        String tempStr = "";
        
        try {
            tempStr = new String(str.getBytes("ISO-8859-1"), "GBK");
            tempStr = tempStr.trim();
        }catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return tempStr;
        }

日期

1、計算兩個日期之間的差距

    import java.text.DateFormat;  
    import java.text.ParseException;  
    import java.text.SimpleDateFormat;  
    import java.util.Date;  
    /** 
    * 時間相距 
    * @author Ben 
    * @version 1.0 
    * @date 2009-10-21 16:38:51 
    */  
    public class DateDistance {  
          
        /** 
         * 兩個時間之間相差距離多少天 
         * @param one 時間引數 1: 
         * @param two 時間引數 2: 
         * @return 相差天數 
         */  
        public static long getDistanceDays(String str1, String str2) throws Exception{  
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
            Date one;  
            Date two;  
            long days=0;  
            try {  
                one = df.parse(str1);  
                two = df.parse(str2);  
                long time1 = one.getTime();  
                long time2 = two.getTime();  
                long diff ;  
                if(time1<time2) {  
                    diff = time2 - time1;  
                } else {  
                    diff = time1 - time2;  
                }  
                days = diff / (1000 * 60 * 60 * 24);  
            } catch (ParseException e) {  
                e.printStackTrace();  
            }  
            return days;  
        }  
          
        /** 
         * 兩個時間相差距離多少天多少小時多少分多少秒 
         * @param str1 時間引數 1 格式:1990-01-01 12:00:00 
         * @param str2 時間引數 2 格式:2009-01-01 12:00:00 
         * @return long[] 返回值為:{天, 時, 分, 秒} 
         */  
        public static long[] getDistanceTimes(String str1, String str2) {  
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            Date one;  
            Date two;  
            long day = 0;  
            long hour = 0;  
            long min = 0;  
            long sec = 0;  
            try {  
                one = df.parse(str1);  
                two = df.parse(str2);  
                long time1 = one.getTime();  
                long time2 = two.getTime();  
                long diff ;  
                if(time1<time2) {  
                    diff = time2 - time1;  
                } else {  
                    diff = time1 - time2;  
                }  
                day = diff / (24 * 60 * 60 * 1000);  
                hour = (diff / (60 * 60 * 1000) - day * 24);  
                min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);  
                sec = (diff/1000-day*24*60*60-hour*60*60-min*60);  
            } catch (ParseException e) {  
                e.printStackTrace();  
            }  
            long[] times = {day, hour, min, sec};  
            return times;  
        }  
        /** 
         * 兩個時間相差距離多少天多少小時多少分多少秒 
         * @param str1 時間引數 1 格式:1990-01-01 12:00:00 
         * @param str2 時間引數 2 格式:2009-01-01 12:00:00 
         * @return String 返回值為:xx天xx小時xx分xx秒 
         */  
        public static String getDistanceTime(String str1, String str2) {  
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
            Date one;  
            Date two;  
            long day = 0;  
            long hour = 0;  
            long min = 0;  
            long sec = 0;  
            try {  
                one = df.parse(str1);  
                two = df.parse(str2);  
                long time1 = one.getTime();  
                long time2 = two.getTime();  
                long diff ;  
                if(time1<time2) {  
                    diff = time2 - time1;  
                } else {  
                    diff = time1 - time2;  
                }  
                day = diff / (24 * 60 * 60 * 1000);  
                hour = (diff / (60 * 60 * 1000) - day * 24);  
                min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);  
                sec = (diff/1000-day*24*60*60-hour*60*60-min*60);  
            } catch (ParseException e) {  
                e.printStackTrace();  
            }  
            return day + "天" + hour + "小時" + min + "分" + sec + "秒";  
        }  
    }  

相關文章