StackOverflow 第四周周報及19年就業情況分析


這是 Stack Overflow 第四周周報,兩篇 Java、兩篇 Python。公眾號「渡碼」為日更,歡迎關注。另外,我搜集了今年的就業數據,對招聘情況和崗位情況做了簡單總結,想了解的朋友點這里

DAY1. 枚舉對象 == 和 equals 區別

我們在比較枚舉常量時可以使用 == 運算符或者 equals 方法,如:

public class EnumEquals {

    public enum FRUITS  {
        /** 蘋果 */
        APPLE,
        /** 橙子 */
        ORANGE
    }public static void equalApple(FRUITS fruit) {
        if (fruit == FRUITS.APPLE) {
            System.out.println("equals");
        }
        if (fruit.equals(FRUITS.APPLE)) {
            System.out.println("equals");
        }
    }
}

先考慮第一個問題:為什么可以用 == 判斷枚舉常量相等?

我們都知道判斷對象的相等應該用 equals 方法,== 只是判斷對象的引用是否相等,枚舉常量能夠使用 == 判斷相等是因為枚舉常量除了定義時初始化的對象外,沒有其他實例。例如:常量 APPLE 在定義時已經初始化,並且運行時不會再有其他的 APPLE 枚舉常量。根據 JLS 文檔,Java 通過以下四點保證枚舉常量不存在定義之外的實例

  • 試圖顯式實例化枚舉類型是編譯時錯誤,例如:new FRUITS()
  • Enum 類中的 clone 方法確保永遠不能克隆Enum常量,看看 clone 方法可以看到直接拋出 CloneNotSupportedException 異常
  • 序列化機制的特殊處理確保不會因為反序列化而創建重復的實例
  • 禁止枚舉類型的反射實例化

因為枚舉常量只有一個實例,因此可以直接用 == 判斷枚舉實例的相等。如果我們看下 equals 源碼就可以發現它也是用 == 進行判斷,所以我們考慮第二個問題:使用 == 和 equals 的區別是什么?

  • == 不會拋出 NullPointerException 異常, 而 equals 會
  • == 的類型不匹配在編譯時檢查,而 equals 不檢查
public class EnumEquals {

    public enum FRUITS  {
        /** 蘋果 */
        APPLE,
        /** 橙子 */
        ORANGE
    }

    public enum SIZE {
        /***/
        SMALL,
        /***/
        MIDDLE,
        /***/
        LARGE
    }

    public static void main(String[] args) {
        FRUITS fruit = FRUITS.APPLE;
        fruit == SIZE.SMALL;
    }
}

因此使用 == 相比 equals 有以下優勢:

  • 更快
  • 運行時更安全
  • 編譯時更安全

參考:

https://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals

https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.9

DAY2. 用 Python 復制文件

我們都知道 Python 庫非常強大,通常我們想實現一個功能基本都找到現成的庫。今天我們就介紹 Python 標准庫中的一個模塊 —— shutil ,該模塊中定義了文件復制的方法。如:復制一個文件,直接調一個函數即可

src = '1.txt'
dst = '2.txt'

shutil.copyfile(src, dst)

除了該函數, shutil 模塊還定義了其他的函數提供文件復制的功能,但是細節略有不同,對比如下:

其中 copy2 復制的比較全面,估計性能也是比較低的。下面簡單舉兩個例子對比一下不同函數的區別。

1. 目的路徑是否是目錄,copyfile vs copy2

src = 'test.rar'
dst = 'D:\\'

shutil.copyfile(src, dst)
shutil.copy2(src, dst)

2. 是否能復制 meta 數據,copyfile vs copy2

src = 'test.rar'
dst = 'test1.rar'

shutil.copyfile(src, dst)
shutil.copy2(src, dst)

查看文件的 meta 信息,copyfile 復制的文件的更新時間是最新的, 而 copy2 復制的文件更新時間與源文件一樣。

這里只舉這兩個例子,如對其他函數感興趣可自行嘗試。另外,shutil 模塊應該還有其他更方便的函數可以供我們使用。總之使用 Python 開發效率還是挺高的,掌握 Python 確實能提高工作效率。

參考:

https://stackoverflow.com/questions/123198/how-do-i-copy-a-file-in-python

DAY3. 什么是 Java Bean

從學 Java web 開發起,我們就知道有 Java Bean 這個東西。但對於我來說,因為我畢業后一直做大數據,講真我確實不知道 Java Bean 的正式定義。下面我們一起看看符合什么要求才叫 Java Bean :
  • 所有的屬性是 private,提供 getter 和 setter 設置屬性
  • 有一個 public 無參構造函數
  • 實現 Serializable 接口

Java Bean 其實是一種規范。對於我們學知識來說,往往想問為什么 Java Bean 定義這樣的規范。對照上面三點,我的思考是這樣的:

  • getter/setter 方法為了對外暴露屬性的讀寫接口,方便框架調用。同時,屬性用 private 修飾可以提高安全性
  • 之前的文章看過 Hadoop 框架反射的例子, public 無參構造可以很方便框架通過反射創建類實例
  • 由於 web 框架通常需要數據傳輸,因此需要對象具有序列化與反序列化的能力

我們今天這篇文章比較簡短,只是簡單介紹了一下 Java Bean 規范的定義,並且談了談我自己的一些思考。

參考:

https://stackoverflow.com/questions/3295496/what-is-a-javabean-exactly

DAY3. Python 中實現 switch 語句

 我們都知道 Python 原生語法中不支持 switch 語句。當然 Python 這么靈活的語法,我們自己實現一個也比較容易。代碼如下:

def f(x):
  return {
      'a': 1,
      'b': 2,
  }[x]

這樣實現稍微有些不完備,沒有默認值,且如果參數不在字典中會報錯。我們更新一版如下:

def f(x):
  return {
      'a': 1,
      'b': 2
  }.get(x, 9)

這樣實現看起來比較理想了,我們還可以用 Lambda 表達式實現復雜計算,例如:

def f3(x):
  return {
      'a': lambda x: x * 5,
      'b': lambda x: x + 7,
      'c': lambda x: x - 2
  }.get(x, lambda x: x)

用 Python 實現 switch 語句還是非常方便的。
猜測 Python 原生之所以不支持 switch 語法是因為 Python 語言本身已經很靈活了,不需要額外提供 switch 語句增加語言本身的臃腫。真是應了那句話,人生苦短,我用 Python

以上便是 Stack Overflow 的第四周周報,希望對你有用,后續會繼續更新,如果想看日更內容歡迎關注公眾號。

公眾號「渡碼」,回復 就業 查看各平台完整的分析報告,分享更多高質量內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM