Recent Posts

琴音's avatar

Awakening#?? 2019/3/21

这是一篇受密码保护的文章,您需要提供访问密码:

icebound's avatar

英语

When I just a kid, I was fear of the outside world, esp […]
Molunerfinn's avatar

Electron-vue开发实战6——开发插件系统之GUI部分

前言

前段时间,我用electron-vue开发了一款跨平台(目前支持主流三大桌面操作系统)的免费开源的图床上传应用——PicGo,在开发过程中踩了不少的坑,不仅来自应用的业务逻辑本身,也来自electron本身。在开发这个应用过程中,我学了不少的东西。因为我也是从0开始学习electron,所以很多经历应该也能给初学、想学electron开发的同学们一些启发和指示。故而写一份Electron的开发实战经历,用最贴近实际工程项目开发的角度来阐述。希望能帮助到大家。

预计将会从几篇系列文章或方面来展开:

  1. electron-vue入门
  2. Main进程和Renderer进程的简单开发
  3. 引入基于Lodash的JSON database——lowdb
  4. 跨平台的一些兼容措施
  5. 通过CI发布以及更新的方式
  6. 开发插件系统——CLI部分
  7. 开发插件系统——GUI部分
  8. 想到再写…

说明

PicGo是采用electron-vue开发的,所以如果你会vue,那么跟着一起来学习将会比较快。如果你的技术栈是其他的诸如reactangular,那么纯按照本教程虽然在render端(可以理解为页面)的构建可能学习到的东西不多,不过在main端(Electron的主进程)应该还是能学习到相应的知识的。

如果之前的文章没阅读的朋友可以先从之前的文章跟着看。并且如果没有看过前一篇CLI插件系统构建的朋友,需要先行阅读,本文涉及到的部分内容来自上一篇文章。

问少's avatar

使用 GPG 签名你的 Commits

本文最后更新于 2019年3月15日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

准备工作

首先要安装好 GPG 工具。

1
$ brew install gnupg gnupg2 pinentry-mac

配置使用环境。

1
2
3
4
5
6
$ test -r ~/.bash_profile && echo 'export GPG_TTY=$(tty)' >> ~/.bash_profile
$ echo 'export GPG_TTY=$(tty)' >> ~/.profile

$ echo "pinentry-program /usr/local/bin/pinentry-mac" >> ~/.gnupg/gpg-agent.conf

$ killall gpg-agent

检查现有的 GPG 秘钥

1
$ gpg --list-secret-keys --keyid-format LONG

如果没有返回值,则说明此电脑上没有配置 GPG 秘钥。
如果有,则可以跳过生成 GPG 秘钥的步骤。

生成一个新的 GPG 秘钥

1
$ gpg --full-generate-key

第一步,选择加密类型,可以直接回车选择默认的 RSA and RSA
第二步,输入秘钥的强度,推荐输入 4096
第三步,选择秘钥的过期时间,嫌麻烦的同学可以直接回车选择默认的永不过期。
第四步,确认一下以上信息有没有错。
第五步,输入你的名字。
第六步,输入你的邮箱,注意此邮箱需要是你的 Github 账号中添加过的邮箱。
第七步,设置此秘钥的密码,使用此秘钥需要用这个密码来解密。
之后稍等片刻,GPG 秘钥即生成完毕。

使用 GPG 秘钥

在终端中使用 gpg --list-secret-keys --keyid-format LONG 命令查看当前秘钥的信息。

1
2
3
4
5
6
$ gpg --list-secret-keys --keyid-format LONG
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec 4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid Hubot
ssb 4096R/42B317FD4BA89E7A 2016-03-10

在这里 3AA5C34371567BD2 就是秘钥的 ID

使用以下命令来获得 GPG 秘钥的公钥,注意 <ID> 需要替换为自己秘钥的 ID。

1
$ gpg --armor --export <ID>

复制以上公钥,去往 Github 账户设置页面即可添加 GPG 秘钥。

接着使用以下命令配置 git 以使用 GPG 秘钥。

1
2
3
$ git config --global user.signingkey <ID>
$ git config --global commit.gpgsign true
$ git config --global gpg.program gpg

带有 GPG 验证的 commit 只是多了 -S 参数。

1
$ git commit -S -m "your commit message"

验证

在提交改动之后,可以使用以下命令来检验以下是否成功使用 GPG 秘钥来签名 commit。

1
$ git log --show-signature -1

若带有下面的提示,则说明成功。

1
gpg: Good signature from "Your Name <[email protected]>"

问少's avatar

Ubuntu 18.04 配置开机启动项

本文最后更新于 2019年3月14日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

在 Ubuntu 16.04 版本中,配置开机启动项是一件很简单的事情,只需在 /etc/rc.local 中添加即可。

但在 Ubuntu 18.04 中,此方法失效。经搜索实践,总结了一下较为简单的设置开机启动项的方法。

首先运行

1
$ crontab -e

之后可能会出现以下提示

1
2
3
4
5
6
7
8
9
no crontab for neo - using an empty one

Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed

Choose 1-4 [1]:

推荐选 1。

在末尾添加新的一行

1
@reboot /path/to/your/boot.sh

之后把开机启动命令都写在 /path/to/your/boot.sh 这个文件里。

最后别忘了给文件加上可执行属性

1
$ chmod +x /path/to/your/boot.sh

此时重启即可看到效果。

问少's avatar

最强日期正则表达式

简单的日期判断(YYYY/MM/DD)

1
^\d{4}(\-|\/|\.)\d{1,2}\1\d{1,2}$

演化的日期判断(YYYY/MM/DD| YY/MM/DD)

1
^(^(\d{4}|\d{2})(\-|\/|\.)\d{1,2}\3\d{1,2}$)|(^\d{4}年\d{1,2}月\d{1,2}日$)$

加入闰年的判断

1
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
櫻川 浅羽's avatar

SONY SmartWatch 3 更換錶帶 SWR510 與翻新作業

淺羽的 SmartWatch 3 從 2015 年 4 月開始,也已經戴了有四年了。其實淺羽一直想換新的 Android Wear,但苦於難以找到功能齊全、好看又能長續航的錶,選來選取竟然都不滿意。平心而論,SmartWatch 3 雖然已經不再有系統更新,而且外觀太偏運動了一些,確實有些落伍了;但是它在四年的使用後還能有約兩個整天的續航,並且還有獨一無二的半透半反式液晶熒幕的設計,雖然色彩效果一般,但在強烈陽光下靠反射光線,保證可用性的同時也很有復古電子錶的味道,讓淺羽很是喜歡。不過指望索尼粑粑出下一代產品不太現實:不說遙遙無期,有沒有首先就是一個問題。所以淺羽選擇了一個簡單的解決方法:更換錶帶。

SmartWatch 3 畢竟已經很老了,雖然官方有出專用的替換錶帶 SWR510,但市面上幾乎只有熒光黃色售賣,而粉色卻很難找到。淺羽也是費了不少力氣,經過一個多月才訂購到一隻粉紅色錶帶。這錶帶沒有包裝,但是一看就知道是索尼自己出品,和原裝的黑色錶帶的風格可謂是一脈相承。大法家一貫以色調作爲賣點,這次的粉紅色款 SWR510 依然是顯眼的熒光色。

這款錶帶上的鎖釦倒是頗有亮點:中間有一條鑿空槽,錶帶的長度是可以無極調節的,很好地解決了原配錶帶三格略緊、四格太鬆的問題。相信很多戴電子錶的孩子都知道淺羽在說什麼(笑)。

順便把貼膜翻新一下,這隻 SmartWatch 3 勉強就可以當作新錶戴了。只不過防水塞已經快斷裂了,要仔細保管才是。

琴音's avatar

无题#?(Password:Villagers’ Home)

这是一篇受密码保护的文章,您需要提供访问密码:

问少's avatar

macOS 下的包管理器 Homebrew

本文最后更新于 2019年3月8日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

介绍

之前使用 Ubuntu 和 CentOS 的时候,它们都各自拥有便捷的包管理器 APTYUM,使用它们安装卸载软件,自动解决依赖问题,非常方便。最近在换用 macOS 系统之后,却没有了类似的管理器,安装软件又回到了和 Windows 一样的体验。虽说 App Store 拥有一些很优秀的软件,但是作为一个未来的码农,需要的很多软件并没有 App Store 版,如果手动下载安装,以后软件更新了还需要再下载安装一次,这些无意义的重复劳动需要解决掉。

早在换 Mac 之前就听说过了 Homebrew 的名字,它自己的介绍就是 The missing package manager for macOS (or Linux),很厉害的一个项目,方便实用。它的野心不小,不满足于 macOS 系统,还将支持扩展到了 Linux 发行版系统上,甚至还支持在 WSL 中使用。

安装

安装非常简单,终端中一行命令即可完成。

1
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

使用

搜索软件

Homebrew 中搜索软件很很简单。

1
$ brew search chrome


如上图可以看到,我搜索 Chrome 的结果。搜索结果有两部分,FormulaeCasks,前者指命令行工具,后者指图形化程序。

如果想查询相关程序的信息,可以使用以下命令,对于 Formulae 程序

1
$ brew info chrome-cli


对于 Casks 程序

1
$ brew cask info google-chrome

安装软件

在知道程序准确名称之后,可以使用以下命令安装,对于 Formulae 程序

1
$ brew install chrome-cli

对于 Casks 程序

1
$ brew cask install google-chrome

卸载软件

卸载软件同样很简单,对于 Formulae 程序

1
$ brew uninstall chrome-cli

对于 Casks 程序

1
$ brew cask uninstall google-chrome

升级软件

更新软件源和 Homebrew 本身。

1
$ brew update

列出没有更新到最新版本的 Formulae 程序。

1
$ brew outdated

更新所有 Formulae 程序,

1
$ brew upgrade


或者更新特定 Formulae 程序。

1
$ brew upgrade node

对于 Casks 程序来说,更新并没有如此简单,不过可以使用一个小插件来使之简化。

1
$ brew tap buo/cask-upgrade

之后,只需运行以下命令即可检查 Casks 程序的更新。

1
$ brew cu

默认不会检查带有自动更新功能的程序,不过我想要的是让它检查,帮我更新,只需添加一个参数即可。

1
$ brew cu -a

问少's avatar

macOS 下 Android 平台工具的 PATH 配置

本文最后更新于 2019年3月7日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

在安装了 Android Studio 之后,相关的 adb fastboot 等工具应该都应经下载在电脑里了。但是 AS 并没有把相关的目录加入 PATH,导致在终端里不可以方便的直接使用,需要加上很长的一串路径才可可以。这个文章记录下解决的办法。

编辑 BASH 的配置文件

1
$ nano ~/.bash_profile

在文件最后追加几行

1
2
3
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH="$PATH:$ANDROID_HOME/platform-tools"
export PATH="$PATH:$ANDROID_HOME/tools"

macOS 下的默认 ANDROID_HOME 位置就是如上配置,无需修改,其他系统下的路径需要根据实际情况修改。

之后再使刚改好的配置生效,或者重新打开终端。

1
$ source ~/.bash_profile

配置好后的效果如下图。

问少's avatar

去除 Next 主题图片的灰色边框

本文最后更新于 2019年3月6日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

最近发了篇文章,带了些截图,发现对于 macOS 处理过的截图,Next 主题在图片周围加一圈灰色边框并不美观。

于是便想办法去掉它。打开浏览器检查图片样式,发现图片周围加了一圈一个像素宽度的灰色边框。

打开 Hexo 博客目录,直接搜索整个目录,果然在 themes/next/source/css/_common/components/post/post-expand.styl 这个文件里找到了配置。

只需将以下代码

1
2
3
4
5
6
img {
box-sizing: border-box;
margin: 0 auto 25px;
padding: 3px;
border: 1px solid $gray-lighter;
}

改为

1
2
3
4
5
6
img {
box-sizing: border-box;
margin: 0 auto 25px;
padding: 3px;
border: none;
}

即可去除边框。

去除边框之后的效果,看起来舒服多了。

最后记得一点,一定要先执行 hexo clean 再部署,否则样式表文件并不会更新导致修改不生效。

问少's avatar

创建 Localhost 证书

本文最后更新于 2019年3月5日 可能会因为没有更新而失效。如已失效或需要修正,请留言!

有时因为开发的需求,需要为本地的网页服务器设置 https 访问。在这里记录一下在 macOS 系统下快速创建自签名证书并设置可信的方法。

Xcode Command Line Tools

基本所有在 macOS 中开发的人应该都已经安装过了命令行工具,在终端中一句命令即可安装。

1
$ xcode-select --install

生成证书

在终端里运行以下命令即可在用户目录里生成证书和秘钥。

1
2
3
4
$ openssl req -x509 -days 3650 -out localhost.crt -keyout localhost.key \
-newkey rsa:2048 -nodes -sha256 \
-subj '/CN=localhost' -extensions EXT -config <( \
printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")

其中 -days 3650 参数是指定证书的有效时间为 3650 天。

设置信任

最后,需要在系统中设置信任,否则直接使用仍会提示不信任。

直接搜索打开“钥匙串访问”,“文件” - “导入项目” - 选择刚生成的 crt 文件。

双击打开刚导入的证书,设置“使用此证书时:始终信任”。

效果如下图。

櫻川 浅羽's avatar

略微難受的 Tilted 體感遊戲控制器外設開箱與動手玩

在不少 FPS 遊戲中,左右擺頭基本上是一個標配動作了。雖然大部分遊戲預設有對應的 Q、E 按鍵做出擺頭動作,但淺羽在玩遊戲時還是經常因爲太投入而做出真正的頭部動作。那麼有沒有什麼辦法把現實中的東西反映到遊戲裏呢?淺羽原先想的是通過攝像頭進行面部識別然後做出對應的動作,但國內的一家公司給出了一個更直接的方案:體感遊戲控制器。

Tilted 這款產品應該是國內團隊推出的(半成品),並在京東衆籌上有發售,提供「膚質黑」、「膚質白」雙色。不過,他們同時也在國外銷售,並且多提供一種「閃耀白」配色,但價格也比國內衆籌高出不少。考慮到黑色配上綠燈太過於雷蛇炫酷,淺羽還是選擇了膚質白配色。

英文網站提供三種配色

參加衆籌約兩個月後,淺羽突然收到了一個快遞,拆開才知道是幾乎已經被忘記了 Tilted。快遞盒子很小,內容除了塑封的 Tilted 包裝盒之外還有一份幾頁的說明書。塑封上有一個防止窒息的小孔,這倒是一個意外的細節。

包裝內除了 Tilted 本身,還有魔術貼帶用來固定 Tilted、不乾膠磁鐵、USB 無線接收器和一條極短的 Micro USB 線纜。Tilted 本身也不大,接縫處很明顯,但整體做工尚可;機身上只有一個按鈕、一圈燈號和一個 Micro USB 接口,沒有使用 Type-C 接口是一個大遺憾。

不乾膠磁鐵和右側的魔術貼帶磁鐵

包裝內配有兩塊帶磁鐵的配件:左側的不乾膠磁鐵和右側的魔術貼帶磁鐵。它們的作用都是將 Tilted 本體固定在頭上(耳機上)。根據說明書解釋,Tilted 本身是一套加速度感測器械,根據不同的情況會以鍵盤按鍵的方式傳送指定按鍵;Tilted 只有在吸附上磁鐵的情況下才會傳送按鍵訊號。

Tilted 出場的時候就預設了一套方案,拿到插好接收器即可使用。不過淺羽爲了調整設定、一探究竟,還是按照說明書安裝好驅動。驅動下載頁面是一個純英文的頁面,並且只提供 Windows 版本;考慮到 Windows 作業系統是遊戲 PC 的大主流,這倒也說得過去。然而安裝介面和主介面在 Hi-DPI 下錯位、英文翻譯錯誤百出,直接減去了淺羽的不少印象分。

  • 錯位
  • 首字母未大寫
  • 支離破碎的英文

進入驅動程式後,淺羽摸索了一下,在設定裏可以更改語言爲中文——然而只有簡體中文,沒有繁體中文。淺羽將 Tilted 開機,並且打開驅動程式,但是只看到「正在連接中…」的提示;後來才反應過來,需要用 Micro USB 線纜將 Tilted 與電腦連接,驅動才能抓到裝置使用接收器的情況下,Tilted 與雜牌無線鍵鼠無異,不能使用驅動程式操作。淺羽無法確認這樣的設計是否爲了防止遊戲認爲 Tilted 是作弊硬體;但 Logitech、Razer 等大廠均可以在無線狀態下連接驅動,這樣的理由其實並不足以作爲藉口

使用 Micro USB 線纜連接電腦後發出綠光的 Tilted

好不容易連接上之後,驅動程式終於展示出了唯一的功能介面。這個介面相當簡單,只能夠針對六個方向的持續加速度和兩個方向的瞬時加速度調整功能。爲了儘可能地減少誤操作,淺羽只設定了三個動作:左偏頭爲 Q、右偏頭爲 E、向前俯身爲 Shift。

  • 依然錯位的介面
  • 預設按鍵方案
  • 淺羽修改過的方案

然而在開始測試之前,淺羽就犯了難:雖然有頭戴式耳機,但是淺羽平時並不習慣使用它玩遊戲。一番糾結之後,淺羽做出了一個艱難的決定:把 Tilted 當作頭飾佩戴……好在,按照宣傳,Tilted 本身只有 15g 重,所以配合魔術貼戴在頭上,倒也不會覺得太重,而且也不會輕易掉下。

  • 淺羽的新頭飾好看嗎?
  • 好看嗎好看嗎?

在遊戲中,淺羽有意只使用 Tilted 控制偏頭動作,並讓手指只集中在走動控制上。然而,Tilted 的反饋非常詭異:有的時候,即使淺羽沒有東西,Tilted 也會傳送指令讓遊戲內的人物偏頭;有時即使淺羽佷用力地偏頭,Tilted 也並不認爲淺羽想要做出偏頭的動作……按照說明書內的操作校準後,Titled 依然我行我素。最終還是只能放棄。

以淺羽的簡單試用看,Tilted 並不是一個有用且好用的外設,起碼目前的階段來看不是。它的功能相對簡單,但即使如此也並沒有做出好的、容易學習和利用的體驗。Tilted 的外觀設計尚可、硬體本身也過關,同時有吸引人類的賣點;但它在驅動程式、調教等細節方面的考慮,堪稱應付了事。加上有反饋說「點擊驅動程式的固件修復後無法開機」「撥打售後電話關機」等問題,它的客戶服務幾乎等於沒有,無論是無心之過還是有意爲之,都極大地壓縮了 Titled 的價值

Roy Binux's avatar

Zerotier Nat 网关出口 和 iptables 调试

每当看到各类教程中的 iptables 指令,在格式参数组合之下可以实现从防火墙,封禁 IP 端口到 NAT 的各种操作,就如同魔法一般,看不明白,却又感到无比强大。想学,但又好像不得要领,稍微不慎可能就再也连不上了。最近配置 Zerotier 的 Nat 网关的时候,看着

櫻川 浅羽's avatar

新年印象:深圳

闊別深圳居然也已經好幾年了,雖然一直遠離,但從小有超過一半時間在深圳、另一半時間也在一河之隔的香港的淺羽,對這裏的感情當然很濃厚。即使深圳已經不能稱之爲家,但是一旦有機會,還是往深圳靠近,彷彿這樣可以找到什麼安慰或者寄託似的。其實這次回來,計劃的行程本來就短,所以只是約飯或者辦事情的時候順便路過,可以看看變化。不過,後來因爲和家裏吵架,居然意外有兩天晚上,可以慢慢地、好好地逛逛這座城市淺羽最熟悉、最愛的一小部分,也算是一點點開心和幸運的事情。
问少's avatar

修复 Ubuntu 下拼音输入法崩溃问题

最近在使用 Ubuntu 18.04 的过程中,遇到了一个拼音输入法总是在选字的时候崩溃的问题。

崩溃表现

crashed with SIGABRT in __assert_fail_base()

具体表现为:在打字时,无法使用数字键选择字词,鼠标点选也无效,只能按空格打出第一个字词。当按数字键选择字词时,输入法会崩溃,并输出字母和数字,例如我想打出“谷歌”,“谷歌”在候选列表第二个位置,按下 2,输入法崩溃,输出 guge2

我搜索了一下,并没有找到解决办法,只好退而求其次,使用 fcitx 代替了 ibus,就这么过了半个月。然而我今天再次搜索的时候竟然找到了解决办法:Selecting a number does not always return a Chinese character with ibus pinyin

解决办法

直接删除输入法的缓存就好:rm ~/.cache/ibus/libpinyin/*

赵坤's avatar

RocketMQ 主备同步

介绍 RocketMQ 的主备同步机制 !

櫻川 浅羽's avatar

用客製化超低款 TrackPoint Caps 改善新 ThinkPad 上的小紅點手感

讀過淺羽之前的 ThinkPad X1 Carbon Gen 6 開箱,或者實際用過這款筆電的人類應該都知道,新的 ThinkPad X1 Carbon 上的 TrackPoint 手感有多差:相比起之前的流暢省力,新款不僅沒有繼承優點,還變得更硬、更難以操作。同時,新的 ThinkPad 只配備一種款式的 TrackPoint Cap。而 @Saoto28 大顯然也發現了同樣的問題,並且提出了一款 SoftRim Type Super Low Profile TrackPoint Caps 用來解決手感問題。

這個解決方案是 Plum 在《使用 TrackPoint Cap 来优化你的小红点手感》一文中提到的,而 Plum 也是在 Alex Lu 的《[en] Notes on Thinkpad X1 Carbon 2017 + Arch Linux》文中發現的。原作者有給出 CAD 資料供大家自行 3D 打印用,不過同時也售賣打印成品,並且有多種顏色選擇。淺羽畢竟還是懶,所以直接購買了一對紅色和一對白色的打印成品。

賣家會直接把成品平郵送出,所以收到也就是一個小信封,上面貼了一張 JPY 120 的郵票。不過付款的時候需要付 JPY 300 的郵費,也許是還需要付 3D 打印的郵費。從日本寄到中國的平郵還挺快的,淺羽只用了 10 天就收到了。不過平郵最大的缺點就是送達是沒有提醒的,好在前臺小姐姐很上心,淺羽抱怨過平郵沒有提醒這件事之後,人家就一直幫淺羽留意信件;結果恰巧當天上午抱怨的,下午就送到了。

  • 平郵信件(略有磨損)
  • 說明內頁(略有磨損)

信封裏面除了用密封袋包裝、泡沫紙保護的小可愛們,還有比本體顯眼得多的一頁發貨單兼說明文件。文件上給出了一個設計剖面圖。由於最近的幾代 ThinkPad 對 TrackPoint 做了剝削改進,爲了輕薄而壓低了其高度並且減小了元件體積。因此這款 TrackPad Cap 只適用在部分筆電上。淺羽還有一把 USB 的 ThinkPad Compact Keyboard,同樣也是不適用的;但是它本身的 TrackPoint 手感倒是比 ThinkPad X1 Carbon Gen 6 好得多。

  • 透光性不錯
  • 表面有一些不太明顯的顆粒
  • 跟舊款的指點桿帽相比矮很多
  • 跟舊款的指點桿帽相比開口更小
  • 自製和新舊世代開口對比
  • 自製和新舊世代高度對比

更換過程與更換普通的指點桿帽配件無異,直接暴力拔出來再插進去即可。安裝好之後,指點桿帽佔用的面積會比原裝的稍大一些,不過並不會溢出設計的區域以至於影響周圍鍵盤使用。高度上則是比原裝的指點桿帽更矮。至於手感呢?由於佔用的面積更大,而且整體是 Soft-rim 設計,是向下凹陷的,所以和手指的接觸面積更大了。同時,雖然作者選用了最硬的塑膠進行 3D 打印,但是本身還是比原裝的指點桿帽更軟、彈性略大,可操作的範圍也更大。

簡單來說:小紅點復活了!

  • 面積比原版更大些
  • 高度則比原版更矮

另外,Lenovo 的這一代 TrackPoint 似乎是天怒人怨,類似的項目還有不少,比如說:

雖然淺羽對 @Saoto28 大的版本已經相當滿意了,但如果有閒錢的話,大概會多買幾種進行嘗試的。

另外,是的,這次拍攝的背景也是從 Plum 那裏學習的。

櫻川 浅羽's avatar

黑莓 Blackberry ACC-60407-001 模組化同步 Dock 開箱

淺羽有一臺紅色的 Blackberry Passport,用來看郵件和消息很方便。不過大部分時候,它的任務是在桌面上當作時鐘和消息提醒,並且保持電量充足、隨時待命。之前一直是用一個可愛的手機桌面支架加上彎頭 USB 線纜做的土製 Dock,不過拜 Blackberry 在消費市場的節節敗退所賜,相關的配件基本都按照垃圾賣了,所以乾脆就入手了一款原裝底座。

根據賣家說明,底座有搭配 Passport、Classic 和 Priv 的款式,都是統一 CNY 88 的售價,淺羽當然根據自己的機型選擇 Passport 款。

全新的包裝

拿到盒子之後發現是有封貼的,果然配件都當作垃圾賣了。正面有標註適用機型和底座功能。背面用多國語言介紹了產品的主要特點:精心設計、攜帶方便、與原廠保護套和保護殼相容。可惜淺羽的 Blackberry Passport 一直都是裸奔的,更別提原廠保護了。

包裝雖然不大,內容卻不少,一共有產品介紹卡一張、文檔一份、底座本體和兩個小部件。底座本體比較簡單,前方有一個朝上的男孩子 Micro USB,正後方則是一個女孩子 Micro USB。本體的主要部分全都是鏡面處理的塑料,非常容易吸指紋,並且也容易劃傷。

除掉底座本體,還有底座槽和一個小支架需要合體。根據淺羽推測,小支架在使用原廠保護套的情況下是不需要安裝的,如果像淺羽一樣沒有任何保護,就需要安裝小支架幫助穩固手機。小支架需要滑動到底座槽的卡扣中,而安裝底座槽就比較簡單暴力,直接按進去就可以了。另外可以看到,淺羽在安裝的過程中,爲了拍照用軟布擦拭了一下,就已經製造了無數劃痕……

  • 明明晃晃的 Silver Edition
  • 合體之後的模樣
  • 側面可以看到小支架的作用
底座槽下也有類似滑軌的結構,但並不是滑動安裝的

然後接上 Micro USB,直接把 Passport 插上去,就可以看到充電狀態啦。雖然這個底座其實大部分結構都是在佔空間,而且安裝上去之後對手機的固定不好、手機甚至還能左右擺動,但是總算是有了亮閃閃的官方配件呢。

  • 造型還是很漂亮的
  • 兩個 Blackberry Logo 合影
  • 原樣擺回小桌板上
櫻川 浅羽's avatar

Studiologic SL88 Grand 編輯預設、更新 1.7.0 韌體及修復踏板問題

Studiologic SL88 Grand 的手感真是極好的,然而這句話只覆蓋了琴鍵,也許勉強還能加上控制桿。硬邦邦的五向導航編碼器加上三個同樣硬邦邦的按鈕,說好聽了叫做確認感很強,實際上配合雖然細膩而且有彩色但是並不很大的熒幕,想要仔細編輯預設還是很吃力。說到底,直接在 MIDI 鍵盤上編輯預設的能力,可能更多是廠家在表達一種「你可以不用,我不能沒有」的態度,當然也有更多的廠家無恥地取消了不配合 PC 獨立使用鍵盤的能力……

Studiologic 官方提供了編輯和備份旗下 MIDI 鍵盤(其實現時在售的也就 SL 一個系列)的軟體 SL Editor,不過同大多數同類一樣,它只提供了 Windows 和 Mac 版本。那也沒辦法,裝一個虛擬機吧。然後按照官方說明書,把 USB 裝置連接進去,就可以正常工作了。需要注意的是,淺羽安裝的是 Windows 7 並且保持 UAC 開啓,這種情況下 SL Editor 需要「以管理員身份運行」才可以正常地與鍵盤連接上。

SL Editor 可以編輯也可以直接控制 MIDI 鍵盤的預設

SL Editor 雖然叫做編輯器,其實同時也有更新固件的功能。淺羽的這臺 SL88 Grand 還是老舊的 1.5.2 系統,看了一下官方已經給出了 1.7.0 系統,主要是增加了 SL Mixface 控制器的支援。想想這款控制器還蠻有意思的,而且還支援藍芽,後續可能會入手,所以順帶更新一下系統。更新的過程並不難,完全按照官方說明,按住「IN」鍵並且開機,鍵盤就會自動進入韌體更新模式;緊接着在 SL Editor 中選擇新的系統檔案,點擊更新即可。不過淺羽偷了個小懶,直接用電腦的 USB 供電而沒有依循官方指示接外置 9V 電源,似乎也沒有問題。

介面看着有種工業風格
韌體更新似乎是獨立運行的有救磚可能性

更新完成之後直接重啓,發現介面的右上角多了一個 SL Mixface 的小圖示,並且可以直接用編碼器切換它的預設集,非常方便並且大大增強了淺羽的購買慾望。隨手彈了幾個和絃,確認一切工作正常,結果突然發現踏板不能用了。遇到這種事情,第一個懷疑的肯定是 Preset 設定了。進入 Preset 設定看,結果發現 PEDAL 1 和 PEDAL 2 兩個選項都是灰色的,無法選擇。求助了 Google,搜尋到 Studiologic SL88 damper pedal issue 這篇帖子,發現其實是更新之後系統預設把 PEDAL 1 / 2 的功能設定爲切換預設集和組了,只要去「Global Settings」把「Programs +/-」設定成「-」就解決問題了。

既然安裝 SL Editor 的初衷是爲了製作預設,淺羽就順帶分享一下預設的音色分配情況。SL 系列每個預設集可以分 4 個區域,指定到任意通道和音高。淺羽主要是設定一個常用音色組和一個管風琴組。常用音色組爲聲學鋼琴、電鋼琴、聲學吉他和絃樂合奏,分別輸出到 MIDI Port 1 的 4 個 MIDI Channel 上,方便做切換或者快速 Lead + Pad 的組合。管風琴組爲:

  • Channel 1/2 是 Solo 音色,放在另一臺琴上,可以快速切換音色;
  • Channel 3 是 UPPER;
  • Channel 4 是 Lower,並且在 SL 上做了一個高低音鍵區的 Split;
  • Channel 5 是 Bass,需要的時候再打開;
  • Channel 6 預留作爲腳鍵盤的輸入。

這樣如果淺羽再額外購買 MIDI 腳鍵盤,就可以在家裏練習管風琴了。豈不美哉。

櫻川 浅羽's avatar

飛傲 FiiO BTR3 幸運紅色開箱

WH-1000XM3 雖然好,但是頭戴式的耳機總有不如普通的掛耳方便的時候。這種時候,SBH-56 接創新 Air 是很好的一個補充了。停工前一天,淺羽正在用 SBH-56 打視訊,本來也是相安無事,但爪欠看了一下 a2dp_codec 發現協議是 SBC。想想之前說多添置一臺藍牙接收器,原先只是說看看 BTR3 的價格,年後再買;但官方本來只有黑色款,最近卻追加了幸運紅色,紅黑配色的金屬搭配玻璃成爲了最後一根稻草。下單、付款行雲流水;順豐的小哥也是馬不停蹄地,趕在年二十九把包裹送到了淺羽這邊。
icebound's avatar

最菜爬虫-模拟登陆

假期在家里歇着,题不想刷,机器学习慕课看着无聊。。想起上学的时候给同学吹逼:“爬虫不用学,Google一下就会 […]
櫻川 浅羽's avatar

可能是長這麼大第一次差點趕不上飛機

如果只算飛機,雖然淺羽也坐了近百次了,但長這麼大還真是第一次險些錯過飛機。
Molunerfinn's avatar

Electron-vue开发实战5——开发插件系统之CLI部分

前言

祝大家2019年猪年新年快乐!本文较长,需要一定耐心看完哦~

前段时间,我用electron-vue开发了一款跨平台(目前支持主流三大桌面操作系统)的免费开源的图床上传应用——PicGo,在开发过程中踩了不少的坑,不仅来自应用的业务逻辑本身,也来自electron本身。在开发这个应用过程中,我学了不少的东西。因为我也是从0开始学习electron,所以很多经历应该也能给初学、想学electron开发的同学们一些启发和指示。故而写一份Electron的开发实战经历,用最贴近实际工程项目开发的角度来阐述。希望能帮助到大家。

预计将会从几篇系列文章或方面来展开:

  1. electron-vue入门
  2. Main进程和Renderer进程的简单开发
  3. 引入基于Lodash的JSON database——lowdb
  4. 跨平台的一些兼容措施
  5. 通过CI发布以及更新的方式
  6. 开发插件系统——CLI部分
  7. 开发插件系统——GUI部分
  8. 想到再写…

说明

PicGo是采用electron-vue开发的,所以如果你会vue,那么跟着一起来学习将会比较快。如果你的技术栈是其他的诸如reactangular,那么纯按照本教程虽然在render端(可以理解为页面)的构建可能学习到的东西不多,不过在main端(electron的主进程)应该还是能学习到相应的知识的。

如果之前的文章没阅读的朋友可以先从之前的文章跟着看。

icebound's avatar

随便写写题解

CodeForces – 1089A  Alice the Fan 题意:两个人打BO5 […]
櫻川 浅羽's avatar

初音未來遊戲補完計畫:New 3DS LL 漫談與動手玩

偶然想起,PSP、PSV 和 PS4 上的初音未來遊戲都玩過了,但 3DS 上好像還有初音兩作沒有玩過。提到掌機就不得不說 Nintendo 的新貴,Swtich 很厲害、寶可夢限定版也很漂亮,但是畢竟沒有本命初音的遊戲,而且恰巧別的遊戲也沒有淺羽喜歡玩的。說到底,還是爲了遊戲選平臺,算是正常思路。
icebound's avatar

回家

往常的时候,远处列车驶来,在西二旗窄小的站台上,排队的人流往往都会有一阵骚动。尤其是工作日的下班时间,人们心中 […]
櫻川 浅羽's avatar

刪除 ESXi 中無效的 NFS 設定檔

中午本來想在存儲伺服器上看看 rsync 的記錄,結果意外地在 /var/log/messages 裏看到了一坨 NFS 連線失敗的日誌:

Jan 27 16:48:01 storage-01 mountd[2341]: mount request denied from 192.168.55.2 for /mnt/STAGE_LSI_Pool
Jan 27 16:48:31 storage-01 mountd[2341]: mount request from 192.168.55.2 for non existent path /mnt/STAGE_LSI_Pool

這個 STAGE_LSI_Pool 是一個很古老的池,看名字就知道早已經放棄不用了。日誌中報的 192.168.55.2 是 ESXi 在存儲網路中的 IP 位置,所以第一反應是去 ESXi Web Console 中看存儲相關的設定,然而並沒有看到這個已經被棄用的 NFS 掛載點。聯想到最開始建置 ESXi 時確實有使用過這個存儲池,於是打算直接 SSH 到 ESXi 內解決問題。首先用 ESXCLI 看一下資料存儲:

[[email protected]:~] esxcli storage nfs list
Volume Name     Host          Share                       Accessible  Mounted  Read-Only   isPE  Hardware Acceleration
--------------  ------------  --------------------------  ----------  -------  ---------  -----  ---------------------
NFS VM Storage  192.168.55.1  /mnt/SAKURAGAWA_POOL_1/VMs        true     true      false  false  Not Supported
NAS             192.168.55.1  /mnt/SAKURAGAWA_POOL_1/NAS        true     true      false  false  Not Supported

並沒有看到相關的卷,那麼直接找相關的設定檔吧。一般來說,Linux 下的 NFS 設定會寫在 /etc/fstab 或者 AutoFS 內。然而 ESXi 雖然看起來像 Linux,卻與標準 Linux 區別甚大:它既沒有 fstab,也沒找到對應 NFS 的設定檔案。。一番瞎猜搜尋無果後,乾脆直接 grep。

[[email protected]:~] grep -rn STAGE_LSI_Pool /etc/
/etc/vmware/esx.conf:246:/nas/VM ISO/share = "/mnt/STAGE_LSI_Pool/NAS/Systems"

果然找到了對應的設定檔案,打開之後發現 242-246 行有相關的設定:

/nas/VM ISO/readOnly = "false"            
/nas/VM ISO/host = "192.168.55.1"                           
/nas/VM ISO/enabled = "true"                                           
/nas/VM ISO/share = "/mnt/STAGE_LSI_Pool/NAS/Systems"

刪除了事。考慮到還有資料存儲在 NFS 上,暫時先不重啓 NFS 服務了,就當作垃圾清理好了。

琴音's avatar

2019/1/26 19th Reborn

在我开始写这篇文章的时候,还有二十分钟我就将到达人生第十九个年头开始的标志点。怎么说呢,十八年里自己活得不算好也不算坏,无论是爱还是友情或是憎恨又或是什么被Cwist&Orange&Larma广泛认为是我矫情属性的重要象征的东西我都经历了一个遍。

今年也不想再写什么太矫情又空洞的东西吧。

作为一个Code Farmer,语言简洁一点是好事。那我也就不那么长篇大论,先给自己定下一个2019年的关键词吧。

选择

这个词在过去的一年里被我的说说、日记、残篇和备忘录反复提到,好像我是得了什么复读症状一样,自己都快把自己的耳朵磨出了茧子。但,做选择需要的勇气和承担选择后果所需要的勇气,都是我认为我暂时还没有的东西。

大概只是意气用事,而不是深思熟虑之后才下决心走上哪条道路。

说实话,在这样一个社会下,这样去做事未免过于幼稚又无趣,但当我失去思考的能力,也放弃了生活的热情之后,做出那些让自己悔之晚矣的事情,似乎也没什么在意料之外。

做个选择吧。

第十九年,to be or not to be.

好时代,来临吧。

icebound's avatar

北邮国际学院部分课程学习技巧

最近被学校期末考试折磨的快不行了,今天刚刚考完。原本是想写一篇文章吐槽一下今年的考试,最终还是决定写一些实用的 […]
Molunerfinn's avatar

2018小结

终于把研究生开题的事情弄得差不多了,可以抽空写一下2018年的小结了。

赵坤's avatar

经典编程语录

我收集的经典编程语录 !

函数不宜过大

程序的功能单位不宜过大,太大的函数容易掩盖错误,就像一个大城市隐藏着逃犯一样。这样的软件很难阅读,很难测试,也很难调试。(《自下而上的编程》, by Paul Graham)

最好保持原样

一家公司想装修办公室地板,结果发现下面是蜿蜒曲折的通信电缆。如果彻底装修,必须更换并重新连接电缆。他们这样做了吗?没有,当他们看到复杂的电缆后,就没有碰任何东西,只是小心地更换了地板。谁知道每根电缆的作用和连接方式?最好保持原样。 —— 《如何维护复杂系统》

数据结构的重要性

只要掌握了数据结构中的四大法宝,就可以包打天下,他们是:array 、linked list 、hash table、binary tree 。这四大法宝可不是各自为战的,灵活结合才能游刃有余。比如,一个用 hash table 组织的 symbol table,其中个个都是由字符型 array 构成的 linked list 组成的。 — Go 语言之父 Rob Pike

赵坤's avatar

2019 中国互联网热点大事件

【长期更新】 记录 2019 年中国互联网的我所认为的值得关注的热点新闻与事件 !

三款App宣战微信

1月15日,罗永浩、张一鸣、王欣都发布了最新的社交产品。据悉,快播王欣发布的产品叫 “马桶MT”;头条张一鸣发布的产品叫 “多闪”;锤子罗永浩发布的产品叫 “聊天宝”。以下是微信当天的应对:

而王欣的产品主打熟人匿名社交,让大家匿名聊天,很快就被全网屏蔽,以下是一段耐人寻味的网友点评:

Molunerfinn's avatar

图床「神器」PicGo v2.0更新,插件系统终于来了

前言

距离上次更新(v1.6.2)已经过去了5个月,很抱歉2.0版本来得这么晚。本来想着在18年12月(PicGo一周年的时候)发布2.0版本,但是无奈正值研究生开题期间,需要花费不少时间(不然毕不了业了T T),所以这个大版本姗姗来迟。不过从这个版本开始,正式支持插件系统,发挥你们的无限想象,PicGo也能成为一个极致的效率工具。

除了发布PicGo 2.0本体,一同发布的还有PicGo-Core(PicGo 2.0的底层,支持CLI和API调用),以及VSCode的PicGo插件vs-picgo等。

's avatar

Rsync使用文档

由于太菜导致反复翻车

Kunagisa Mari's avatar

AliceandCyberpunk

提到爱丽丝梦游仙境,除了”童书“之外,你还能想到什么?

熟悉我的人会知道,我对文字游戏有一种奇怪而狂热的痴迷,我一直是
西尾维新 的粉丝,同时一直在大力推荐
《哥德尔,艾舍尔,巴赫》
而且我对悖论性的东西也是很好奇的。
以上是吹水时间,那么为什么爱丽丝会和赛博朋克等东西扯上关系呢?(
以下是纯粹胡说,请勿在正经文章里以本文作为论据,如果你这样做了,我对你的论文成绩不负责

爱丽丝是如何和计算机科学扯上关系的

要谈赛博朋克,避不开的便是计算机科学。
众所周知,刘易斯卡罗尔(Lewis
Carol)是个数学家,所以这本书里涉及到的段子有很多是与逻辑和数学有关的,并且具有很多影射。
更多的细节可以参照
这位老兄的文章

爱丽丝自己

爱丽丝本身是一个具有严重好奇心的反传统形象,非常适合作为一个人物的原型(Prototype)形象,同时爱丽丝这本书也具有荒诞性和一定意义上的恐怖(或者说包含一点哥特风格),它的经典性也决定了它容易成为引起读者共鸣的形象。

再来说赛博朋克和爱丽丝

赛博朋克具有固有的荒诞性,而爱丽丝这一书也具有这一特点,因此爱丽丝与赛博朋克具有内在的契合性。
同时,爱丽丝也适合作为揭秘者和探索者形象,也既赛博朋克作品中的主角(反抗者),类似于Matrix里的主角(爱丽丝的个性使她一定会选择红药丸(Red
Pill),而红药丸这一概念就借自爱丽丝其书-见参考1,这里的借用是一种超概念的变大/变小),实验性动画玲音的玲音(表世界/现实世界,这里的联系并不紧密,因为探索后玲音扬升为神–
~~ 我怎么又突然想到小圆了 ~~)。
ACG作品中也有许多和爱丽丝相关的,例如小樱新作(参见注释2,这个点子是我看到某张图想到的,没想到有人做过了),另外,三蹦子玩家新年活动打得爽吗,你看看地图名。
还有一个和赛博朋克沾边的Alice相关作品–刀剑神域Alicization篇。
同时,赛博朋克和爱丽丝同样反映对于现实世界的担忧。(还有个有趣的东西,生物学上的红皇后理论)

参考及扩展内容

琴音's avatar

Primo Cache试用——HDD Boost#Tech 1

文件越来越大,电影、游戏,甚至一些高保真度的音乐都动辄以GBytes作为单位计算空间占用时,HDD的读取速度就不那么尽如人意了。

作为一个算是老资历的游戏玩家,我可怜的5400rpm的希捷酷鱼每每让我在WOW读蓝条、R6转圈、以及AC:Odyssey开放世界加载地图和Warframe进入福尔图娜&希图斯时都能泡杯咖啡,耗时之久令我不禁怀疑是否它已经有了坏道。

当然,我并不是什么人民币玩家,也就不存在自掏腰包买一根2TB SSD或是一根Optane的究极举措——实话说这块HDD还是我去魔都的时候上一块WD 1TB坏掉时候换的,这才没到三个月。

嗯,是挺头疼的。

四处爬帖,最后爬到一个看起来很Dio的软件。

Primo Cache.

仔细看了看官网说明文档。

官方说明

也恰巧是有一点学过的东西,我仔细研究了一会。

简单来说,PCache拦截System至HDD的I/O请求,拦截同时检测读取数据是否已经在PCache中存储,若有,则直接使用其存储在内存中的Cache。

(吐槽:其实这大概已经是个过时的软件了。)

下载安装之后,设置界面如下。

在这里解释一下吧。

1.提升读性能:使用一级缓存和二级缓存提升顺序&随机读取的性能

2.提升读性能(仅使用SSD缓存):仅使用SSD作为二级缓存,提升顺序读取性能

3.提升写性能:和1相同,只不过提升的是写性能

4.提升读&写性能:包括以上所有,即:使用一级缓存和二级缓存提升综合读写性能

个人建议无脑选4,但如果只是为了游戏加载的话2就可以了。(当然,我还要跑AE、Pr……必然选4)。

再向下要我们选择自己需要缓存的卷了。

当然是选择存储了大量杂物的——HDD。(这里我小心翼翼徘徊了半天)

要强调的事情是PrimoCache的缓存来自于多余的内存,所以内存不够的人就直接叉掉吧。

接下来设置缓存粒度、内存设置为缓存的大小等一系列最终设置。

由于我的电脑有16GB的内存,我刻意分出了3GB的大小用于加速HDD。

缓存粒度越小,缓存的速度就越快,缓存策略则是设置缓存用于加速的趋势,而延时写入则是必须注意的一个地方。

Primo Cache的缓存是基于内存RAM实现的,所以当断电时缓存会被清空。延时写入会让写入硬盘的数据滞留在缓存中,在预设的延时之后才写入硬盘,在这个延时中若是电脑断电、死机、重启等一系列故障,内存将因此刷新,进而损毁数据甚至缓存盘。

要不要开这个选项,我个人认为需要思考。

然后确定,大功告成。

这就是最终的效果。

个人使用一周之后,感觉效果还是不错的。但是要不要拿内存换硬盘的性能……仁者见仁智者见智吧。

琴音's avatar

域名更换公告

鉴于.tk域名运营商Freenom近日来经常出现的不经告知直接收回域名的恶劣行为,我刚刚注册了一个新的域名,亦即现在的www.talrasha.me,从前那个域名将在到期之后彻底停止解析

琴音's avatar

无题#17

x的真是服了在自习室外放微信提示音的傻逼。

问少's avatar

又一次更换了评论系统

去年暑期的时候 HyperComments 开始收费,并且不给钱就不给看历史数据,一声不吭就直接进入收费模式,这也太狗了。去他妈的 HyperComments 吧,不用就不用了。于是在那个时候换了 Disqus 这个经典的评论系统。

Disqus 虽好,但国内访问不了,我那时还感叹了一下,以后评论随缘吧(说的好像能访问就有很多评论一样)。思来想去,国内用户看不到评论系统,少了点东西,那样的话看我这个网站总是怪怪的。

今天在升级 NexT 主题时,又详细看了一下配置信息,看到了 Gitment 和 Gitalk 这个玩意儿,在 GitHub 的仓库中开 Issue 为每个页面记录评论。不得不说,这个思路很清奇。本身 Hexo 博客就是托管在 GitHub 仓库中的,那么一个 Issue 就对应一个文章,这个 Issue 下面的评论就对应文章下面的评论。

现在你看到的评论框就是 Gitalk 了,比 Gitment 更新的勤快,比 Gitment 维护的人多,比 Gitment 好看,是我选择 Gitalk 的理由。

有一点不太方便的地方就是,每篇文章都需要手动初始化评论,不能自动初始化。新文章的初始化还简单些,就是访问一下页面,老文章的初始化就有些蛋疼,毕竟也有几十个呢。还好网上找到了一键脚本,得以解决这个问题。话虽是这么说,但我还是没有用一键脚本,仍是访问了每篇文章来初始化。别问为什么,就是想顺便回顾一下历史。

现在,国内用户终于可以访问我的评论系统了,不过真的会有多少人来评论吗?#捂脸

琴音's avatar

我们还有未来的时候#16

这是一篇受密码保护的文章,您需要提供访问密码:

icebound's avatar

密码保护:goodbye2018

无法提供摘要。这是一篇受保护的文章。
's avatar

Telegram RSS机器人

信任Systemd的人,最终……

Kunagisa Mari's avatar

科技公司迷思-信仰

英雄用剑刺死恶龙,然后坐在尸身上,看着闪烁的珠宝,慢慢地长出鳞片、尾巴和触角,最终变成恶龙。

以上这段话是某对苹果公司和谷歌的评价,苹果公司的 仿1984广告 (见上)和Google曾经的“不作恶”还在记忆中,Apple和Google就成了新的老大哥,Apple的T2等和原先的反抗者形象愈行愈远,彻底的把自家产品变成了消费主义产品- 人为的取消 可维修性(如果说在T2产生之前还勉强可以辩解只是设计需求,那么现在可以说是彻底的计划报废了–和某些打印机厂商固件里打印计数器的作用类似,非常消费主义),同理,Google从当初一怒之下退出中国的企业变成了制订Dragonfly计划的企业。

而索尼,一再消费粉丝信仰给用户喂屎。你对消费电子企业的信仰只能把你变成他们的摇钱树,而主动提及信仰的大多是骗子–罗永浩的锤子科技便是例子,而 骗子终究是骗子

说穿了,企业终究是企业,政治家和资本家也变不成别的什么东西,他们干什么的最终目的都是你的钱包👛(或者对于政治家来说,权力),而不是达到或追求什么东西,即使他们本来想这么做。人总是要恰饭的,这个平庸的理由打倒了无数曾经的年轻人,也将在可预见将来打倒无数的年轻人。

没有什么东西值得信仰,特别是你要自己掏腰包的时候。你要记得,不要给信仰买单,而是要给产品本身和售后服务买单,如果什么东西看起来不值它的价格,那它在大部分情况下确实不值这个价格,无论它是什么厂商制造的。

在消费主义下,没有什么人可以幸免,但至少你得找个相对来说对你好而不是消费你的厂商。

琴音's avatar

Waiting#15

愿你的现实待你温柔。

琴音's avatar

Reset#14

Making myself out of control maybe kind of self-destruction…

But, how can I get away from this>>>

Making everything back to normal is difficult, and it’s hard for me to REALIZE what is going on.

Daily Routine leads to SD ending, so I’m going to find a way to save myself.

Hard to describe…

If love means Suffering…

Can I get away from my heart?

琴音's avatar

Leave#13

日子一天天过去。

我原本还以为一切都会如我们希望而发展。

可我最后才知道,那些被称之为希望的东西,恰恰是连梦中都实现不了的可笑愚钝。

于是,这次,最后一个 Female Illusion也不见了。

问少's avatar

COM6516 Assessed Lab

Assessed Lab 1

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
/*
* Developed by Neo on 05/11/18 11:12.
* Last modified 05/11/18 10:39.
* Copyright (c) 2018. All rights reserved.
*/

import sheffield.EasyReader;

/**
* This class can generate a walking plan for a old person
*/
public class GenerateWalkingPlan {
/**
* Program starts here.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
// Ask for user's name and age for creating plan
EasyReader myReader = new EasyReader();

String name = myReader.readString("What is your name? ");
int age = myReader.readInt("Hello " + name + ", how old are you? ");

// Create a walk plan and print it
WalkingPlan newPlan = new WalkingPlan(name, age);

newPlan.generate();
newPlan.toPrint();
}
}
Kunagisa Mari's avatar

一些奇怪的东西

意义和价值 是用什么衡量的?

我喜欢品味文字,品味文字间有趣的关联性,喜欢空灵,喜欢沉重,喜欢虚幻,喜欢现实。
我品尝过噩梦,它披着美好出现。
我观赏过美景,它含于纸墨之间。
我也想拥有自己的天地,不在现实之中,而在屏幕之上跃动。
因为,我在现实中反抗自己的性别,反抗我和外界的丑陋,却不能得到胜利,也不可能得到胜利。
我想要点燃别人,帮助别人,却总是看见一点点的其它火焰熄灭
说不清是羡慕还是嫉妒,我更想做那些天生可以的人,或者什么都看不到的傻瓜。
我能品味文字的优劣,我在梦境中构造自己的世界。我尝试用纸折叠连接出它们,用语言和色笔构造它们,用音符连缀他们,可我不能接受,我认为我创造它们是劣质的。
我渴望自洽,在各个层面上。可我幻想的能力并不充足。
它越来越具体却越来越崩毁,在建构的同时坍塌。我无法用文字传递这种矛盾,也无法用精妙的文字把戏,隐喻和映射勾勒它的外形。
我想让文字纤细,可我得到的只是沉重的编织物而非轻帛。
但是,我还是想把它们中较好的留下来。
它们或许关于头顶的群星,关于被人监视的世界,关于代码构造的大地,关于永不屈服的反抗者,关于敲碎水缸的脑,关于人和一切自然中存在,不存在和同时存在又不存在的东西。
这是开场,谢幕是什么时候呢?
或许是我不再反抗的那一天,是我不再坚持荒谬信仰的那一天,活成自己讨厌的样子的那一天。这比死亡更令人恐惧。
我希望我不要战胜自己,热爱老大哥。
就这样,当我失败的那一天,这些和我剩下的东西,是我曾经抗争的墓碑。
感谢您的时间。

问少's avatar

COM6506-Assignment

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
package dateTests;

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MetaMorphicTestingExample {
/**
* Illustration of how one might test the Metamorphic relation MA,
* given as example in the assignment (that the day of the week can
* be optional.
*/
@Test
void MA() {
//Imagine that the following string had been in our CatPart tests:
String originalInput = "Tue, 3 Jun 2008 11:05:30 GMT";
//Now we compute the output from the original test case.
LocalDateTime originalDateTime = LocalDateTime.parse(originalInput, DateTimeFormatter.RFC_1123_DATE_TIME);

/*Now we generate a new test input to test the Metamorphic relation.
* For the relation MA, we remove the 'Tue' part of the input, and make
* the assumption that we should also remove the subsequent comma and space
* as well to avoid a parsing error:
*/

String metaMorphInput = "3 Jun 2008 11:05:30 GMT";
LocalDateTime metaMorphDateTime = LocalDateTime.parse(metaMorphInput, DateTimeFormatter.RFC_1123_DATE_TIME);

/*Our Metamorphic relation suggests that the resulting time should remain
* equal to the original time. Therefore we make this our test oracle:
*/

assertEquals(originalDateTime, metaMorphDateTime);
}
}
问少's avatar

COM6516 Week11

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
/*
* Developed by Neo on 12/8/18 7:39 PM.
* Last modified 11/24/17 2:18 PM.
* Copyright (c) 2018. All rights reserved.
*/

/*
* JCalculator.java
* Class to produce a simple calculator in a window
*/

import javax.swing.*;
import java.awt.*;

public class JCalculator extends JFrame {
private JCalculator() {
super("JCalculator");
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
setSize(300, 400);
setLocationRelativeTo(null);
Container contentPane = this.getContentPane();

JTextArea display = new JTextArea(1, 20);
display.setEditable(false);
display.setFont(new Font("Courier", Font.BOLD, 40));
display.setPreferredSize(new Dimension(300, 100));
contentPane.add(display, BorderLayout.NORTH);

CalculatorButtons buttons = new CalculatorButtons(display);
contentPane.add(buttons, BorderLayout.CENTER);

}

public static void main(String[] args) {
JFrame frm = new JCalculator();
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setVisible(true);
}
}
's avatar

Openwrt IPv6 配置

从起点出发然后回到起点。

vitech's avatar

ElasticSearch 配置Logstash导入mysql数据库

网上教程不少,但是大多对新手不太友好,细节也不太好,这里针对ElasticSearch小白。

以ElasticSearch 5.6.12 和 LogStash 5.6.13为例。这两个的安装从略。
尽量保证两者版本不要相差太多。考虑到LogStash只作为管道,版本不需要一致。

先到LogStash目录下安装JDBC插件

cd /opt/logstash
bin/plugin install logstash-input-jdbc

如果是windows下,请自行在可执行文件后加上.bat

安装完之后开始导入,这个导入过程我们编写一个conf文件实现,这里以logstash.conf为例,为了方便可以直接在logstash/bin下创建一个logstash.conf

input {
  jdbc { 
    # "your-database" 是数据库名    
    jdbc_connection_string => "jdbc:mysql://localhost:3306/your-database"  
    #mysql数据库用户名密码
    jdbc_user => "root" 
    jdbc_password => "********"
    #schedule 可选,如果有schedule则会自动同步,这里意思是每一分钟同步一次,没有就只同步一次。具体的见官方文档
    #schedule => "* * * * *"
    #这里需要使用一个mysql连接库,文末有下载地址,自行下载后随便放一个地方,这里只是举例
    jdbc_driver_library => "/usr/local/logstash/mysql-connector-java-6.0.5.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    #查询,这里只需要select一下即可,比如从your-schema数据表
    statement => "SELECT * FROM `your-schema`"
    }
  }
output {
  stdout { codec => json_lines }
  elasticsearch {
  "hosts" => "localhost:9200"
  #your-index是事件要被写进的索引 如果没有索引就新建一个
  "index" => "your-index"
  #your-type-name 只是数据集的分类,自定义,同类数据尽量使用同一个type
  "document_type" => "your-type-name"
  #可选,这里的意思是绑定原mysql表的id列作为主键,可以避免重复
  "document_id" => "%{id}"
  }
}

然后执行

cd /opt/logstash/bin
./logstash -f logstash.conf

可以看到一排输出,然后数据就注入成功了。

顺带一提,如果小白注入完数据发现有unassigned数据,或者说集群健康度不够,是因为现在的节点分片不够存储数据集的1份备份(默认一份)。只需要执行诸如

curl -XPUT 'localhost:9200/your-index/_settings' -d '{"number_of_replicas": 0}'

将备份数降低即可。

一个可用的Maven的mysql-connector-java-6.0.5.jar

问少's avatar

COM6516 Week10

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
75
76
77
78
79
80
81
82
83
84
85
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MyFrame extends JFrame implements ActionListener {
private MyPanel drawingPanel;

private MyFrame() {
int width = (int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2.0);
int height = (int) (width / 16.0 * 9.0);
setSize(width, height);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);

//For better looks.
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

drawingPanel = new MyPanel();
drawingPanel.setPolygon(5);
Container contentPane = this.getContentPane();
contentPane.add(drawingPanel, BorderLayout.CENTER);

JPanel columnOfButtons = new JPanel(new GridLayout(8, 1));
ButtonGroup buttonGroup = new ButtonGroup();
for (int i = 3; i < 10; i++) {
makeRadioButton(columnOfButtons, String.valueOf(i), buttonGroup, this);
}

JButton exit = new JButton("Exit");
exit.addActionListener(this);
columnOfButtons.add(exit);

contentPane.add(columnOfButtons, BorderLayout.EAST);

setVisible(true);
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(MyFrame::new);
}

private void makeRadioButton(JPanel p, String name, ButtonGroup group, ActionListener target) {
JRadioButton b = new JRadioButton(name);
group.add(b);
// add it to the specified JPanel and make the JPanel listen
p.add(b);
b.addActionListener(target);
}

public void actionPerformed(ActionEvent e) {
// Do the appropriate thing depending on which button is pressed.
// Use the getActionCommand() method to identify the button.
switch (e.getActionCommand()) {
case "Exit":
System.exit(0);
case "3":
drawingPanel.setPolygon(3);
break;
case "4":
drawingPanel.setPolygon(4);
break;
case "5":
drawingPanel.setPolygon(5);
break;
case "6":
drawingPanel.setPolygon(6);
break;
case "7":
drawingPanel.setPolygon(7);
break;
case "8":
drawingPanel.setPolygon(8);
break;
case "9":
drawingPanel.setPolygon(9);
break;
}
}

}
vitech's avatar

lnmp配置laravel/thinkphp时出现no input file specified的常见问题

lnmp的域名绑定命令即使到最新的1.5版都是一套不太成熟的做法。
我们每次执行诸如lnmp vhost add时,都会在目录下生成一个类似这样的.user.ini文件

open_basedir=/home/wwwroot/your-project/:/tmp/:/proc/

.user.ini的作用是覆写php.ini中的部分参数,在这里来说,open_basedir在php.ini中可能有一个全局值,而在这个目录下有一个局部的值会覆盖全局值。

而open_basedir则是造成nginx/php-fpm 报错的罪魁祸首,这么说可能不恰当,因为.user.ini的本意是好的,其机理是限制php访问目录,举例来说,你在这个目录下配置的php文件只能操作/home/wwwroot/your-project/下的文件。

而这样就导致了我们在使用诸如laravel/ThinkPHP框架时的问题。比如我们在home/wwwroot下建立了名为your-project的laravel项目,但是lnmp绑定vhost时,按常理是要绑定到/public目录下的。因为/public下是整个网站的入口,这样一来就产生问题了:.user.ini中会生成/home/wwwroot/your-project/public/:/tmp/:/proc/这样的参数,然而这个项目的php是必须要有要调用/public外文件的权限的!这个问题的产生往往会让人难以排查,因为不管是浏览器输出,亦或是nginx和php-fpm的log都不会给出任何错误信息,一个隐藏在/public下的.user.ini文件很难让新手发觉出问题。

解决方案:

.user.ini被安全锁定了,先使用

chattr -i .user.ini

将其解锁,然后vim编辑去掉/public,再chattr +i .user.ini加锁。
当然你也可以直接解锁后删掉,这样损失了一定安全性,对于小项目或者本地项目倒没什么意义了。

Kunagisa Mari's avatar

简单易懂的水表指南

查水表在天朝是一个永恒的话题,官方查水表叫查水表,民间查水表叫出道,下面将会对您对水表的了解作出一点微小的贡献。

水表概论

为啥被查

一般来说,查水表主要发生在您手动泄漏了自己的信息的情况下。
官方水表主要依赖以下信息,从容易查到难查排序。

  • 手机号
  • QQ
  • 微信
  • 锑度
  • 知乎
    据传言,逼乎没有提供官方接口,水表只能发函人工查。

    查什么人

    实际上,根据大部分人匿名性的强度,查是都可以查,只不过是成本问题(不要停下来啊!),而且网警也没那么闲,没钱又费力的活谁干?
    一个简单的表述:当您没上名单的时候,您只要别作出自报家门之类的行为,一般不会有事。
    最简单的说法 成本>收益 哦嚯

    查,都可以查

    这里介绍几种查水表的方式,让大家学习一个

    人肉搜索

    顾名思义,直接把名字/ Nickname 之类的玩意喂给搜索引擎/平台内搜索,看看有没有什么好文明(bushi
    如果能搜到您的企鹅号之类的,哦嚯,gg。
    这个对于个人来说也是有用的,比如看看 您家乡附近 有什么风景名胜啊之类的,或者看看您有没有在某些社交平台自我爆破,例如自报姓名单位手机号等等。通过id等搜集尽可能多的信息。
    另外,如果您头像复用,有足够闲心的人也是可以抓到的
    可以爬取到的信息来源
  • 锑度贴吧
    您关注的:学校/地区相关吧,自爆发言。
  • 锑度云
    公开分享的内容。
  • QQ空间
    人际关系,和学校等公用帐号的交互,风景图(可以知道行程)
  • Flicker等图片平台
    特殊地标,商品等。
  • Twitter/微博等
    地理位置,相关发言(地区相关的事件等)
  • 注意
    尽管某些平台是私密的,但 Telegram 等的公开群和频道也是可以视奸的。

    侧信道

    人脉绘图

    即使您没有在十万甚至九万个平台复用 id ,也是可以查到您的,只要找到您在一个平台上的人际关系,并且在其他平台上找到对应的人,想想看,您懂了没?

    EXIF

    图像中存在一些元数据,包括地理位置,拍摄条件等等。
    其它的元数据也是可以被滥用的,此处不一一枚举。

    行为特征/语癖/不标准的外语

    一个人的语癖可以反应他的特征,部分方言也可以确定居住地区(大概范围)
    另外,不要刻意去使用外语,您不标准的使用反而会使您露馅(例如某位用 zh_TW 却把軟體写成軟件,韌體写成固件的屑,拜托,不会装tw人就别装,搞得好像大脑升级了一样

    截图

    截图是个信息量很大的东西,可以看到您用的操作系统(手机ROM或品牌)/浏览器/其它软件(通知栏图标等),有些时候还会带上其它信息(如数字水印)

    邮箱

    从社工库里一查,可以查到114514个相关帐号和密码。

    分享的链接

    某些平台在分享时会在 url 里带上相关信息,例如 utm=”” uid=”” 小心一个链接就翻车

    时间

    -1s(bushi
    时间反应了您到作息习惯。

以上。

Kunagisa Mari's avatar

每周密码学WriteUP

弱智XOR

ref:Single-byte XOR cipher
额,其实这是一个脑残暴力题,加密方式类似凯撒,把某个字当关键字逐字XOR
直接开始绿皮暴力破解

1
2
3
4
5
6
7
8
string=input()  
for j in range(0,127):
print(str(i))
for i in range(0,len(string)-1,2):
char=eval("0x"+string[i:i+2])
buff=char^j
print(chr(buff),end='')
print('\n')

emmm,从结果里找个看的顺眼的(绿皮大法好

弱智XOR,升级版

ref:Single-byte XOR cipher
从一堆字符串里找到被单字符xor加密的那个
继续绿皮,利用python逐行处理。
加个判断,发现不可打印字符就丢弃,并过滤长度不足30的字串来减少过滤工作量

维吉尼亚密码

ref:Break repeating-key XOR
每日卡西斯基试验时间,由于密文够长,无需绿皮,直接按照密钥长度逐字符分析,做个统计。
由于不知道密钥长度,只好对密钥长度绿皮一下。
顺带一提,对于这种密码,密钥长度不够长的时候长度为质数最安全。(数学原因显然易见)

沙雕AES

ref:https://cryptopals.com/sets/1/challenges/8
这个题的有意思之处在于,它没让你找到原文是啥,只让你找到哪个文本串是加密的。
由搜索可知,本题采用的AES的ECB(电子密码本)有个重要缺陷,同样的原文块会被加密为同样的密文块(脑壳痛)。
本例中块的大小才16byte,直接大鼓式重复检查可得。
(题外话,现在aes128已经可以绿皮出来了)

Molunerfinn's avatar

一周一部好电影V【WEEK210 网络迷踪】

2018-11-11 WEEK210 网络迷踪

网络迷踪——————————————Searching

  • 导演:阿尼什·查甘蒂
  • 主演:约翰·赵/米切尔·拉/黛博拉·梅辛/约瑟夫·李/萨拉·米博·孙/亚历克丝·杰恩·高/梅金·刘/刘卡雅/多米尼克·霍夫曼/西尔维亚·米纳西安/梅丽莎·迪斯尼/康纳·麦克雷斯/科林·伍德尔/约瑟夫·约翰·谢尔勒/阿什丽·艾德纳/托马斯·巴布萨卡/朱莉·内桑森/罗伊·阿布拉姆森/盖奇·
    比尔托福/肖恩·奥布赖恩/瑞克·萨拉比亚/布拉德·阿布瑞尔/加布里埃尔D·安吉尔
  • 片长:102分钟
  • 影 片类型:剧情/悬疑/惊悚
  • 豆 瓣评分:8.7/10(from85,981users)
  • IMDB评分:7.8/10(from38,178users)
问少's avatar

COM6516 Week09

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
/*
* Developed by Neo on 19/11/18 11:54.
* Last modified 19/11/18 11:54.
* Copyright (c) 2018. All rights reserved.
*/

import javax.swing.*;
import java.awt.*;

public class CornerString extends JFrame {
public CornerString() {
super("Corner String");

//For better looks.
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setSize(960, 480);
this.setResizable(false);
this.setLocationRelativeTo(null);

this.setContentPane(new StringPanel());

this.setVisible(true);
}

public static void main(String[] args) {
new CornerString();
}

public class StringPanel extends JPanel {
public StringPanel() {
super(new BorderLayout());

JLabel label1 = new JLabel("To be or not to be");
JLabel label2 = new JLabel("To be or not to be");
JLabel label3 = new JLabel("To be or not to be");
JLabel label4 = new JLabel("To be or not to be");

label1.setFont(new Font("Consolas", Font.PLAIN, 32));
label1.setForeground(Color.BLUE);
label2.setFont(new Font("Comic Sans MS", Font.PLAIN, 32));
label2.setForeground(Color.GREEN);
label3.setFont(new Font("Monospaced", Font.PLAIN, 32));
label3.setForeground(Color.RED);
label4.setFont(new Font("Courier", Font.PLAIN, 32));
label4.setForeground(Color.YELLOW);

JPanel northPanel = new JPanel();
northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.X_AXIS));

northPanel.add(label1);
northPanel.add(Box.createHorizontalGlue());
northPanel.add(label2);

JPanel southPanel = new JPanel();
southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.X_AXIS));

southPanel.add(label3);
southPanel.add(Box.createHorizontalGlue());
southPanel.add(label4);

add(northPanel, BorderLayout.NORTH);
add(southPanel, BorderLayout.SOUTH);
}
}
}
icebound's avatar

一点碎碎念

刚刚从2018年的ICPC阴影中走出来,感觉有很多事要做,很多话想说。 今年我们队去了两个站,徐州站和青岛站。 […]
问少's avatar

COM6516 Week08

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
/*
* Developed by Neo on 12/11/18 10:21.
* Last modified 12/11/18 10:21.
* Copyright (c) 2018. All rights reserved.
*/

import java.util.*;

public class ListStringConvert {
public static void main(String[] args) {
List<String> fixedList = Arrays.asList("elephant","lion","leopard", "tiger");
System.out.println(fixedList);
List<String> myList = new LinkedList<String>(fixedList);

// Iterator<String> iter = myList.iterator();
ListIterator<String> iter = myList.listIterator();

ArrayList<String> newList = new ArrayList<>();
while (iter.hasNext()) {
newList.add(iter.next().toUpperCase());
}

System.out.println(newList);
}
}
问少's avatar

COM6516 Week07

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
/*
* Developed by Neo on 05/11/18 11:12.
* Last modified 05/11/18 10:39.
* Copyright (c) 2018. All rights reserved.
*/

import sheffield.EasyReader;

/**
* This class can generate a walking plan for a old person
*/
public class GenerateWalkingPlan {
/**
* Program starts here.
*
* @param args command line arguments.
*/
public static void main(String[] args) {
// Ask for user's name and age for creating plan
EasyReader myReader = new EasyReader();

String name = myReader.readString("What is your name? ");
int age = myReader.readInt("Hello " + name + ", how old are you? ");

// Create a walk plan and print it
WalkingPlan newPlan = new WalkingPlan(name, age);

newPlan.generate();
newPlan.toPrint();
}
}
Kunagisa Mari's avatar

wahway-nmsl

(此处应有龙图)

华为nmsl

在支持微信指纹的emui8和9中,您无法更换默chou认bao的菊花启动器。
#include <disclaimer.h>//你知道接下来的操作是危险,不受支持的,你确定你看完了每一行字。//如果你手机凉了,这不是我的锅//你知道你在干什么
本文章介绍了如何更换emui的启动器和弱智语音助手(无需解锁)

更换启动器

1. 暴力解决

用 adb 迫真卸载
adb shell pm unistall -k -user 0 com.huawei.android.launcher
这将对用户0(机主)保留数据卸载辣鸡菊花桌面。
实际上这个指令可以迫真卸载所有系统应用。
严重警告⚠:请确保卸载华为桌面后系统有且仅有一个启动器(驾驶模式也是启动器),否则后果自负。
对于想知道上面发生什么的人:我只能告诉你,菊花把启动器选择界面的 intent 魔改了,所以无法选择,只能依赖系统的 fallback 。
顺带一提,可以借助island把它安回去,如果您需要知道如何操作,请从站点下方的联系方式戳我。

2.使用device owner强行设置。

(略)您可以参考Android developer站点内容。

问少's avatar

COM6506 Week07

Diamond Gate

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package diamond;

import java.util.Collection;
import java.util.HashSet;

class DiamondGate {

private DiamondGateState state;
private Collection<String> registered;
private int visitors;
private Collection<String> overdue, bookList;

DiamondGate(Collection<String> registered, Collection<String> overdue) {
this.registered = registered;
this.overdue = overdue;
this.bookList = new HashSet<>();
this.visitors = 0;
this.state = new Idle(this);
}

// State Machine operations

void entry_scan(String key) {
state.entry_scan(key);
}

void exit_scan(String key) {
state.exit_scan(key);
}

void entry_sensor_activated() {
state.entry_sensor_activated();
}

void exit_sensor_activated() {
state.exit_sensor_activated();
}

void time_out() {
state.time_out();
}

void pay_fine(String key) {
state.pay_fine(key);
}

void return_book(String key) {
state.return_book(key);
}

// Context operations

DiamondGateState.State getState() {
return state.getState();
}

void setState(DiamondGateState state) {
this.state = state;
}

boolean isRegistered(String s) {
return registered.contains(s);
}

void incrementVisitors() {
visitors++;
}

void decrementVisitors() {
visitors--;
}

int getVisitors() {
return visitors;
}

boolean isOverdue(String key) {
return overdue.contains(key);
}

void paid_fine(String key) {
if (overdue.contains(key)) {
overdue.remove(key);
bookList.add(key);
}
}

void returned_book(String key) {
if (bookList.contains(key)) {
bookList.remove(key);
}
}
}
Schro_Dr's avatar

在分离实现与声明时使用模板类是不是搞错了什么——模板类与LNK2019

今天做数据结构的实验时需要自己实现堆栈,为了代码的优雅省事我选择使用模板类来实现堆栈,但这时却开始疯狂报错LNK2019,真的是可喜可贺并不
经过一番查阅发现,当把模板类的声明与实现分离写在两个独立的文件中,则构建时会出现”error LNK2019″错误。
原因时在实例化模板时,编译器会创建一个具有给定模板参数的新类,所以编译器必须在此时访问模板类方法的实现。但如果这些实现不在.h文件中,那么这些方法将不可访问,编译器无法实例化模板。
解决方法有三个:
1.在类的声明,即.h文件的最后包含类方法的实现文件,即.cpp。
2.在使用类的文件(一般为main文件)中同时引用模板类的接口文件和方法的实现文件,即.h和.cpp文件
3.最后一个办法就是把类方法的声明和定义都放在类的定义中。
为了保持代码的优雅我本来时打算使用第一个方法的,但是却出现了”C1014 包含文件太多” 和”E0003 文件包含自身”这些问题,又不想使用第三个方法——这样就失去了分文件的意义了。
最后折中一下,选择了第二种方法,在使用模板类的cpp文件中同时引用模板类的声明与实现,终于可以运行,可喜可贺,可喜可贺。

参考StackOverflow的回答

问少's avatar

COM6516 Week05

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
/**
* Multiplication table
* Create a table to show 1 to 9 multiplication.
*/
public class MultiplicationTable {

/**
* World starts here
*
* @param args Command line arguments
*/
public static void main(String[] args) {
int num = 9;
System.out.print(" |");
for (int i = 0; i < num; i++) {
System.out.printf("%4d", i + 1);
}
System.out.println();
System.out.print("---");
for (int i = 0; i < num; i++) {
System.out.print("----");
}
System.out.println("--");
for (int i = 0; i < num; i++) {
System.out.print((i + 1) + " |");
for (int j = 0; j < num; j++) {
System.out.printf("%4d", (i + 1) * (j + 1));
}
System.out.println();
}
}
}
Kunagisa Mari's avatar

古典密码学介绍-1-概论与替换式密码

什么是古典密码学

古典密码是密码学中的其中一个类型,其大部分加密方式都是利用替换式密码或移项式密码,有时则是两者的混合。

https://zh.m.wikipedia.org/wiki/古典密碼

简而言之,古典密码学处理的对象是字符(特别是拼音文字字符),而现代密码学则是更数学化的。
古典密码学有时候是和象棋,字谜,甚至语言学等分不开关系,这让它少一些严肃而多了一些浪漫。

古典密码的类型

替换式

替换式密码指将明文字符映射到对应的密文符号表中的密码。

单字母替换式

凯撒密码 Caesar Cipher

凯撒密码可能是古典密码里最出名的,它也可能是历史上第一个实际投入到战争中并起作用的密码。
它很简单,只需将字母表向后推移即可。
示例:
b c d e f g h i j k l m n o p q r s t u v w x y z

1
密文:d e f g h i j k l m n o p q r s t u v w x y z a b c

以上示例给出的是凯撒所使用的密码在英文字母表中的对应。
例如:对于 Apple 采用上述加密后对应的单词为 Dssoh
凯撒密码还有一些亲戚:例如

猪舍密码 Pigpen Cipher

这个奇怪名字的密码来源是它的符号表(如图,来自维基百科: 猪舍密码 。)

它的名字和阴谋论有关,它的另一个名字揭示了这一点:共济会密码。
早在1700年代,共济会就开始经常使用这种密码保护一些私密纪录或通讯。

关键词替换密码

觉得一个个换顺序太单调了?这里有个凯撒密码的略微升级版:用关键词改变顺序。
将你选择的关键词去除重复字母后写在对应表开头,然后按顺序(或者你愿意的话,乱序)去除出现过的字母写下去,得到对应表。
例如,我们选择 Duvet 作为关键词,则:
b c d e f g h i j k l m n o p q r s t u v w x y z

1
密文:d u v e t a b c f g h I j k l m n o p q r s w x y z

这些非常简单的密码有一个共同的特点:一一对应。
然而这也给它们带来了一个共同的巨大的弱点:字母在同一语言中出现的频率是不同的,以英/法语为例,它们中最常出现的是字母’E’,因此,文中出现次数最多的符号便很大概率代表’E’,由此类推,便可获得整个密码表,这种方法被称为频率分析。
为了对抗这种操作,后来又演变出了

