Java工程師該如何編寫高效代碼(轉(zhuǎn)阿里技術(shù)微信公眾號(hào))

Java工程師該如何編寫高效代碼?

常意 [阿里技術(shù)]

image

阿里妹導(dǎo)讀:世界上只有兩種物質(zhì):高效率和低效率;世界上只有兩種人:高效率的人和低效率的人。——蕭伯納

同理,世界上只有兩種代碼:高效代碼和低效代碼;世界上只有兩種人:編寫高效代碼的人和編寫低效代碼的人。如何編寫高效代碼,是每個(gè)研發(fā)團(tuán)隊(duì)都面臨的一個(gè)重大問(wèn)題。本文作者根據(jù)實(shí)際經(jīng)驗(yàn),查閱了大量資料,總結(jié)了"Java高效代碼50例",讓每一個(gè)Java程序員都能編寫出"高效代碼"。

1.常量&變量

1.1.直接賦值常量值,禁止聲明新對(duì)象

直接賦值常量值,只是創(chuàng)建了一個(gè)對(duì)象引用,而這個(gè)對(duì)象引用指向常量值。反例:

Long i = new Long(1L);

正例:

Long i = 1L;

1.2.當(dāng)成員變量值無(wú)需改變時(shí),盡量定義為靜態(tài)常量

在類的每個(gè)對(duì)象實(shí)例中,每個(gè)成員變量都有一份副本,而成員靜態(tài)常量只有一份實(shí)例。反例:

