Java開發新手問題集錦

来源:http://www.cnblogs.com/beijingsxt/archive/2016/01/14/5130242.html
-Advertisement-
Play Games

北京尚學堂提供Java是目前最流行的編程語言之一——它可以用來編寫Windows程式或者是Web應用,移動應用,網路程式,消費電子產品,機頂盒設備,它無處不在。有超過30億的設備是運行在Java之上的。根據Oracle的統計數據,光是使用中的Java Card就有有50億。超過900萬程式員選擇使用...


北京尚學堂提供

Java是目前最流行的編程語言之一——它可以用來編寫Windows程式或者是Web應用,移動應用,網路程式,消費電子產品,機頂盒設備,它無處不在。

有超過30億的設備是運行在Java之上的。根據Oracle的統計數據,光是使用中的Java Card就有有50億。

超過900萬程式員選擇使用Java進行開發,它是最受開發人員歡迎的語言,同時也是最流行的開發平臺。

本文為那些準Java程式員們準備了一系列廣為流傳的Java最佳編程實踐

  • 優先返回空集合而非null

如果程式要返回一個不包含任何值的集合,確保返回的是空集合而不是null。這能節省大量的”if else”檢查。

1

2

3

public class getLocationName {

    return (null==cityName ? "": cityName);

}

  • 謹慎操作字元串

如果兩個字元串在for迴圈中使用+操作符進行拼接,那麼每次迴圈都會產生一個新的字元串對象。這不僅浪費記憶體空間同時還會影響性能。類似的,如果初始化字元串對象,儘量不要使用構造方法,而應該直接初始化。比方說:

1

2

3

4

5

//Slower Instantiation

String bad = new String("Yet another string object");

      

//Faster Instantiation

String good = "Yet another string object"

  • 避免無用對象

創建對象是Java中最昂貴的操作之一。因此最好在有需要的時候再進行對象的創建/初始化。如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

import java.util.ArrayList;

import java.util.List;

 

public class Employees {

 

    private List Employees;

 

    public List getEmployees() {

 

        //initialize only when required

        if(null == Employees) {

            Employees = new ArrayList();

        }

        return Employees;

    }

}

  • 數組與ArrayList之爭

開發人員經常會發現很難在數組和ArrayList間做選擇。它們二者互有優劣。如何選擇應該視情況而定。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

import java.util.ArrayList;

 

public class arrayVsArrayList {

 

    public static void main(String[] args) {

        int[] myArray = new int[6];

        myArray[7]= 10; // ArraysOutOfBoundException

 

        //Declaration of ArrayList. Add and Remove of elements is easy.

        ArrayList<Integer> myArrayList = new ArrayList<>();

        myArrayList.add(1);

        myArrayList.add(2);

        myArrayList.add(3);

        myArrayList.add(4);

        myArrayList.add(5);

        myArrayList.remove(0);

         

        for(int i = 0; i < myArrayList.size(); i++) {

        System.out.println("Element: " + myArrayList.get(i));

        }

         

        //Multi-dimensional Array

        int[][][] multiArray = new int [3][3][3];

    }

}

  • 數組是定長的,而ArrayList是變長的。由於數組長度是固定的,因此在聲明數組時就已經分配好記憶體了。而數組的操作則會更快一些。另一方面,如果我們不知道數據的大小,那麼過多的數據便會導致ArrayOutOfBoundException,而少了又會浪費存儲空間。
  • ArrayList在增刪元素方面要比數組簡單。
  • 數組可以是多維的,但ArrayList只能是一維的。
  • try塊的finally塊沒有被執行

看下下麵這段代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

public class shutDownHooksDemo {

    public static void main(String[] args) {

        for(int i=0;i<5;i++)

        {

            try {

                if(i==4) {

                    System.out.println("Inside Try Block.Exiting without executing Finally block.");

                    System.exit(0);

                }

            }

            finally {

                System.out.println("Inside Finally Block.");

            }

        }

    }

}

從代碼來看,貌似finally塊中的println語句應該會被執行5次。但當程式運行後,你會發現finally塊只執行了4次。第5次迭代的時候會觸發exit函數的調用,於是這第5次的finally便永遠也觸發不到了。原因便是——System.exit會掛起所有線程的執行,包括當前線程。即便是try語句後的finally塊,只要是執行了exit,便也無力回天了。

在調用System.exit時,JVM會在關閉前執行兩個結束任務:

首先,它會執行完所有通過Runtime.addShutdownHook註冊進來的終止的鉤子程式。這一點很關鍵,因為它會釋放JVM外部的資源。

接下來的便是Finalizer了。可能是System.runFinalizersOnExit也可能是Runtime.runFinalizersOnExit。finalizer的使用已經被廢棄有很長一段時間了。finalizer可以在存活對象上進行調用,即便是這些對象仍在被其它線程所使用。而這會導致不可預期的結果甚至是死鎖。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

public class shutDownHooksDemo {

 

    public static void main(String[] args) {

            for(int i=0;i<5;i++)

            {

                    final int final_i = i;

                    try {

                            Runtime.getRuntime().addShutdownHook(

                                            new Thread() {

                                            public void run() {

                                            if(final_i==4) {

                                            System.out.println("Inside Try Block.Exiting without executing Finally block.");

                                            System.exit(0);

                                            }

                                            }

                                            });

                    }

                    finally {

                            System.out.println("Inside Finally Block.");

                    }

 

            }

    }

}

  • 判斷奇數

看下這幾行代碼,看看它們是否能用來準確地判斷一個數是奇數?

1

2

3

public boolean oddOrNot(int num) {

    return num % 2 == 1;

}

看似是對的,但是每執行四便會有一個錯誤的結果(用數據說話)。考慮到負奇數的情況,它除以2的結果就不會是1。因此,返回值是false,而這樣是不對的。

代碼可以修改成這樣:

1

2

3

public boolean oddOrNot(int num) {

    return (num & 1) != 0;

}

這麼寫不光是負奇數的問題解決了,並且還是經過充分優化過的。因為算術運算和邏輯運行要比乘除運算更高效,計算的結果也會更快。

  • 單引號與雙引號的區別

1

2

3

4

5

6

public class Haha {

    public static void main(String args[]) {

    System.out.print("H" + "a");

    System.out.print('H' + 'a');

    }

}

看起來這段代碼會返回”Haha”,但實際返回的是Ha169。原因就是用了雙引號的時候,字元會被當作字元串處理,而如果是單引號的話,字元值會通過一個叫做基礎類型拓寬的操作來轉換成整型值。然後再將值相加得到169。

  • 一些防止記憶體泄露的小技巧

記憶體泄露會導致軟體的性能降級。由於Java是自動管理記憶體的,因此開發人員並沒有太多辦法介入。不過還是有一些方法能夠用來防止記憶體泄露的。

  • 查詢完數據後立即釋放資料庫連接
  • 儘可能使用finally塊
  • 釋放靜態變數中的實例
  • 避免死鎖

死鎖出現的原因有很多。避免死鎖不是一句話就能解決的。通常來說,當某個同步對象在等待另一個同步對象所擁有的資源上的鎖時,便會產生死鎖。

試著運行下下麵的程式。它會告訴你什麼是死鎖。這個死鎖是由於兩個線程都在等待對方所擁有的資源,因此會產生死鎖。它們會一直等待,沒有誰會先放手。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

public class DeadlockDemo {

   public static Object addLock = new Object();

   public static Object subLock = new Object();

 

   public static void main(String args[]) {

 

      MyAdditionThread add = new MyAdditionThread();

      MySubtractionThread sub = new MySubtractionThread();

      add.start();

      sub.start();

   }

private static class MyAdditionThread extends Thread {

      public void run() {

         synchronized (addLock) {

        int a = 10, b = 3;

        int c = a + b;

            System.out.println("Addition Thread: " + c);

            System.out.println("Holding First Lock...");

            try { Thread.sleep(10); }

            catch (InterruptedException e) {}

            System.out.println("Addition Thread: Waiting for AddLock...");

            synchronized (subLock) {

               System.out.println("Threads: Holding Add and Sub Locks...");

            }

         }

      }

   }

   private static class MySubtractionThread extends Thread {

      public void run() {

         synchronized (subLock) {

        int a = 10, b = 3;

        int c = a - b;

            System.out.println("Subtraction Thread: " + c);

            System.out.println("Holding Second Lock...");

            try { Thread.sleep(10); }

            catch (InterruptedException e) {}

            System.out.println("Subtraction  Thread: Waiting for SubLock...");

            synchronized (addLock) {

               System.out.println("Threads: Holding Add and Sub Locks...");

            }

         }

      }

   }

}

輸出:

1

2

3

4

5

6

Addition Thread: 13

Subtraction Thread: 7

Holding First Lock...

Holding Second Lock...

Addition Thread: Waiting for AddLock...

Subtraction  Thread: Waiting for SubLock...

但如果調用的順序變一下的話,死鎖的問題就解決了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

public class DeadlockSolutionDemo {

   public static Object addLock = new Object();

   public static Object subLock = new Object();

 

   public static void main(String args[]) {

 

      MyAdditionThread add = new MyAdditionThread();

      MySubtractionThread sub = new MySubtractionThread();

      add.start();

      sub.start();

   }

 

 

private static class MyAdditionThread extends Thread {

      public void run() {

         synchronized (addLock) {

        int a = 10, b = 3;

        int c = a + b;

            System.out.println("Addition Thread: " + c);

            System.out.println("Holding First Lock...");

            try { Thread.sleep(10); }

            catch (InterruptedException e) {}

            System.out.println("Addition Thread: Waiting for AddLock...");

            synchronized (subLock) {

               System.out.println("Threads: Holding Add and Sub Locks...");

            }

         }

      }

   }

    

   private static class MySubtractionThread extends Thread {

      public void run() {

         synchronized (addLock) {

        int a = 10, b = 3;

        int c = a - b;

            System.out.println("Subtraction Thread: " + c);

            System.out.println("Holding Second Lock...");

            try { Thread.sleep(10); }

            catch (InterruptedException e) {}

            System.out.println("Subtraction  Thread: Waiting for SubLock...");

            synchronized (subLock) {

               System.out.println("Threads: Holding Add and Sub Locks...");

            }

         }

      }

   }

}

輸出:

1

2

3

4

5

6

7

8

Addition Thread: 13

Holding First Lock...

Addition Thread: Waiting for AddLock...

Threads: Holding Add and Sub Locks...

Subtraction Thread: 7

Holding Second Lock...

Subtraction  Thread: Waiting for SubLock...

Threads: Holding Add and Sub Locks...

  • 替Java省點記憶體

某些Java程式是CPU密集型的,但它們會需要大量的記憶體。這類程式通常運行得很緩慢,因為它們對記憶體的需求很大。為了能提升這類應用的性能,可得給它們多留點記憶體。因此,假設我們有一臺擁有10G記憶體的Tomcat伺服器。在這台機器上,我們可以用如下的這條命令來分配記憶體:

1

export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"

  • Xms = 最小記憶體分配
  • Xmx = 最大記憶體分配
  • XX:PermSize = JVM啟動時的初始大小
  • XX:MaxPermSize = JVM啟動後可分配的最大空間
  • 如何計算Java中操作的耗時

在Java中進行操作計時有兩個標準的方法:System.currentTimeMillis()和System.nanoTime()。問題就在於,什麼情況下該用哪個。從本質上來講,他們的作用都是一樣的,但有以下幾點不同:

  1. System.currentTimeMillis()的精度在千分之一秒到千分之15秒之間(取決於系統)而System.nanoTime()則能到納秒級。
  2. System.currentTimeMillis讀操作耗時在數個CPU時鐘左右。而System.nanoTime()則需要上百個。
  3. System.currentTimeMillis對應的是絕對時間(1970年1 月1日所經歷的毫秒數),而System.nanoTime()則不與任何時間點相關。
  4. Float還是double

數據類型

所用位元組

有效位數

float

4

7

double

8

15

在對精度要求高的場景下,double類型相對float要更流行一些,理由如下:

大多數處理器在處理float和double上所需的時間都是差不多的。而計算時間一樣的前提下,double類型卻能提供更高的精度。

  • 冪運算

Java是通過異或操作來進行冪運算的。Java對於冪運算有兩種處理方式:

  • 乘積:

1

2

3

4

5

double square = double a * double a;                           // Optimized

double cube = double a * double a * double a;                   // Non-optimized

double cube = double a * double square;                       // Optimized

double quad = double a * double a * double a * double a;          // Non-optimized

double quad = double square * double square;                  // Optimized

  • pow方法:在無法使用乘積的情況下可以使用pow方法。

1

double cube = Math.pow(base, exponent);

不到萬不得已不要使用Math.pow。比方說,當指數是小數的時候。因為Math.pow要比乘積慢300-600倍左右。

  • 如何處理空指針異常

空指針異常是Java中很常見的異常。當你嘗試調用一個null對象上的方法時便會拋出這個異常。比如:

1

int noOfStudents = school.listStudents().count;

在上述例子中,school為空或者listStudents()為空都可能會拋出了NullPointerException。因此最好檢查下對象是否為空以避免類似情況。

1

2

3

4

private int getListOfStudents(File[] files) {

      if (files == null)

        throw new NullPointerException("File list cannot be null");

    }

  • JSON編碼

JSON是數據存儲及傳輸的一種協議。與XML相比,它更易於使用。由於它非常輕量級以及自身的一些特性,現在JSON在網路上已經是越來越流行了。常見的數據結構都可以編碼成JSON然後在各個網頁間自由地傳輸。不過在開始編碼前,你得先安裝一個JSON解析器。在下麵的例子中,我們將使用json.simple庫來完成這項工作 (https://code.google.com/p/json-simple/)。

下麵是編碼成JSON串的一個簡單的例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import org.json.simple.JSONObject;

import org.json.simple.JSONArray;

 

public class JsonEncodeDemo {

     

    public static void main(String[] args) {

         

        JSONObject obj = new JSONObject();

        obj.put("Novel Name", "Godaan");

        obj.put("Author", "Munshi Premchand");

  

        JSONArray novelDetails = new JSONArray();

        novelDetails.add("Language: Hindi");

        novelDetails.add("Year of Publication: 1936");

        novelDetails.add("Publisher: Lokmanya Press");

         

        obj.put("Novel Details", novelDetails);

         

        System.out.print(obj);

    }

}

輸出:

1

{"Novel Name":"Godaan","Novel Details":["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}

  • JSON解析

開發人員要想解析JSON串,首先你得知道它的格式。下麵例子有助於你來理解這一點:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.Iterator;

 

import org.json.simple.JSONArray;

import org.json.simple.JSONObject;

import org.json.simple.parser.JSONParser;

import org.json.simple.parser.ParseException;

 

public class JsonParseTest {

 

    private static final String filePath = "//home//user//Documents//jsonDemoFile.json";

     

    public static void main(String[] args) {

 

        try {

            // read the json file

            FileReader reader = new FileReader(filePath);

            JSONParser jsonParser = new JSONParser();

            JSONObject jsonObject = (JSONObject)jsonParser.parse(reader);

             

            // get a number from the JSON object

            Long id =  (Long) jsonObject.get("id");

            System.out.println("The id is: " + id);          

 

            // get a String from the JSON object

            String   type = (String) jsonObject.get("type");

            System.out.println("The type is: " + type);

 

            // get a String from the JSON object

            String   name = (String) jsonObject.get("name");

            System.out.println("The name is: " + name);

 

            // get a number from the JSON object

            Double ppu =  (Double) jsonObject.get("ppu");

            System.out.println("The PPU is: " + ppu);

             

            // get an array from the JSON object

            System.out.println("Batters:");

            JSONArray batterArray= (JSONArray) jsonObject.get("batters");

            Iterator i = batterArray.iterator();

            // take each value from the json array separately

            while (i.hasNext()) {

                JSONObject innerObj = (JSONObject) i.next();

                System.out.println("ID "+ innerObj.get("id") +

                        " type " + innerObj.get("type"));

            }

             // get an array from the JSON object

            System.out.println("Topping:");

            JSONArray toppingArray= (JSONArray) jsonObject.get("topping");

            Iterator j = toppingArray.iterator();

            // take each value from the json array separately

            while (j.hasNext()) {

                JSONObject innerObj = (JSONObject) j.next();

                System.out.println("ID "+ innerObj.get("id") +

                        " type " + innerObj.get("type"));

            }

             

 

        } catch (FileNotFoundException ex) {

            ex.printStackTrace();

        } catch (IOException ex) {

            ex.printStackTrace();

        } catch (ParseException ex) {

            ex.printStackTrace();

        } catch (NullPointerException ex) {

            ex.printStackTrace();

        }

     }

 }

jsonDemoFile.json

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

{

    "id": 0001,

    "type": "donut",

    "name": "Cake",

    "ppu": 0.55,

    "batters":

        [

            { "id": 1001, "type": "Regular" },

            { "id": 1002, "type": "Chocolate" },

            { "id": 1003, "type": "Blueberry" },

            { "id": 1004, "type": "Devil's Food" }

        ],

    "topping":

        [

            { "id": 5001, "type": "None" },

            { "id": 5002, "type": "Glazed" },

            { "id": 5005, "type": "Sugar" },

            { "id": 5007, "type": "Powdered Sugar" },

            { "id": 5006, "type": "Chocolate with Sprinkles" },

            { "id": 5003, "type": "Chocolate" },

            { "id": 5004, "type": "Maple" }

        ]

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

The id is: 1

The type is: donut

The name is: Cake

The PPU is: 0.55

Batters:

ID 1001 type Regular

ID 1002 type Chocolate

ID 1003 type Blueberry

ID 1004 type Devil's Food

Topping:

ID 5001 type None

ID 5002 type Glazed

ID 5005 type Sugar

ID 5007 type Powdered Sugar

ID 5006 type Chocolate with Sprinkles

ID 5003 type Chocolate

ID 5004 type Maple

  • 簡單字元串查找

Java提供了一個庫函數叫做indexOf()。這個方法可以用在String對象上,它返回的是要查找的字元串所在的位置序號。如果查找不到則會返回-1。

  • 列出目錄下的文件

你可以用下麵的代碼來列出目錄下的文件。這個程式會遍歷某個目錄下的所有子目錄及文件,並存儲到一個數組裡,然後通過遍曆數組來列出所有文件。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import java.io.*;

 

public class ListContents {

    public static void main(String[] args) {

        File file = new File("//home//user//Documents/");

        String[] files = file.list();

 

        System.out.println("Listing contents of " + file.getPath());

        for(int i=0 ; i < files.length ; i++)

        {

            System.out.println(files[i]);

        }

    }

}

  • 一個簡單的IO程式

Java提供了FileInputStream以及FileOutputStream類來進行文件的讀寫操作。FileInputStream的構造方法會接收輸入文件的路徑作為入參然後創建出一個文件的輸入流。同樣的,FileOutputStream的構造方法也會接收一個文件路徑作為入參然後創建出文件的輸出流。在處理完文件之後,一個很重要的操作就是要記得”close”掉這些流。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

import java.io.*;

 

public class myIODemo {

    public static void main(String args[]) throws IOException {

        FileInputStream in = null;

        FileOutputStream out = null;

         

        try {

            in = new FileInputStream("//home//user//Documents//InputFile.txt");

            out = new FileOutputStream("//home//user//Documents//OutputFile.txt");

             

            int c;

            while((c = in.read()) != -1) {

                out.write(c);

            }

        } finally {

            if(in != null) {

                in.close();

            }

            if(out != null) {

                out.close();

            }

        }

    }

}

  • 在Java中執行某個shell命令

Java提供了Runtime類來執行shell命令。由於這些是外部的命令,因此異常處理就顯得異常重要。在下麵的例子中,我們將通過一個簡單的例子來演示一下。我們會在shell命令行中打開一個pdf文件。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

 

public class ShellCommandExec {

 

    public static void main(String[] args) {

        String gnomeOpenCommand = "gnome-open //home//user//Documents//MyDoc.pdf";

 

        try {

            Runtime rt = Runtime.getRuntime();

            Process processObj = rt.exec(gnomeOpenCommand);

 

            InputStream stdin = processObj.getErrorStream();

            InputStreamReader isr = new InputStreamReader(stdin);

            BufferedReader br = new BufferedReader(isr);

 

            String myoutput = "";

 

            while ((myoutput=br.readLine()) != null) {

                myoutput = myoutput+"\n";

            }

            System.out.println(myoutput);

        }

        catch (Exception e) {

            e.printStackTrace();

        }

    }

}

  • 使用正則

正則表達式的結構摘錄如下(來源: Oracle官網)

字元

x

字元x

\

反斜杠

\0n

8進位值為0n的字元(0<=n<=7)

\0nn

 

\0mnn

8進位值為0mnn的字元(0 <= m <= 3, 0<=n<=7)

\xhh

16進位值為0xhh的字元

\uhhhh

16進位值為0xhhhh的字元

\x{h…h}

16進位值為0xh…h的字元(Character.MINCODEPOINT <= 0xh…h <= Character.MAXCODEPOINT)

\t

製表符(‘\u0009′)

\n

換行符(‘\u000A’)

\r

回車(‘\u000D’)

\f

分頁符(‘\u000C’)

\a

警告符(‘\u0007′)

\e

ESC(‘\u001B’)

\cx

ctrl+x

字元分類

[abc]

a, b或c

[^abc]

abc以外的任意字元

[a-zA-Z]

a到z以及A到Z

[a-d[m-p]]

a到d或者m

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 什麼是正則表達式在電腦上我們經常會使用(通配符)找出我們需要的文件,例如:*.doc ,這裡的 * 代表匹配零個或多個字元。正則表達式也是用來進行文本匹配的工具,只不過它更加強悍。引用 PHP 手冊里的一句話:正則表達式是一個從左到右匹配目標字元串的模式,大多數字元自身就代表一個匹配 它們自身的模式...
  • Java中想要實現鍵值映射,可以通過Map介面來實現鍵值對的添加與訪問 Map keyValues = new HashMap(); keyValues.put(1, "1"); keyValues.put(2, "22"); keyVal...
  • 本文翻譯自modern effective C++,由於水平有限,故無法保證翻譯完全正確,歡迎指出錯誤。謝謝!矛盾的是,我們很容易就能創造出一個和std::shared_ptr類似的智能指針,但是,它們不參加被指向資源的共用所有權管理。換句話說,這是一個行為像std::shared_ptr,但卻不....
  • 1.fopen /file_get_contents 每次請求都會重新做DNS查詢,並不對 DNS信息進行緩存。但是CURL會自動對DNS信息進行緩存。對同一功能變數名稱下的網頁或者圖片的請求只需要一次DNS查詢。這大大減少了DNS查詢的次數。所以CURL的性能比fopen /file_get_conten...
  • vi a.go1 package main 2 import fmt "fmt" 3 func main(){ 4 fmt.Println("hello world") 5 }編譯: $ 6g a.go # 編譯; 輸出 a.6 $ 6l a.6 # 鏈接; 輸出 6.o...
  • 1. 安裝Nginx和Passenger(參考:https://www.phusionpassenger.com/library/install/nginx/install/oss/el6/)sudo yum install -y epel-release pygpgme curlsudo curl...
  • 題目:Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...