多射密码

简单来说,就是一个字母可以对应多个符号,从而打乱单个字符频率。更有甚者,还可以插入空字符(指密文中无意义的字符),从而使频率分析歇菜。 这类中最出名的便是伟大密码。
这是替换密码发展的结束了么?显然不会。接下来还有:

多字母替代式密码

加密由两组或多组密码字母集组成,加密者可自由的选择然后交替使用多个密码字母集加密消息。这么做将会增加解码的困难度,因为破解者必须找出全部密码字母集才能解读。

另一个多字母替代式密

维吉尼亚密码

亦作维吉尼亚方格。
这是一个更难解读的多字母替代式密码的例子:使用的是多个密码字母集。这也是一种创新的加密方法。随着这个方格,它有26组不同用来加密的密码字母集。每个密码字母集就是多移了一位的凯撒密码。
维吉尼亚方格看起来就是这样:

使用时先选择一个关键字,接着重复这个关键字直到跟明文相同长度。然后看明文消息下方是哪一个密码字母集和关键字上的字母对应,并写下对应字母。
例如,假设明文为:

1
2
3
选择某一关键词并重复而得到密钥,如关键词为LEMON时,密钥为:

~~~~LEMONLEMONLE

对于明文的第一个字母A,对应密钥的第一个字母L,于是使用表格中L行字母表进行加密,得到密文第一个字母L。类似地,明文第二个字母为T,在表格中使用对应的E行进行加密,得到密文第二个字母X。以此类推,可以得到:

1
2
3
明文:ATTACKATDAWN
密钥:LEMONLEMONLE
密文:LXFOPVEFRNHR

解密的过程则与加密相反。例如:根据密钥第一个字母L所对应的L行字母表,发现密文第一个字母L位于A列,因而明文第一个字母为A。密钥第二个字母E对应E行字母表,而密文第二个字母X位于此行T列,因而明文第二个字母为T。以此类推便可得到明文。
显然,如果关键字长于原文这个密码几乎是不可破解的。但是密钥的重复会带来问题:会有the之类的小词被加密,透过它们便可找出关键字。这便是卡西斯基实验
如果更丧心病狂一点,还有弗里德曼试验来更高级的用概率论解决。
替换式密码的好处是可以设计方便的器具,例如著名的密码轮和可称为替换式密码巅峰的恩尼格玛
这个值得我们之后单开一篇讲述。
(本文中使用大量公有领域及维基百科内容)

Kunagisa Mari's avatar

配置Cloudflare Access

什么是Cloudflare Access

Cloudflare本社吹水页

Secure Application Access Without a VPN

CloudflareCloudflare Access

简单来说, Cloudflare Access 就是一个基于 CF 反代的访问控制系统,可以高速部署并应用。

哪里买得到呢

  • 你的网站需要对接 CF 本社或 Partner。
  • 访问控制台,打开需要配置的网站,里面 Access 就是了。
    需要注意的是免费 白嫖 版规则数目有限制,最多 5 用户规则。

    动手配置

    1. 开启 Access
      从上一条那里进入后,先戳 Apply 开启该测试版功能,然后选择方案一路 Next 填表就 OK 了
    2. 配置
      注意:Access保护只对经过Cloudflare反向代理的页面有效
      1. 设置登录验证域
        戳下面的 Login Page Domain ,选一个 (你选的域名).cloudflareaccess.com 做登录验证域
        温馨提示:这里的验证域是全账号统一用的一个 点 Change 即可修改

        设置验证方式

      • 用邮箱验证
        这个无需设置, Cloudflare会自动配好。
      • 设置 Google 账号登录
        先从这里戳 Add 然后选 Google,右边会出来向导,按照它一步步操作就好啦。
      • 设置 Github 登录
        操作和上面基本算是相同。

        关于 Instant Auth 开关

        这个只能在只有一种验证方式时启用,效果是跳过方式选择页。

        如何修改移除登录方式

        从上面图里位置戳对应标,里面有 Edit 和 Delete
        其他方式我还没试过

        设置访问控制策略

        下方列表是已有规则,新建账户应该是下面没有东西的。
      1. 添加规则
        戳 Create Access Policy
        进入如下界面: 从上到下分别是
        • 应用(策略)名
          随自己喜好起一个。
        • 应用域
          要控制访问的页面,按需求填写。
          (子域名,可选,不填为二级域).()/(需要控制的页面,可选,不填为根目录)
        • 登陆有效时间
          不解释。
          下面是最重要的
        • 控制策略
          • 策略名
            随意起个。
          • 对应策略
            允许(Allow),阻止(Deny)或可不需登录访问(Bypass)
            可不需登录访问(Bypass)主要用于暴露特定位于被保护页面下不需保护的页面
          • 应用对象
            可以根据以下几种方式区分
            • 限制邮件地址(Email)
              后面框填允许登录的邮件地址。
            • 限制邮件地址后缀(Emails ending in …)
              填域名。
            • IP 范围(IP ranges)
              不解释。
            • 每个人(Everyone)
              门户大开。
              其中策略为可不需登录访问(Bypass)时,只有IP 范围(IP ranges)和每个人(Everyone)可用
              需要一条以上的规则请点 Add new policy ,设置完成后点 Save。

              查看操作记录

              页面底部有登录记录。

              完成后效果

              访问时会自动跳转到认证页,认证后会返回。
Kunagisa Mari's avatar

小说安利:钟与无穷动

传送门:轻国

如果悲剧已经注定,抗争是否还有意义?


本小说tag:变身,超能力,悲剧
本小说中的超能力并不是那种上可毁天灭地,下可下海把妹的那种,尽管主角和女主的超能力很强大,他们也不能超越在不断变动的时间线上稳定的悲剧命运。
以下内容纯属扯淡。

乐迷作者

本书中充满了对古典音乐等的描写,其中乐曲流动感的描写优美而形象,恰到好处的衬托了场景变化。
随着音乐改变,命运也不断跟随。
顺带一提,标题即来自在文中作为线索的帕格尼尼《无穷动》。

##黑化“女主”

因为我会按照这个步骤给你们人类安排好同样的结局。这是我的计划。我现在努力读书,大概就是为了将来这一天而作预备吧。

萧寒 钟与无穷动

即使身为天才,即使能够许下实现一切的愿望,他/她也逃不脱黑化和厄运。
穿越到你所想要的世界后,也许是孤身一人…
况且,他许下的荒谬愿望竟然得以实现。
这下男主相当尴尬了,好兄弟变妹了x

“呵呵,看来,在这个世界里你也会是一个真正的天才呢。”萧寒微笑着说道,“我一直等着你觉醒,总会有那么一天——这是我来到这个时代后惟一凭借信心和直觉来判断的事情了。可惜的是,当我高一再次和你分到同一个班级的时候,我遇到的是一个只会玩沙丁鱼游戏的大男孩。

萧寒 钟与无穷动

有时候,也许无知是另一种幸福,超过他人的能力,带来的并不一定是幸福。
天才,即是恩赐,也是痛苦,然而你并没有机会选择。
然而我只会发傻,莫得天才
不知你可曾听说过全知者悖论,全知者像西比拉一样,眼看着毁灭将临,却无法可想。

组织与自由

完全不情愿的男女主角,只想平静生活,却面临不断被追杀和加入“超常儿童与青少年培育计划”这个组织成为棋子的选择。
被曲灵芝嘲笑滥用能力的后果,却在否认中一次次成为现实。可摆脱这种“自由?是正确的选择么?

“天才”

“所以一般情况下我给自己设置一个自动感知的防御模式,在遇到其他早熟天才动用能力时,才自动启用先知能力。哎哟!”

萧寒 钟与无穷动

看到这段时候,我笑得像个操纵向量的孩子
天才也是另一方向的笨拙吧,一切都要付出代价,多少而已。

马鹿木头男主

