復聯4中滅霸一個響指能夠隨機消滅一半生命,Github 上的滅霸腳本能夠隨機刪除一半服務器文件。我在想怎麼作到隨機刪除一半的文件呢??隨機算法的底層怎麼實現的?這兩天抽時間整理了答案。html
let "i=`find . -type f | wc -l`/2";
if [[ uname=="Darwin" ]]; then
find . -not -name "Thanos.sh" -type f -print0 | gshuf -z -n $i | xargs -0 -- cat;
else
find . -not -name "Thanos.sh" -type f -print0 | shuf -z -n $i | xargs -0 -- cat;
fi
複製代碼
爲了完全讀懂這段腳本,特地查了幾個關鍵字let、find、shuf/gshuf、xargs。linux
大體解釋下,let "i=`find . -type f | wc -l`/2";
將i賦值爲服務器普通文件行數的一半。git
if [[ uname=="Darwin" ]]
應該是用來判斷系統是 Mac or Linux 的,Linux 用 shuf
作隨機,Mac 用 gshuf
。github
find . -not -name "Thanos.sh" -type f -print0 | gshuf -z -n $i | xargs -0 -- cat;
找到全部名稱不是 Thanos.sh
的普通文件,隨機選取 $i
個,並將這些做爲參數執行 cat
操做,真正刪除將 cat
改成 rm
便可。算法
例如獲取 [0,100) 區間的隨機數。服務器
final long l = System.currentTimeMillis();
final int i = (int) (l % 100);
複製代碼
例如獲取 int 的隨機數。微信
final double d = Math.random();
final int i = (int) (d*100);
複製代碼
我看了 Math.random()
的源碼,也是調用 Random
類的方法。dom
// Math.random() 實現
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
// RandomNumberGeneratorHolder 實際上是 Random 類
private static final class RandomNumberGeneratorHolder {
static final Random randomNumberGenerator = new Random();
}
// nextDouble() 方法在 Random 類中的實現
public double nextDouble() {
return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
}
複製代碼
Random
類提供賊多隨機方法,返回的類型不一樣,提供兩個構造器。ide
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
複製代碼
方法的話,看一下方法名就知道幹啥了的吧。 ui
源碼看得挺困難,網上找的資料表示 Random 的隨機算法有一下特色:
算法用到了線性同餘方程。下期我學完後整理下資料,分享出來。
隨機數算法都是僞隨機數,從參數傳入的那一刻,之後的輸出是特定的了。目前產生真隨機數的是這個東東。
龜龜,用到量子力學了。我也只看了點皮毛,當課外知識擴展吧。
emmm,有興趣的推薦看汪潔老師講的課,我以爲他對物理這塊科普的挺好的,還包括相對論、天文、外星人等等
歡迎關注微信公衆號,提供感悟和技術文章,偶爾抽獎,期待和你一塊兒進步。微信搜索小兵張健或掃描如下二維碼。