public class HttpConnection {

正例:

public class HttpConnection {

1.3.盡量使用基本數(shù)據(jù)類型,避免自動(dòng)裝箱和拆箱

Java 中的基本數(shù)據(jù)類型double、float、long、int、short、char、boolean,分別對(duì)應(yīng)包裝類Double、Float、Long、Integer、Short、Character、Boolean。JVM支持基本類型與對(duì)應(yīng)包裝類的自動(dòng)轉(zhuǎn)換,被稱為自動(dòng)裝箱和拆箱。裝箱和拆箱都是需要CPU和內(nèi)存資源的,所以應(yīng)盡量避免使用自動(dòng)裝箱和拆箱。反例:

Integer sum = 0;

正例:

int sum = 0;

1.4.如果變量的初值會(huì)被覆蓋,就沒有必要給變量賦初值

反例:

List<UserDO> userList = new ArrayList<>();

正例:

List<UserDO> userList;

1.5.盡量使用函數(shù)內(nèi)的基本類型臨時(shí)變量

在函數(shù)內(nèi),基本類型的參數(shù)和臨時(shí)變量都保存在棧(Stack)中,訪問(wèn)速度較快;對(duì)象類型的參數(shù)和臨時(shí)變量的引用都保存在棧(Stack)中,內(nèi)容都保存在堆(Heap)中,訪問(wèn)速度較慢。在類中,任何類型的成員變量都保存在堆(Heap)中,訪問(wèn)速度較慢。反例:

public final class Accumulator {

正例:

public final class Accumulator {

1.6.盡量不要在循環(huán)體外定義變量

在老版JDK中,建議“盡量不要在循環(huán)體內(nèi)定義變量”,但是在新版的JDK中已經(jīng)做了優(yōu)化。通過(guò)對(duì)編譯后的字節(jié)碼分析,變量定義在循環(huán)體外和循環(huán)體內(nèi)沒有本質(zhì)的區(qū)別,運(yùn)行效率基本上是一樣的。反而,根據(jù)“ 局部變量作用域最小化 ”原則,變量定義在循環(huán)體內(nèi)更科學(xué)更便于維護(hù),避免了延長(zhǎng)大對(duì)象生命周期導(dǎo)致延緩回收問(wèn)題 。反例:

UserVO userVO;

正例:

List<UserDO> userDOList = ...;

1.7.不可變的靜態(tài)常量,盡量使用非線程安全類

不可變的靜態(tài)常量,雖然需要支持多線程訪問(wèn),也可以使用非線程安全類。反例:

public static final Map<String, Class> CLASS_MAP;

正例:

public static final Map<String, Class> CLASS_MAP;

1.8.不可變的成員變量,盡量使用非線程安全類

不可變的成員變量,雖然需要支持多線程訪問(wèn),也可以使用非線程安全類。反例:

@Service

正例:

@Service

2****.對(duì)象&類

2.1.禁止使用JSON轉(zhuǎn)化對(duì)象

JSON提供把對(duì)象轉(zhuǎn)化為JSON字符串、把JSON字符串轉(zhuǎn)為對(duì)象的功能,于是被某些人用來(lái)轉(zhuǎn)化對(duì)象。這種對(duì)象轉(zhuǎn)化方式,雖然在功能上沒有問(wèn)題,但是在性能上卻存在問(wèn)題。反例:

List<UserDO> userDOList = ...;

正例:

List<UserDO> userDOList = ...;

2.2.盡量不使用反射賦值對(duì)象

用反射賦值對(duì)象,主要優(yōu)點(diǎn)是節(jié)省了代碼量,主要缺點(diǎn)卻是性能有所下降。反例:

List<UserDO> userDOList = ...;

正例:

List<UserDO> userDOList = ...;

2.3.采用Lambda表達(dá)式替換內(nèi)部匿名類

對(duì)于大多數(shù)剛接觸JDK8的同學(xué)來(lái)說(shuō),都會(huì)認(rèn)為L(zhǎng)ambda表達(dá)式就是匿名內(nèi)部類的語(yǔ)法糖。實(shí)際上, Lambda表達(dá)式在大多數(shù)虛擬機(jī)中采用invokeDynamic指令實(shí)現(xiàn),相對(duì)于匿名內(nèi)部類在效率上會(huì)更高一些。反例:

List<User> userList = ...;

正例:

List<User> userList = ...;

2.4.盡量避免定義不必要的子類

多一個(gè)類就需要多一份類加載,所以盡量避免定義不必要的子類。反例:

public static final Map<String, Class> CLASS_MAP =

正例:

public static final Map<String, Class> CLASS_MAP;

2.5.盡量指定類的final修飾符

為類指定final修飾符,可以讓該類不可以被繼承。如果指定了一個(gè)類為final,則該類所有的方法都是final的,Java編譯器會(huì)尋找機(jī)會(huì)內(nèi)聯(lián)所有的final方法。內(nèi)聯(lián)對(duì)于提升Java運(yùn)行效率作用重大,具體可參見Java運(yùn)行期優(yōu)化,能夠使性能平均提高50%。反例:

public class DateHelper {

正例:

public final class DateHelper {

注意:使用Spring的AOP特性時(shí),需要對(duì)Bean進(jìn)行動(dòng)態(tài)代理,如果Bean類添加了final修飾,會(huì)導(dǎo)致異常。

3.方法

3.1.把跟類成員變量無(wú)關(guān)的方法聲明成靜態(tài)方法

靜態(tài)方法的好處就是不用生成類的實(shí)例就可以直接調(diào)用。靜態(tài)方法不再屬于某個(gè)對(duì)象,而是屬于它所在的類。只需要通過(guò)其類名就可以訪問(wèn),不需要再消耗資源去反復(fù)創(chuàng)建對(duì)象。即便在類內(nèi)部的私有方法,如果沒有使用到類成員變量,也應(yīng)該聲明為靜態(tài)方法。反例:

public int getMonth(Date date) {

正例:

public static int getMonth(Date date) {

3.2.盡量使用基本數(shù)據(jù)類型作為方法參數(shù)類型,避免不必要的裝箱、拆箱和空指針判斷

反例:

public static double sum(Double value1, Double value2) {

正例:

public static double sum(double value1, double value2) {

3.3.盡量使用基本數(shù)據(jù)類型作為方法返回值類型,避免不必要的裝箱、拆箱和空指針判斷

在JDK類庫(kù)的方法中,很多方法返回值都采用了基本數(shù)據(jù)類型,首先是為了避免不必要的裝箱和拆箱,其次是為了避免返回值的空指針判斷。比如:Collection.isEmpty()和Map.size()。反例:

public static Boolean isValid(UserDO user) {

正例:

public static boolean isValid(UserDO user) {

3.4.協(xié)議方法參數(shù)值非空,避免不必要的空指針判斷

協(xié)議編程,可以@NonNull和@Nullable標(biāo)注參數(shù),是否遵循全憑調(diào)用者自覺。反例:

public static boolean isValid(UserDO user) {

正例:

public static boolean isValid(@NonNull UserDO user) {

3.5.協(xié)議方法返回值非空,避免不必要的空指針判斷

協(xié)議編程,可以@NonNull和@Nullable標(biāo)注參數(shù),是否遵循全憑實(shí)現(xiàn)者自覺。反例:

// 定義接口

正例:

// 定義接口

3.6.被調(diào)用方法已支持判空處理,調(diào)用方法無(wú)需再進(jìn)行判空處理

反例:

UserDO user = null;

正例:

UserDO user = JSON.parseObject(value, UserDO.class);

3.7.盡量避免不必要的函數(shù)封裝

方法調(diào)用會(huì)引起入棧和出棧,導(dǎo)致消耗更多的CPU和內(nèi)存,應(yīng)當(dāng)盡量避免不必要的函數(shù)封裝。當(dāng)然,為了使代碼更簡(jiǎn)潔、更清晰、更易維護(hù),增加一定的方法調(diào)用所帶來(lái)的性能損耗是值得的。反例:

// 函數(shù)封裝

正例:

boolean isVip = Boolean.TRUE.equals(user.getVip());

3.8.盡量指定方法的final修飾符

方法指定final修飾符,可以讓方法不可以被重寫,Java編譯器會(huì)尋找機(jī)會(huì)內(nèi)聯(lián)所有的final方法。內(nèi)聯(lián)對(duì)于提升Java運(yùn)行效率作用重大,具體可參見Java運(yùn)行期優(yōu)化,能夠使性能平均提高50%。注意:所有的private方法會(huì)隱式地被指定final修飾符,所以無(wú)須再為其指定final修飾符。反例:

public class Rectangle {

正例:

public class Rectangle {

注意:使用Spring的AOP特性時(shí),需要對(duì)Bean進(jìn)行動(dòng)態(tài)代理,如果方法添加了final修飾,將不會(huì)被代理。

4.表達(dá)式

4.1.盡量減少方法的重復(fù)調(diào)用

反例:

List<UserDO> userList = ...;

正例:

List<UserDO> userList = ...;

4.2.盡量避免不必要的方法調(diào)用

反例:

List<UserDO> userList = userDAO.queryActive();

正例:

List<UserDO> userList;

4.3.盡量使用移位來(lái)代替正整數(shù)乘除

用移位操作可以極大地提高性能。對(duì)于乘除2^n(n為正整數(shù))的正整數(shù)計(jì)算,可以用移位操作來(lái)代替。反例:

int num1 = a * 4;

正例:

int num1 = a << 2;

4.4.提取公共表達(dá)式,避免重復(fù)計(jì)算

提取公共表達(dá)式,只計(jì)算一次值,然后重復(fù)利用值。反例:

double distance = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

正例:

double dx = x2 - x1;

4.5.盡量不在條件表達(dá)式中用!取反

使用!取反會(huì)多一次計(jì)算,如果沒有必要?jiǎng)t優(yōu)化掉。反例:

if (!(a >= 10)) {

正例:

if (a < 10) {

4.6.對(duì)于多常量選擇分支,盡量使用switch語(yǔ)句而不是if-else語(yǔ)句

if-else語(yǔ)句,每個(gè)if條件語(yǔ)句都要加裝計(jì)算,直到if條件語(yǔ)句為true為止。switch語(yǔ)句進(jìn)行了跳轉(zhuǎn)優(yōu)化,Java中采用tableswitch或lookupswitch指令實(shí)現(xiàn),對(duì)于多常量選擇分支處理效率更高。經(jīng)過(guò)試驗(yàn)證明:在每個(gè)分支出現(xiàn)概率相同的情況下,低于5個(gè)分支時(shí)if-else語(yǔ)句效率更高,高于5個(gè)分支時(shí)switch語(yǔ)句效率更高。反例:

if (i == 1) {

正例:

switch (i) {

備注:如果業(yè)務(wù)復(fù)雜,可以采用Map實(shí)現(xiàn)策略模式。

5.字符串

5.1.盡量不要使用正則表達(dá)式匹配

正則表達(dá)式匹配效率較低,盡量使用字符串匹配操作。反例:

String source = "a::1,b::2,c::3,d::4";

正例:

String source = "a::1,b::2,c::3,d::4";

5.2.盡量使用字符替換字符串

字符串的長(zhǎng)度不確定,而字符的長(zhǎng)度固定為1,查找和匹配的效率自然提高了。反例:

String source = "a:1,b:2,c:3,d:4";

正例:

String source = "a:1,b:2,c:3,d:4";

5.3.盡量使用StringBuilder進(jìn)行字符串拼接

String是final類,內(nèi)容不可修改,所以每次字符串拼接都會(huì)生成一個(gè)新對(duì)象。StringBuilder在初始化時(shí)申請(qǐng)了一塊內(nèi)存,以后的字符串拼接都在這塊內(nèi)存中執(zhí)行,不會(huì)申請(qǐng)新內(nèi)存和生成新對(duì)象。反例:

String s = "";

正****例:

StringBuilder sb = new StringBuilder(128);

5.4.不要使用""+轉(zhuǎn)化字符串

使用""+進(jìn)行字符串轉(zhuǎn)化,使用方便但是效率低,建議使用String.valueOf.反例:

int i = 12345;

正例:

int i = 12345;

6.數(shù)組

6.1.不要使用循環(huán)拷貝數(shù)組,盡量使用System.arraycopy拷貝數(shù)組

推薦使用System.arraycopy拷貝數(shù)組,也可以使用Arrays.copyOf拷貝數(shù)組。反例:

int[] sources = new int[] {1, 2, 3, 4, 5};

正例:

int[] sources = new int[] {1, 2, 3, 4, 5};

6.2.集合轉(zhuǎn)化為類型T數(shù)組時(shí),盡量傳入空數(shù)組T[0]

將集合轉(zhuǎn)換為數(shù)組有2種形式:toArray(new T[n])和toArray(new T[0])。在舊的Java版本中,建議使用toArray(new T[n]),因?yàn)閯?chuàng)建數(shù)組時(shí)所需的反射調(diào)用非常慢。在OpenJDK6后,反射調(diào)用是內(nèi)在的,使得性能得以提高,toArray(new T[0])比toArray(new T[n])效率更高。此外,toArray(new T[n])比toArray(new T[0])多獲取一次列表大小,如果計(jì)算列表大小耗時(shí)過(guò)長(zhǎng),也會(huì)導(dǎo)致toArray(new T[n])效率降低。反例:

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, ...);

正例:

List<Integer> integerList = Arrays.asList(1, 2, 3, 4, 5, ...);

建議:集合應(yīng)該提供一個(gè)toArray(Class<T> clazz)方法,避免無(wú)用的空數(shù)組初始化(new T[0])。

6.3.集合轉(zhuǎn)化為Object數(shù)組時(shí),盡量使用toArray()方法

轉(zhuǎn)化Object數(shù)組時(shí),沒有必要使用toArray[new Object[0]],可以直接使用toArray()。避免了類型的判斷,也避免了空數(shù)組的申請(qǐng),所以效率會(huì)更高。反例:

List<Object> objectList = Arrays.asList(1, "2", 3, "4", 5, ...);

正例:

List<Object> objectList = Arrays.asList(1, "2", 3, "4", 5, ...);

7.集合

7.1.初始化集合時(shí),盡量指定集合大小

Java集合初始化時(shí)都會(huì)指定一個(gè)默認(rèn)大小,當(dāng)默認(rèn)大小不再滿足數(shù)據(jù)需求時(shí)就會(huì)擴(kuò)容,每次擴(kuò)容的時(shí)間復(fù)雜度有可能是O(n)。所以,盡量指定預(yù)知的集合大小,就能避免或減少集合的擴(kuò)容次數(shù)。反例:

List<UserDO> userDOList = ...;

正例:

List<UserDO> userDOList = ...;

7.2.不要使用循環(huán)拷貝集合,盡量使用JDK提供的方法拷貝集合

JDK提供的方法可以一步指定集合的容量,避免多次擴(kuò)容浪費(fèi)時(shí)間和空間。同時(shí),這些方法的底層也是調(diào)用System.arraycopy方法實(shí)現(xiàn),進(jìn)行數(shù)據(jù)的批量拷貝效率更高。反例:

List<UserDO> user1List = ...;

正例:

List<UserDO> user1List = ...;

7.3.盡量使用Arrays.asList轉(zhuǎn)化數(shù)組為列表

原理與"不要使用循環(huán)拷貝集合,盡量使用JDK提供的方法拷貝集合"類似。反例:

List<String> typeList = new ArrayList<>(8);

正例:

List<String> typeList = Arrays.asList("Short", "Integer", "Long");

7.4.直接迭代需要使用的集合

直接迭代需要使用的集合,無(wú)需通過(guò)其它操作獲取數(shù)據(jù)。反例:

Map<Long, UserDO> userMap = ...;

正例:

Map<Long, UserDO> userMap = ...;

7.5.不要使用size方法檢測(cè)空,必須使用isEmpty方法檢測(cè)空

使用size方法來(lái)檢測(cè)空邏輯上沒有問(wèn)題,但使用isEmpty方法使得代碼更易讀,并且可以獲得更好的性能。任何isEmpty方法實(shí)現(xiàn)的時(shí)間復(fù)雜度都是O(1),但是某些size方法實(shí)現(xiàn)的時(shí)間復(fù)雜度有可能是O(n)。反例:

List<UserDO> userList = ...;

正例:

List<UserDO> userList = ...;

7.6.非隨機(jī)訪問(wèn)的List,盡量使用迭代代替隨機(jī)訪問(wèn)

對(duì)于列表,可分為隨機(jī)訪問(wèn)和非隨機(jī)訪問(wèn)兩類,可以用是否實(shí)現(xiàn)RandomAccess接口判斷。隨機(jī)訪問(wèn)列表,直接通過(guò)get獲取數(shù)據(jù)不影響效率。而非隨機(jī)訪問(wèn)列表,通過(guò)get獲取數(shù)據(jù)效率極低。反例:

LinkedList<UserDO> userDOList = ...;

正例:

LinkedList<UserDO> userDOList = ...;

其實(shí),不管列表支不支持隨機(jī)訪問(wèn),都應(yīng)該使用迭代進(jìn)行遍歷。

7.7.盡量使用HashSet判斷值存在

在Java集合類庫(kù)中,List的contains方法普遍時(shí)間復(fù)雜度是O(n),而HashSet的時(shí)間復(fù)雜度為O(1)。如果需要頻繁調(diào)用contains方法查找數(shù)據(jù),可以先將List轉(zhuǎn)換成HashSet。反例:

List<Long> adminIdList = ...;

正例:

Set<Long> adminIdSet = ...;

7.8.避免先判斷存在再進(jìn)行獲取

如果需要先判斷存在再進(jìn)行獲取,可以直接獲取并判斷空,從而避免了二次查找操作。反例:

public static UserVO transUser(UserDO user, Map<Long, RoleDO> roleMap) {

正例:

public static UserVO transUser(UserDO user, Map<Long, RoleDO> roleMap) {

8.異常

8.1.直接捕獲對(duì)應(yīng)的異常

直接捕獲對(duì)應(yīng)的異常,避免用instanceof判斷,效率更高代碼更簡(jiǎn)潔。反例:

try {

正例:

try {

8.2.盡量避免在循環(huán)中捕獲異常

當(dāng)循環(huán)體拋出異常后,無(wú)需循環(huán)繼續(xù)執(zhí)行時(shí),沒有必要在循環(huán)體中捕獲異常。因?yàn)椋^(guò)多的捕獲異常會(huì)降低程序執(zhí)行效率。反例:

public Double sum(List<String> valueList) {

正例:

public Double sum(List<String> valueList) {

8.3.禁止使用異常控制業(yè)務(wù)流程

相對(duì)于條件表達(dá)式,異常的處理效率更低。反例:

public static boolean isValid(UserDO user) {

正例:

public static boolean isValid(UserDO user) {

9.緩沖區(qū)

9.1.初始化時(shí)盡量指定緩沖區(qū)大小

初始化時(shí),指定緩沖區(qū)的預(yù)期容量大小,避免多次擴(kuò)容浪費(fèi)時(shí)間和空間。反例:

StringBuffer buffer = new StringBuffer();

正例:

StringBuffer buffer = new StringBuffer(1024);

9.2.盡量重復(fù)使用同一緩沖區(qū)

針對(duì)緩沖區(qū),Java虛擬機(jī)需要花時(shí)間生成對(duì)象,還要花時(shí)間進(jìn)行垃圾回收處理。所以,盡量重復(fù)利用緩沖區(qū)。反例:

StringBuilder builder1 = new StringBuilder(128);

正例:

StringBuilder builder = new StringBuilder(128);

其中,使用setLength方法讓緩沖區(qū)重新從0開始。

9.3.盡量設(shè)計(jì)使用同一緩沖區(qū)

為了提高程序運(yùn)行效率,在設(shè)計(jì)上盡量使用同一緩沖區(qū)。反例:

// 轉(zhuǎn)化XML(UserDO)

正例:

// 轉(zhuǎn)化XML(UserDO)

去掉每個(gè)轉(zhuǎn)化方法中的緩沖區(qū)申請(qǐng),申請(qǐng)一個(gè)緩沖區(qū)給每個(gè)轉(zhuǎn)化方法使用。從時(shí)間上來(lái)說(shuō),節(jié)約了大量緩沖區(qū)的申請(qǐng)釋放時(shí)間;從空間上來(lái)說(shuō),節(jié)約了大量緩沖區(qū)的臨時(shí)存儲(chǔ)空間。

9.4.盡量使用緩沖流減少IO操作

使用緩沖流BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等,可以大幅較少IO次數(shù)并提升IO速度。反例:

try (FileInputStream input = new FileInputStream("a");

正例:

try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("a"));

其中,可以根據(jù)實(shí)際情況手動(dòng)指定緩沖流的大小,把緩沖流的緩沖作用發(fā)揮到最大。

10.線程

10.1.在單線程中,盡量使用非線程安全類

使用非線程安全類,避免了不必要的同步開銷。反例:

StringBuffer buffer = new StringBuffer(128);

正例:

StringBuilder buffer = new StringBuilder(128);

10.2.在多線程中,盡量使用線程安全類

使用線程安全類,比自己實(shí)現(xiàn)的同步代碼更簡(jiǎn)潔更高效。反例:

private volatile int counter = 0;

正例:

private final AtomicInteger counter = new AtomicInteger(0);

10.3.盡量減少同步代碼塊范圍

在一個(gè)方法中,可能只有一小部分的邏輯是需要同步控制的,如果同步控制了整個(gè)方法會(huì)影響執(zhí)行效率。所以,盡量減少同步代碼塊的范圍,只對(duì)需要進(jìn)行同步的代碼進(jìn)行同步。反例:

private volatile int counter = 0;

正例:

private volatile int counter = 0;

10.4.盡量合并為同一同步代碼塊

同步代碼塊是有性能開銷的,如果確定可以合并為同一同步代碼塊,就應(yīng)該盡量合并為同一同步代碼塊。反例:

// 處理單一訂單

正例:

// 處理單一訂單

10.5.盡量使用線程池減少線程開銷

多線程中兩個(gè)必要的開銷:線程的創(chuàng)建和上下文切換。采用線程池,可以盡量地避免這些開銷。反例:

public void executeTask(Runnable runnable) {

正例:

private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);

后記

作為一名長(zhǎng)期奮戰(zhàn)在業(yè)務(wù)一線的"IT民工",沒有機(jī)會(huì)去研究什么高深莫測(cè)的"理論",只能專注于眼前看得見摸得著的"技術(shù)",致力于做到"干一行、愛一行、專一行、精一行"。

阿里云研究中心10+本白皮書全套下載!

數(shù)字經(jīng)濟(jì)時(shí)代,各個(gè)行業(yè)都面臨著巨大的挑戰(zhàn)和機(jī)遇,如何用新科技來(lái)發(fā)現(xiàn)和驅(qū)動(dòng)新的商業(yè)場(chǎng)景和業(yè)務(wù)增量。識(shí)別下方二維碼或點(diǎn)擊“閱讀原文”10+本白皮書全套下載!涵蓋人工智能、云計(jì)算、大數(shù)據(jù)等多項(xiàng)領(lǐng)域。

image
image
image

你可能還喜歡
點(diǎn)擊下方圖片即可閱讀

拼不過(guò) GO?阿里如何重塑云上的 Java

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,401評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,635評(píng)論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,128評(píng)論 1 323
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,365評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,881評(píng)論 1 334
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,733評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,935評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,172評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評(píng)論 1 282
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,595評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,908評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容