这个算是轻小说套路了吧(x
不过也得看人用,况且本部男主即非白痴也非汤姆苏,也算和女主(bushi)对等。

安静的战争

也许无声的战争最可怕,更何况风暴中心还不自知。
开篇围绕男主妹妹的心战,成了最终解决的导火索。
为了自己的安全,成为小人,失去底线,值得么?这是个重要的问题…
夹杂的日常,反而加深了实感…

Gaojianli's avatar

即日起本站域名切换到gaojianli.me

一直以来,我都使用的是

问少's avatar

COM6516 Week04

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person {
String name;
String birth;

Person(String name, String birth) {
this.name = name;
this.birth = birth;
}

@Override
public String toString() {
return "Name: " + name + "\n" +
"Birth: " + birth;
}
}
Roy Binux's avatar

少女前线拖尸脚本 和 生成它的可视化工具

最近在玩少女前线,这是一个手机游戏,over。不是,就真的没有什么好讲的嘛,了解的人早有耳闻,不了解的就只要知道这是个手机游戏就好了,嗯。

然后,我会好好地,正常地,氪金地去玩这个游戏吗?不可能的,玩游戏哪有破解它有意思呢。当年破解 Ingress 是因为它用的 HTTPS 通信的,算是本行。百万亚瑟王是因为别人已经逆向好了,我只是写了一些 bot。现在这么办,玩不了了吗?作为一个不会安卓,不会逆向,不会汇编的菜鸡,那我只好上按键精灵了啊。于是乎,我找到了这个: AnkuLua

AnkuLua 是一個專注在自動化的Android App
基本自動化動作有:

  • 抓取螢幕並找尋指定圖案
  • 對找圖結果採取使用者要的動作(例如點擊、抓放(drag and drop)、打字…等等)

最重要的是,它能运行 lua 脚本!虽然我是一个不会安卓,不会逆向,不会汇编的菜鸡,但是我会 lua 啊。

ankulua-vision

不过,在使用过程中发现,找寻指定图案,需要不断截图/裁剪,这样太麻烦了。于是我又用 electron 做了一个可视化的截图资源管理器 ankulua-vision,像这样的:

基本思路就是,一般游戏是由众多 UI 界面组成的,点击某个按钮能跳转到某个界面上去。那么通过截图,标注识别区域,那么程序就能知道游戏现在所处的界面。通过标注按钮区域,那么只需要 goto('battle'),程序就能自动规划从当前界面到 battle 的可行路径,然后点啊点啊就完成需要的操作了。这样一方面不需要自己去裁剪图片了,另一方面通过框架代码,在运行过程中能够有更多的错误检查,自动应对可能出现的各种异常。

理论上,对于点啊点的游戏,是能实现无代码的。即使不能,对于复杂的动作,也可以通过 lua 拓展。

源码在这里:https://github.com/binux/ankulua-vision

你依旧需要在安卓手机或者模拟器中安装 ankulua,然后加载生成的 start.lua 脚本。默认自带了一个简单的循环逻辑,运行后可以直接图形化界面配置运行。当然你也可以通过 lua 脚本拓展,除了 ankulua 本身的 API 可用之外,你也可以使用 stateMachine 这套界面跳转逻辑 API,重用简化步骤。stateMachine 的 API 在 README 中有简略的文档说明。

源码使用 GPLv3 或 MIT 许可证,取决于第一个有效 PR(例如 fix typo 不算),如果第一个 PR 之前有商业化需求或者 PR 作者要求,则 MIT。

少女前线拖尸脚本

WARNING: 任何使用脚本的行为都是官方禁止的,我不对下文所述任何内容以及其后果负责

于是,这里就是 少女前线的拖尸脚本:

https://github.com/binux/binux_github_com/releases/download/gf/shojo.zip

同时它也是一个 ankulua-vision 的项目,你可以通过 ankulua-vision 打开这个项目目录,调整截屏或者按钮位置。

脚本实现的功能

  • 43e, 02, 52n 拖尸
  • 自动重启后勤
  • 自动强化或者分解人形
  • 自动修理

使用方法

  1. 根据 [填坑结束?][失了智]萌新向拖尸教学帖[更新8-1N相关] 一文准备好打手和阵型,一队练级队,二队补给队,52n 还需要 3 队狗粮队。
  2. 解压拷贝脚本到手机中,在 ankulua 中加载 start.lua。
  3. 在启动界面中选择你的两个打手(每轮结束后,两个打手会交换),选择拖尸任务,如果仅自动后勤,选择 null 就好了。

其中 52n 会在战斗中撤退 5, 8 号位 (见 NGA 文 “43e的说明” 展开部分),02 在选择 m4a1 时会撤退 1, 7 号位。

然后开始吧!

WARNING: 任何使用脚本的行为都是官方禁止的,我不对上文所述任何内容以及其后果负责

over

问少's avatar

COM6506 Week02

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
public class Person {
String name;
double weight;
double height;

public Person(String name, double weight, double height) {
this.name = name;
this.weight = weight;
this.height = height;
}

public String getName() {
return name;
}

public double getWeight() {
return weight;
}

public double getHeight() {
return height;
}

public static void main(String[] args) {
Person jeff = new Person("Jeff", 72.4, 2.2);
Person jim = new Person("Jim", 65, 1.7);
System.out.println("Jeff is " + jeff.getHeight() + "m tall.");
System.out.println("Jim is " + jim.getHeight() + "m tall.");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class BMICalculator {
Person person;

public BMICalculator(Person p) {
this.person = p;
}

public double calculateBMI() {
double bmi = person.getWeight() / (person.getHeight() * person.getHeight());
return bmi;
}

public static void main(String[] args) {
Person jeff = new Person("Jeff", 85.4, 1.9);
BMICalculator calculator = new BMICalculator(jeff);
System.out.println("Jeff's BMI is: " + calculator.calculateBMI());
}
}
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
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class BMICalculatorTest {
/*
* BMI should be somewhere between 20 and 30.
*/
@Test
void testPersonInNormalCategory() {
Person jeff = new Person("Jeff", 85.4, 1.9);
BMICalculator calculator = new BMICalculator(jeff);
double result = calculator.calculateBMI();
assertTrue(result > 20);
assertTrue(result < 30);
}

/*
* BMI should be zero
*/
@Test
void testWeightlessPerson() {
Person jeff = new Person("Jeff", 0, 1.9);
BMICalculator calculator = new BMICalculator(jeff);
double result = calculator.calculateBMI();
assertEquals(result, 0D);
}

/*
* BMI should be infinite
*/
@Test
void testHeightlessPerson() {
Person jeff = new Person("Jeff", 85.4, 0);
BMICalculator calculator = new BMICalculator(jeff);
double result = calculator.calculateBMI();
assertTrue(Double.isInfinite(result));
}
}
Kay's avatar

如何入门科学上网

每当我们希望通过 Facebook 与国际友人聊天,想在 Twitter 看川普吹嘘,或是想上 Youtube 看一段精彩的视频,又或是想上 Wikipedia 了解一个新事物……在国内正常的访问这些境外网站,通常只能会在漫长的等待后得到一个“404 Not Found”抑或是其他错误提示。这时候,我们的上网受到了 GFW 阻碍,为越过这道障碍,我们就需要科学上网。

何谓科学上网?

用较专业的说法,科学上网又叫做突破网络审查或突破网络封锁。指在中国大陆,突破防火长城(GFW)实行的网络审查,绕过互联网审查封锁技术(IP封锁、端口封锁、关键词过滤、域名劫持等),实现对网络内容的访问。又称为翻墙、穿墙、梯子、科学上网、魔法上网、爱国上网等。

为什么要科学上网?

作为一名BYR,众所周知,我们敬爱的前任校长方Sir,正是GFW之父。

作为北邮学子,在党的领导下,方Sir的带领下,我们要坚定不移地为共产主义事业奋斗终生,要毫不犹豫地维护方Sir的作品,坚决地站在方Sir的立场:中国应该着手建设国家网络边防,构建信息科技自主创新和信息技术方面的中国话语权,打造网络疆域保护体系,更好维护国家利益。

但是作为一名普通网民,在全球化的当下,我们需要与国际保持密切的联系,我们是否更应该一同呼吁网络自由。不可否认,GFW 的确挡住不少不好的网站,但与此同时国外大量高质量的信息和服务也被挡在了墙外,这迫使我们需要科学上网,才能让国外优质资源得以充分利用。

如何科学上网?

科学上网的方式有很多,以下介绍几种代表性的:

免费 VPN

如果你只是偶尔逛逛 Facebook,Instagram,或是几周才需要上一次 Google 搜索资料。免费的代理 VPN 软件已经可以满足你的需求了。这类软件基本只需要下载安装,或是再安装一个配置文件,即可运行,简单易用,是轻度用户的首选。

优点:操作简单,部分免费。

缺点:速度普遍较慢,容易掉线,可能限流,不太安全。

蓝灯(Lantern)是一款比较常见的基于 P2P 网络的开源 VPN 软件,抗封锁能力较强。有一定免费流量,可购买专业版。技术原理推荐阅读《蓝灯的历史和现状》

下载地址:官网(墙外),Github(墙内)。

Shadowsocks(R)

如果你经常访问墙外网站,并且对网络的速度或流量要求较高,免费 VPN 已经难以满足你的需求,那么不妨试试 SS/SSR。

优点:较稳定,启动快,速度可能较快(与服务器有关)

缺点:配置较麻烦,费用相对较高,可合租。

关于 SS or SSR 一直争论不休,推荐阅读《关于ShadowsocksR和Shadowsocks的安全性》,下文以 SS 为例。

Shadowsocks是一种基于 Socks5 代理方式的加密传输协议,分为服务器端和客户端。搭建需要三步:1.购买服务器;2.配置服务器;3.配置 Shadowsocks。由于环境和服务器不同,搭建的过程和搭好后的速度都将略有不同。服务器推荐 Vultr,一家美国新泽西的服务器运营商,全球有15个数据中心可供选择,最重要的是,资瓷支付宝。推荐一个较详细具体搭建的教程:点击进入

当然 SS 也不是万全之策,因为服务器 IP 也可能被墙。但只要删除服务器,再创建一个,换个 IP 基本就能解决。再不行就换个城市吧,东京最近被墙了不少。

肉身翻墙

办好护照,买张机票,说走就走……

优点:人都在墙外了。

缺点:费时费力费钱,移民是个好东西

推荐阅读

《科学上网翻墙教程》

在最后

梯子只是个工具,怎么使用尤为关键。梯子只是把你带到墙外,你获得了无限制自由访问墙外资源的能力。你可以用于刷FB,Twitter,也可以用于寻找优质学术论文,但是我们强烈不建议你将它用于一些不符合社会主义核心价值观的用途。

Kay's avatar

果园小学期的个人感想

很久之前就了解到会有这次小学期,听说是几个同学组成一组,完成一个代码量相对较大的程序。年轻气盛的我还满怀着期待 …

继续阅读“果园小学期的个人感想”

Gaojianli's avatar

树莓派添加温控风扇(二)

前言

上回说到,对于arm64的系统来说,目前并没有一个库可以支持对GPIO的调用。那么接下来摆在我面前的就三条路:

  1. 修改setup.c,让cpuinfo中包含相应的Hardware信息,随后重新编译内核
  2. 修改wiringPi源码
  3. 放弃使用库

可行的方法

上面三个选项中,1和2显然是极其不现实的,因此我决定采用第三条路。在之前那个issue中,我看到了这样一种用法:

Gaojianli's avatar

树莓派添加温控风扇(一)

前言

前不久不知道树莓派抽什么风,风扇的噪音突然变得奇大无比,弄得潇叫苦连连。虽然我亲自去听了之后觉得声音远远比不上他的神舟和那台安装了FreeBSD的古董机,但毕竟有求于人,这样下去也不是个办法。稍加分析不难得出,风扇声音大是因为24小时常开导致了积灰和磨损,尤其是前者更是难以避免。而我树莓派大部分时候都处于闲置状态,风扇其实是没必要24小时上线的。那么,能不能让风扇按需启动呢?这样一来可以改善噪音问题,同时树莓派困扰许久的供电不足问题也能够得到相应的改善。

Brian Lee's avatar

有向图

《Algorithm》(Sedgewick)笔记:有向图


术语

一幅有 方向性的图 (或

Brian Lee's avatar

并查集

《Algorithm》(Sedgewick)笔记:并查集


动态连通性

动态连通性

Brian Lee's avatar

广度优先搜索

《Algorithm》(Sedgewick)笔记:广度优先搜索


原理

遍历图G 时,要找到从sv 的最短路径,从s 开始,在所有一条边就可以到达的顶点中寻找v ,如果找不到就继续在与s 距离两条边的所有顶点中查找v ,如此一直进行。当两次寻找相遇时,合二为一。直到查找到最短路径。


相关问题

单点最短路径

给定一幅图和一个起点s ,回答“从s 到给定目的顶点v 是否存在一条路径?如果有,找出其中最短的那条”


实现

使用一个队列来保存所有已经被标记过但其邻接表还未被检查过的顶点。

先将起点加入队列,然后重复以下步骤直到队列为空:

  1. 取队列中的下一个顶点v 并标记它
  2. 将与v 相邻的所有未被标记过的顶点加入队列

搜索过程

  1. 首先将顶点0 标记并加入队列
  2. 从队列中删去顶点0 并将其邻居顶点215 标记、加入路径,并加入队列中
  3. 从队列中删除顶点2 并检查其相邻顶点,01 已被标记,将34 标记、加入路径并加入队列
  4. 从队列中删除顶点0 并检查其相邻顶点,发现已经全被标记,于是跳过
  5. 从队列中删除顶点5 并检查其相邻顶点,发现已经全被标记,于是跳过
  6. 从队列中删除顶点3 并检查其相邻顶点,发现已经全被标记,于是跳过
  7. 从队列中删除顶点4 并检查其相邻顶点,发现已经全被标记,于是跳过

代码

public class BFS {    private boolean[] marked;   //到达该顶点的最短路径是否已知    private int[] edgeTo;   //到达该顶点已知路径上最后一个顶点    private int s;  //起点    public BFS(Graph G, int s) {        marked = new boolean[G.V()];        edgeTo = new int[G.V()];        this.s = s;        bfs(G, s);    }    private void bfs(Graph G, int s) {        Queue<Integer> queue = new LinkedList<>();        marked[s] = true;   //标记起点        queue.offer(s);     //起点加入队列        while (!queue.isEmpty()) {            int v = queue.poll();   //从队列中删去下一顶点            for (int w : G.adj(v)) {                if (!marked[w]) {   //对每个未被标记的相邻结点                    edgeTo[w] = v;  //保存最短路径的最后一条边                    marked[w] = true;   //标记它,因为最短路径已知                    queue.offer(w); //将它添加到队列中                }            }        }    }    public boolean hasPathTo(int v) {        return marked[v];    }    public Iterable<Integer> pathTo(int v) {        if (!hasPathTo(v))  return null;        Stack<Integer> pathReverse = new Stack<>();        for (int x = v; x != s; x = edgeTo[x])            pathReverse.push(x);        pathReverse.push(s);        Queue<Integer> path = new LinkedList<>();        while (!pathReverse.isEmpty())            path.offer(pathReverse.pop());        return path;    }}

DFS与BFS区别

  • 深度优先搜索搜索一幅图的方式是寻找离起点更远的顶点,只在碰到死胡同时才访问近处的顶点;广度优先搜索会首先覆盖起点附近的顶点,只在临近的所有顶点都被访问了之后才向前进。
  • 深度优先搜索不断深入图中并在栈中保存了所有分叉的顶点;广度优先搜索则像扇面一样扫描图,用一个队列保存访问过的最前端的顶点。
  • 深度优先遍历算法借助于 结构实现;广度优先遍历算法借助于队列 结构实现。

源代码

https://github.com/XutongLi/Algorithm-Learn/tree/master/src/S4_Graphs/S4_1_Undirected_Graph/S4_1_5_Breadth_First_Search


Brian Lee's avatar

深度优先搜索

《Algorithm》(Sedgewick)笔记:深度优先搜索


原理

要搜索一幅图,用一个递归方法来遍历所有顶点。在访问其

Brian Lee's avatar

无向图

《Algorithm》(Sedgewick)笔记:无向图


定义

无向图是由一组顶点和一组能够将两个顶点相连的边组成的。边仅

Brian Lee's avatar

散列表

《Algorithm》(Sedgewick)笔记:散列表


原理

在记录的存储地址和它的关键字之间建立一个确定的对应关系;这

Brian Lee's avatar

二分查找树

《Algorithm》(Sedgewick)笔记:二分查找树


原理

一棵 二叉查找树

Brian Lee's avatar

二分查找

《Algorithm》(Sedgewick)笔记:二分查找


原理

  • 在数组有序的前提下
  • 先将被查找的键和子数组的中间键比较,如果被查找的键小于中间键,就在左子数组查找,大于就在右子数组查找,否则中间键就是要找的键
  • 若表中存在该键,则返回该键的位置
  • 否则返回小于该键的元素数量

时间复杂度

$O(logN)$

分析

令 $C(N)$ 为在大小为 $N$ 的数组中查找一个键所需进行的比较次数。

显然有 $C(0) = 0$ 、$C(1)=1$

对于 $N>0$ 可得到归纳关系式:

$C(N)\leq C(\lfloor N/2 \rfloor)+1$

无论查找会在中间元素的左侧还是右侧继续,子数组大小都不会超过 $\lfloor N/2 \rfloor$ ,需要一次比较来检查中间元素和被查找的键是否相等,并决定继续查找左子数组还是右子数组。

当 $N=2^n-1$ 时,$\lfloor N/2 \rfloor=2^{n-1}+1$ ,

迭代得:

$C(2^n-1)\leq C(2^0)+n$

得:$C(N)=C(2^n)\leq n+1<lgN+1$


图示


代码

非递归

public static int binarySearch (int[] integer, int n, int key) {        int low = 0;        int high = n - 1;        while (low <= high) {            int mid = (low + high) / 2;            if (key < integer[mid]) {                high = mid - 1;            }            else if (key > integer[mid]){                low = mid + 1;            }            else {                return mid; //查找到            }        }        return low;  //未查找到,返回比其少的元素数量    }

递归

public static int search (int[] integer, int key) {        int lo = 0, hi = integer.length - 1;        return binarySearch(integer, key, lo, hi);    }public static int binarySearch (int[] integer,  int key, int lo, int hi) {        if (lo > hi)            return lo;    //未查找到,返回比其少的元素数量        int mid = (lo + hi) / 2;        if (integer[mid] == key)            return mid;        else if (integer[mid] > key)            return binarySearch(integer, key, 0, mid - 1);        else            return binarySearch(integer, key, mid + 1, hi);    }

源代码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S3_Searching/S3_1_SymbolTables/S3_1_5_BinarySearch/BinarySearch.java


Brian Lee's avatar

TopK问题

Topk 问题,即求得 N 个乱序元素中第 k 大(小)的元素,是一个很经典的问题。在此文章中,我总结了自己对此问题的思路。


思路

Dimpurr's avatar

钉子的谜之 SETUP 18 @ Ningen

本文原载于 人间 / Dimpurr Cheny ,前文 钉子的谜之 SETUP (2014) 。

?‍? 简要介绍一下自己,并且谈谈正在做什么?

这里钉子,现役帝都大学生。曾经写写画画做过不少事情,当过宅圈内知名前端博主,设计过几个流行的 WordPress 主题,发起过一点音乐社区相关小项目,都已经成为过去。大一以来,唯一的成就是为了拯救北邮人技术组废部危机,不得不成为偶像,建立了 BYRIO 开源社区。目前在选择遵循自己内心去做游戏设计和编曲,还是顺应他人期待继续在 CASIA 和 MSRA 的 ML 搬砖日常前犹豫不决。

? 你使用的硬件有?

主役 MacBook Pro + Surface Pro ,经常同时携带 (虽然很重) ,前者用于影音处理、工程开发、平面设计、绘图板画画 (Wacom Intuos PTM CTH680) ,后者用于 PDF 阅读和批注、 OneNote 笔记、 Surface Pen 作画、推 Gal 和小游戏 (V-A HALL, FrostPunk) 。 Surface Pro 虽然性能有限,但是在轻薄的前提上能让自己在任何时空基本具备进行任何工作的能力。

宿舍配备 Linksys WRT1900AC v1 用于享受百兆校园网 (IPv6 免流 + 学校网络中心成员特权套餐) ,一块 26’ DELL UltraSharp Monitor U2415 外接屏一般连接 MBP 用于宿舍组团看 Rick and Morty 或少女歌剧、瀑布流展示作画和人体结构参考资料、工作时看论文和文档等,计划接上 Switch Dock 之后用来在宿舍玩舞力全开。配置 MIDIPLUS X6 键盘 + ATH-AD2000X 开放式大耳用于演奏。

随身 Sony XPERIA XZ1 ,佩戴 Moto 360 。 SHURE SE846 耳塞退烧,前端 iBasso DX90 和耳放 Sony PHA3 常年借给同学。 iPad mini 用于音游 (Cytus II, Arcera, Groove Coaster, Dynamix) , Nintendo Switch 用于 Party Game (分手厨房) 和沉迷死喷浪涂 (Splatoon) 。

? 你使用的软件有?

常年 macOS, Windows 和 Linux 跨平台用户,曾经是 OpenSUSE 党。 macOS 下剪贴板历史 Paste 和快速访问 Spotlight 重度用户, Win 对应工具是 Ditto 和 Keypirinha 。所有常用 App 必须选择跨平台解决方案, 必备滴答清单 + SimpleList 。日常 IM Telegram 和 QQ ,偶尔用 HexChat 挂 IRC 。念念不忘的 Mac 独占 App 有 Sketch, GarageBand, Agenda, OmniFocus 和 XLD 。念念不忘的 Win 或者 Unix 独占 App 没有,非要说的话 PC 游戏。

曾经 Sublime Text 2 党,如今 Visual Studio Code 忠实用户,必备插件是 background 自带魔理沙背景 + GitLens 。终端分别 iTerm2 和 Cmder / MobaXTerm 。 macOS 下用 SourceTree 做 Git GUI ,用 MAMP PRO 做服务器测试环境。写作环境 ByWord 和 Typora ,设计主 Sketch 辅 Axure 和 PhotoShop ,偶尔用 Illustrator 描矢量画或者 InDesign 做小册子。剪辑一般用 Final Cut Pro 或者 Premiere 。三维制作 3DS MAX 和 Blender 。

主要用 CLIP STUDIO PAINT 作画,新的拟真铅笔手感非常好。有时候会使用 Krita , Tyson 大大绘制的 Kiki 启动屏幕非常可爱,自带的丰富笔刷和镜像画笔等功能很能激发创作灵感, BYRIO 社区还组织参与过 Krita 中文文档的翻译工作,在此安利。

? 你梦想中的设备是怎么样的?

梦想是巨硬让 Surface Pro 性能、品控和售后再好一点,水果让 MacBook Pro 再便宜一点,索法不要搞 XZ2 这种歪门邪道好好出 XZP 这种全平衡侧面指纹带耳机孔的好手机。离开大学宿舍后可能会对个人工作站的设备有新的愿望,目前暂时并没有什么其他的梦想。

? 以下附图。

Surface Pro 桌面

Surface Pro 开始

MacBook Pro 桌面

MacBook Pro LaunchPad

本文来自 钉子の次元 - Dimpurr - 千里之行,始於足下。 ,原文地址 钉子的谜之 SETUP 18 @ Ningen

Brian Lee's avatar

排序算法总结

《Algorithm》(Sedgewick)笔记:排序算法总结


比较

算法是否稳定是否为原地排序最好时间平均时间最坏时间辅助空间
选择排序$O(n^2)$$O(n^2)$$O(n^2)$$O(1)$
插入排序$O(n)$$O(n^2)$$O(n^2)$$O(1)$
冒泡排序$O(n)$$O(n^2)$$O(n^2)$$O(1)$
希尔排序$O(n^{1.3})$$O(1)$
归并排序$O(nlogn)$$O(nlogn)$$O(nlogn)$$O(n)$
快速排序$O(nlogn)$$O(nlogn)$$O(n^2)$$O(logn)$
堆排序$O(nlogn)$$O(nlogn)$$O(nlogn)$$O(1)$

稳定 : 如果一个排序算法能够保留数组中重复元素的相对位置则可以被称为是稳定的。

原地排序 :原地排序就是指在排序过程中不申请多余的存储空间,只利用原来存储待排数据的存储空间进行比较和交换的数据排序。


一些结论

快速排序时最快的通用排序算法,因为它内循环中的指令很少,而且可以利用缓存。在使用三向切分之后,快速排序对于实际应用中的可能出现的某些分布的输入变成线性级别。

如果稳定性很重要而空间又不是问题,归并排序可能是最好的。

当n较小时,如(n<50),可采用直接插入或简单选择排序,前者是稳定排序,但后者通常记录移动次数少于前者

当n较大时,应采用时间复杂度为 $O(nlgn)$ 的排序方法(主要为快速排序和堆排序)

当n较大时,为避免顺序存储时大量移动记录的时间开销,可考虑用链表作为存储结构(如插入排序、归并排序、基数排序)


源代码

https://github.com/XutongLi/Algorithm-Learn/tree/master/src/S2_Sorting


Brian Lee's avatar

堆排序

《Algorithm》(Sedgewick)笔记:堆排序


原理

  • 使用一个面向最大元素的优先队列并重复删除最大元素
  • 分为两个阶段:堆的构造阶段下沉排序阶段

复杂度

时间复杂度

$O(NlogN)$

空间复杂度

$O(1)$


堆的构造

目的

将原始数组重新组织安排进一个堆中

实现

  • 可以从左到右遍历数组,将各元素插入堆中,每次插入后用swim()保证堆有序。时间复杂度为 $O(NlogN)$
  • 另一种更高效的方法是从右至左用sink()构造子堆。如果一个结点的两个子结点都已经是堆了,那么在该结点上调用sink()可以将它们变成一个堆。这个过程会递归地建立起堆。时间复杂度为 $O(N)$ 。在此我们采用这种方法。

图示


下沉排序

目的

从堆中按递减顺序取出所有元素并得到排序结果

实现

将堆中的最大元素删除,然后放入堆缩小数组后空出的位置

时间复杂度为 $NlogN$

图示


代码

public static void sort(Comparable[] a) {        int N = a.length - 1;        //构造堆        for (int k = N / 2; k >= 1; k--)            sink(a, k, N);        //下沉排序        while (N > 1) {            exch(a, 1, N--);            sink(a, 1, N);        }    }    private static void sink(Comparable[] a, int k, int N) {        while (2 * k <= N) {            int j = 2 * k;            if (j < N && less(a, j, j + 1))                j++;            if (!less(a, k, j))                break;            exch(a, k, j);            k = j;        }

排序过程


优缺点

优点

  • 是唯一能够同时最优地利用空间和时间的方法
  • 对记录数较大的文件很有效

缺点

  • 无法利用缓存。数组元素很少和相邻的其他元素进行比较,因此缓存未命中的次数要远远高于大多数比较都在相邻元素间进行的算法

源代码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/S2_4_5_HeapSort/HeapSort.java


Brian Lee's avatar

堆与优先队列

《Algorithm》(Sedgewick)笔记:堆与优先队列




Brian Lee's avatar

快速排序

《Algorithm》(Sedgewick)笔记:快速排序


原理

  • 快速排序是一种分治的排序算法
Kay's avatar

食其家の丼

食其家 食其家1982年创立于日本横滨,是以牛丼作为主力商品的快餐连锁店。在上海、江苏、浙江、北京、天津、广东等都有直营店。在北京门店并不多,一共6家,我这次去的是海淀区的翠微凯德MALL店。

关于丼

丼在汉语中:1、jǐng同“井”。2、dǎn 一为投物井中所发出的声音;二作姓。宋 邵思《姓解》卷一:“丼,蕃姓也” 而在日语中:可以指盛装饭或面的食具,又称丼钵;丼物,以碗盛装的饭上浇盖各式食材的日本庶民料理;另一则为投物井中所发出的声音。 所以食其家的丼应该就可以理解为日本盖浇饭的意思。日本最普遍的五大丼为GYUDON(牛丼)、KATSUDON(胜丼)、OYAKODON(亲子丼)、TENDON(天丼)及UNAGIDON(鳗丼)。而食其家以牛丼为主,也有鳗丼。

这家店

店面不大,是那种开放式的,正常的快餐店吧。桌子中间有个小架子,放着菜单、餐具、餐巾和酱料,旁边还有个服务铃。入店落座后,服务员会先上一杯茶,比起一般的快餐店,食其家的服务会稍好一些。值得一提的是食其家并不是先买单后用餐的,而是先用餐再买单的(导致了我忘了买单,尴尬地被叫了回去)。

这一餐

点得算是比较多。
牛肉/鳗鱼双拼丼
牛肉拌着酱汁渗入米饭里,感觉可以说是不错了。牛肉比较薄,肥瘦相间,既有脂肪饱和的口感,又不至于太腻。烤鳗鱼的口感也不错,入口有蒲烤的香,细嚼有鳗鱼的鲜。但是内侧脂肪有点多,口感有点油腻。
温泉蛋
调味裙带丝
章鱼小丸子
虽长得不怎么好看,盘也没码好,但味道还行。

在最后

之前也吃过别的食其家,相比之下,这家的环境不算好,可能是地段位置的原因。菜品都差不多,毕竟都是直营店,都是正常的日本快餐。服务的话,说不上很好,但由于普通的快餐店。
Brian Lee's avatar

归并排序

《Algorithm》(Sedgewick)笔记:归并排序


原理

Brian Lee's avatar

希尔排序

《Algorithm》(Sedgewick)笔记:希尔排序


原理

  • 改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序
  • 希尔排序的思想是使数组中任意间隔为h的元素都是有序的,这样的数组被称为h有序数组。换句话说,一个h有序数组就是h个互相独立的有序数组编织在一起组成的一个数组

复杂度

时间复杂度

不超过$O(n^2)$ ,当$n$ 较大时,比较和移动次数约在$n^{1.25}$ 到$1.6n^{1.25}$

空间复杂度

$O(1)$


图示


代码

public static void sort(Comparable[] a) {        int N = a.length;        int h = 1;        while (h < N / 3)            h = 3 * h + 1;        while (h >= 1) {            //分别进行插入排序            for (int i = h; i < N; i++) {                for (int j = i; j >= h && less(a[j], a[j - h]); j -= h)                    exch(a, j, j - h);            }            h = h / 3;        }    }

上述代码使用了序列$\frac{1}{2}(3^k-1)$ ,从$N/3$ 开始递减至$1$

序列计算:

$h_{k+1}=3\times h_k+1 (h_1=1)$

$h_{k+1}+\frac{1}{2} = 3(h_k+\frac{1}{2})$

$\therefore h_k+\frac{1}{2}= \frac{3}{2}\times 3^{k-1}$

$\therefore h_k=\frac{1}{2}(3^k-1)$


特点

  • 希尔排序更高效的原因是它权衡了子数组的规模和有效性
  • 时间复杂度取决于N与增量序列
  • 如何选择最佳增量序列,目前尚未解决,但最后一个增量值必须为1,且避免增量序列中的值(尤其是相邻的值)有公因子

源码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/S2_1_6_ShellSort/ShellSort.java


Brian Lee's avatar

冒泡排序

算法笔记:冒泡排序


原理

  1. 比较相邻的元素,如果第一个比第二个大,交换这两个元素
  2. 对每一对相邻元素进行同样的工作,从开始第一对到结尾最后一对。这步做完后,最后的元素会是最大的数
  3. 重复以上步骤,除了已选出的元素,直到没有任何一对元素需要比较,则序列有序

复杂度

时间复杂度

$O(n^2)$

空间复杂度

$O(1)$


图示


代码

实现一

最优情况$O(n^2)$

public static void sort(Comparable[] a) {        int N = a.length;        for (int i = 0; i < N; i++) {            for (int j = 1; j < N - i; j++) {                if (less(a[j], a[j - 1]))                    exch(a, j, j - 1);            }        }    }

实现二

最优情况$O(n)$

优化点 :由于冒泡排序要遍历整个未排好的部分,如果在整个排序过程中没有交换,我们就可断定列表已经排好。因此可以改良冒泡排序,使其在已知列表排好的情况下提前结束。

public static void sort2(Comparable[] a) {        int N = a.length;        boolean isExch = true;        for (int i = 0; i < N && isExch; i++) {            isExch = false;            for (int j = 1; j < N - i; j++) {                if (less(a[j], a[j - 1])) {                    exch(a, j, j - 1);                    isExch = true;                }            }        }    }

实现三

最优情况$O(n)$

优化点 :记录已排好序的位置,之后的遍历到此位置就可以停止。

public static void sort3(Comparable[] a) {        int N = a.length;        boolean isExch = true;        int tail = N, temp = N;        for (int i = 0; i < N && isExch; i++) {            isExch = false;            for (int j = 1; j < tail; j++) {                if (less(a[j], a[j - 1])) {                    exch(a, j, j - 1);                    isExch = true;                    temp = j;                }            }            tail = temp;        }    }

特点

  • 每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值

源码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/Others_Bubble_Sort/Bubble.java


Kay's avatar

初入股市的一点想法……

成年以来,我尝试了许多以前因为各种原因不能做的事情,其中一样就是炒股。

如何入门炒股

首先得选择一家靠谱的证券公司。何谓靠谱的证券公司?看看中国证监会公布2018年证券公司分类结果吧。而我选择了AA级的广发证券,大概是因为在广东比较有名。关于广发证券与广发银行,广发证券的前身是1991年9月8日成立的广东发展银行(简称广发银行)证券部。1993年末,作为广发银行子公司的广东广发证券公司正式成立。2001年,通过增资扩股,改制为广发证券股份有限公司,广发银行仍作为其第一大股东。1999年5月,根据银证分离的要求,广发银行将广发证券股权全部转让出去,成为两个完全独立的公司。
然后开一个股票账户。可以带好身份证等证件去最方便的营业部开户,但广发证券实现了非常便捷的线上开户。下载APP,填写和上传一些资料,阅读并同意一些条款后,就可以注册上交所和深交所的账户了,按规定开户费用是深圳证券账户50元,上海证券账户40元,共90元,但是有些营业所直接垫付了,不需要交开户费,还有些是交部分开户费,而我开户的营业部是先帮我垫付了,说是销户的时候再交,大概是想防止用户流失吧。
再之后就该注入资金了,先绑定银行卡,再银行转证券,然后就能看到资金转入了账户中的现金。
有了现金,就该选一只股票了。至于怎么选,那就太深奥了。投资有风险,入市需谨慎。选好后就可以买入了,可以选择合适的买入价格和买入数量。国内是以100股为一手,交易的最小单位也是一手,也就是说最少也要买100股。对于像我一样的小白来说,最好先从低价的,稳健的,少量的股票入手,先试试水。还有国内的交易时间是工作日的早上9:30-11:30和下午1:00-3:00,其他时间可以先委托。可以使用一些软件来分析股票,像同花顺、大智慧。

初入股市

前一天晚上抱着试试的心态,以3.65的价格委托买入天津松江(600225)一手,也就365元。第二天,几番波动后,竟然涨停了!第一次买股票就涨停,还行。之后,我选择了见好就收,在T+1日就以4.16的价格卖出了。算了一下,盈利51元,也就一顿饭钱吧,毕竟只投入了300+r。设想一番,如果投入的是三百万,就能赚一辆不错的轿车了。股市还是挺刺激的。初入股市,小获成功。

Brian Lee's avatar

插入排序

《Algorithm》(Sedgewick)笔记:插入排序


原理

  1. 将每一个元素插入到其他已经有序的元素中的适当位置
  2. 为了给要插入的元素腾出空间,需要将其余所有元素在插入之前都向右移动一位

复杂度

时间复杂度

$O(n^2)$

空间复杂度

$O(1)$


图示


代码

public static void sort(Comparable[] a) {    int N = a.length;    for (int i = 1; i < N; i++) {        for (int j = i; j > 0 && less(a[j], a[j - 1]); j--)            exch(a, j , j - 1);    }}

特点

  • 插入排序所需要的时间取决于输入中元素的初始顺序
  • 插入排序对于部分有序数组十分高效,也很适合小规模数组

源码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/S2_1_3_Insertion_Sort/Insertion.java


Brian Lee's avatar

选择排序

《Algorithm》(Sedgewick)笔记:选择排序


原理

  1. 找到数组中最小的那个元素
  2. 将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)
  3. 在剩下的元素中找到最小的元素,将它与第二个元素交换位置
  4. 直到将整个数组排序

复杂度

时间复杂度

$O(n^2)$

空间复杂度

$O(1)$


图示


代码

public static void sort(Comparable[] a) {        int N = a.length;        for (int i = 0; i < N; i++) {            int min = i;            for (int j = i + 1; j < N; j++) {                if (less(a[j], a[min]))                    min = j;            }            exch(a, i, min);        }    }

特点

运行时间和输入无关

有序数组或值全部相等的数组和一个元素随机排列的数组所用的排序时间一样长。

数据移动最少

每次交换都会改变两个数组元素的值,因此选择排序用了N次交换,交换次数和数组的大小是线性关系。其他任何排序算法都不具备这个特性。


源码

https://github.com/XutongLi/Algorithm-Learn/blob/master/src/S2_Sorting/S2_1_2_Selection_Sort/Selection.java


Brian Lee's avatar

背包

《Algorithm》(Sedgewick)笔记:背包

目的

帮助用例收集元素并迭代遍历所有收集到的元素。用例也可以检查背包是否为空或者获取背包中元素的数量。

特点

  • 迭代的顺序不确定且与用例无关
  • 不支持从中删除元素

API

public class Bag<Item> implements Iterable<Item>

Bag()创建一个空背包
void add(Item item)添加一个元素
boolean isEmpty()背包是否为空
int size()背包中的元素数量

实现

public class Bag<Item> implements Iterable<Item> {    private class Node {        Item item;        Node next;    }    private Node first;     //栈顶    private int N;          //元素数量    public boolean isEmpty() { return N == 0; }    public int size() { return N; }    public void add(Item item) {        Node oldFirst = first;        first = new Node();        first.item = item;        first.next = oldFirst;        N ++;    }    public Iterator<Item> iterator() {        return new ListIterator();    }    private class ListIterator implements Iterator<Item> {        private Node current = first;        public boolean hasNext() { return current != null; }        public void remove() { }        public Item next() {            Item item = current.item;            current = current.next;            return item;        }    }}

源码地址

https://github.com/XutongLi/Algorithm-Learn/tree/master/src/S1_foundation/S1_3_BagQueueStack/S1_3_3_10_Bag

Kay's avatar

2018 BUPT Summer Training #1 (恢复训练) 部分题解(仍会更新)

原题链接 A. Treasure Island Time limit: 2000 ms Memory limi …

继续阅读“2018 BUPT Summer Training #1 (恢复训练) 部分题解(仍会更新)”

via these people and places