Recent Posts

櫻川 浅羽's avatar

擦肩而過的 Nikon F100

偶然機會,淺羽看到一臺成色還可以的 Nikon F100,連着 MB-15 手把就一起收下了。按說這樣定位的準專業機身,以現時 HK$2000 不到的售價,應該是非常抵用的。只是非常可惜,淺羽手上的這臺的視度無法調節,並且觀景器中可以隱約看到一條黑色痕跡。淺羽檢查反光鏡和對焦屏之後,簡單判斷應該是目鏡組上的劃痕。這樣推測可能是目鏡組受到撞擊,因此留下劃痕並導致無法調整視度。雖然大致清楚原因,但因爲無法自行維修,只得放棄送回。
櫻川 浅羽's avatar

便宜大碗的自由,X220 的生產力煉成之路

Mentor 換工作地點,走前給了淺羽一塊珍藏的 ThinkPad X220。淺羽隨意檢查了一下,發現竟然還可以正常使用,只是電池壽命比較低。小小驚喜之後,淺羽打算把這塊 ThinkPad X220 作爲 Toy Machine。
櫻川 浅羽's avatar

人像攝影棚拍活動

這次人像棚拍活動算是淺羽接觸過的最大型、(時間)緊張的人像攝影活動了。在預算和精力等的限制下,結果算是淺羽滿意的,當然活動舉辦方也是表示滿意的。事後回看,有留下一些遺憾,但也積攢了不少經驗。
icebound's avatar

2019小学期作业反思

低下头,看看自己有多么菜 瞎写的 这次小学期真的是让我身心俱疲。在睡了将近十二个小时后,我爬起来上了两节互联网 […]
櫻川 浅羽's avatar

斷捨離 | 紀念 iPad Air 2 君

隨緣掛二手許久,淺羽最終還是出掉了 iPad Air 2。

淺羽最初入手 iPad Air 的目的是玩音樂遊戲。在 2015 年的冬天,大部分的 Android 手機雖然效能都沒什麼問題,但觸摸總是有一些延遲;當時淺羽的主力 Xperia Z Ultra 也不例外。彼時淺羽最便攜的數位產品,除了 6.44″ 的巨型手機外便是 MacBook Pro 13″。偶然借用同學的 iPad Air 玩了一個月,淺羽體會到了 10 吋玻璃板子在娛樂和閱讀的方便之處,於是緊接着的下一個月也入手了——一臺 Surface 3。在 iPad 還沒有 Smart Keyboard Cover 和 Apple Pencil 的年代,淺羽下單時主要考慮到 TypeCover 和 Surface Pen的生產力10 吋的便攜性USB 接埠的擴展潛力以及補足缺失的 Windows 生態。Surface 3 用着也很舒服,並且一度成爲淺羽的主力 Windows 裝置;但它雖然生產力強悍,娛樂上卻相當弱勢。結果的就是沒幾個月後,淺羽再度下單 iPad Air 2。

雖說一開始是爲了音樂遊戲而購入 iPad,並且也玩過了 Cytus、Deemo、ユビート等不少知名遊戲,但最終淺羽卻發現了 iPad 在生活中的其他便利之處。由於一開始就考慮到了導航的問題,淺羽入手的時候選擇了 Wi-Fi + Cellular 版。香港購買的 iPad 自然使用 CSL 和 Smartone 都不是問題,而令淺羽驚喜的是在大陸使用中國聯通和中國電信都很自然流暢;唯獨只能接收不能發送簡訊、也不能打電話略微限制了 iPad 的用途。除去內建的導航所需的 GPS+GLONASS 和數位羅盤,隨時上網的特性也大大方便了迷路時掏出 iPad 快速確認,省去了開熱點的麻煩和擔心手機電量的擔憂

肥宅快樂玻璃板

iPad Air 2 勤懇跟隨淺羽服役了幾乎四年,雖然本身也有換代的 iPad Air 3 可選,但依然歷久彌新。是說,數位產品一貫是買新不買舊,但 Apple A8X 看起來也沒比新的 iPad 使用的 A10 Fusion 落後多少嘛!其實它本身的優點是不少的,比如即使放到四年後的今天依然輕薄,握在爪子裏並沒有感到太多的重量,而且平衡感非常好。這一點甚至超越了淺羽現役的主力小米平板 4 和 HP Chromebook x2 的平板部分。由於本身配備的 Retina 螢幕觀感非常舒服,加上更新後的 Hand-off 和 AirDrop 功能也能和 Mac 無縫銜接,淺羽也開始在碎片時間使用 iPad 瀏覽網頁,並且用 Photos 應用管理和展示照片。同時淺羽還購入了 GoodReader 和(限時免費的)Reeder 3,讓 iPad 與 E-Ink 相互補充,接管數位閱讀。最終在淺羽開始使用 Logic Pro X 和 MainStage 之後,沒有多塊熒幕的淺羽只得求助 Logic Remote,原本爲娛樂而下單的 iPad 最終也成爲了生產力工具。

Apple 的生態系統大計幾近實現,但這時淺羽的 iPad 和 Mac 都面臨着換代的問題。2014 款的 MacBook Pro 雖然效能還不算差,但因爲預算限制而購入的「乞丐版」只配備了 128G 的固態硬碟,顯然無法應付中度到重度的行業使用;四年之後的 2018 年,換新又沒有中意的款式,而更換 SSD 依然價格較高。權衡之下,趁着廠牌還比較保值,淺羽直接轉手了除掉 iPad 外的所有 Apple 產品和附件。而這時的 iPad 作爲淺羽唯一還在蘋果生態系統中的半隻爪子,也面臨着類似的問題:使用沒有大問題但不順暢,更新又嫌棄貴。而即使下定決心更新,iPad Air 3 與 iPad Pro 之間,各有千秋,難以抉擇

隨着淺羽生活重心的轉移,淺羽已經不會滿城市到處亂竄了。而即使旅遊的時候,便宜大碗的小米平板 4 LTE 也可以很好地滿足淺羽的需要。加上 Android 系統本身和生態的進步,即使是一向弱勢的平板領域,淺羽也會考慮同樣的作業系統。更換了更小的手機、補齊了 7 吋的小平板和 12 吋大平板之後,中間 9.7 吋的 iPad 卻受到了冷落;雖然配上了 Logitech K380,最終變成了桌面上的 RSS 閱讀器和 Telegram 聊天機,外加 iPad OS 體驗機。

既然「斷捨離」就找個理由。聊 Telegram 只有 iPad 能做嗎?不是,甚至 iPad 還不是體驗最好的那一個。所以 iPad 至此,已經對淺羽沒有太實際的用處,更遑論更新換代了。唯一不下的,大概只有玩音樂遊戲的低延遲體驗了。

最後,還是放一張和 iPad Air 2 的合影吧(雖然並沒有淺羽的臉)。

最後一次看着這臺 iPad 重新開機
linkthis's avatar

Munin配置

多看README。
櫻川 浅羽's avatar

堅果 Pro 2S 的美好與極致強迫症

錘子科技說起來是個很長很長的故事,但這個故事已經落下帷幕了。不過,過去的幾年,錘子還是留下了 Smartisan OS 這款個性鮮明的定製 Android,以及幾款同樣個性鮮明的手機。從最開始的 T1、T2 和 T3,到所謂的「恥辱」 M1 和 M1L,再到可謂收山之作的堅果 3、堅果 Pro 2S 和堅果 R1,雖然它們始終只是少數人的玩物,但依然都有自己的獨特亮眼之處。
Kay's avatar

Computational Literary Analysis on Jane Eyre

About the project This is a final project of course Introduction to Computational Literary Analysis at 2019 UC Berkeley Summer School, instructed by Jonathon Reeve. Course repository link: https://github.com/JonathanReeve/course-computational-literary-analysis Introduction Jane Eyre is a novel by English writer Charlotte Brontë, published under the pen name “Currer Bell”, on 16 October 1847. Jane Eyre follows the …

Continue reading "Computational Literary Analysis on Jane Eyre"

櫻川 浅羽's avatar

讓 MIUI 真正好用:國際版加入小米支付與 Google Camera

小米 MIX 2 作爲小米的一代經典,即繼承了 MIX 系列的特別的家族外觀和材質,又擁有旗艦級別的硬體。小米自家的 MIUI 在治療國產毒瘤的方面頗有成效,而且米呸的在地化做得顯然比 Apple Pay 要好不少。所以當淺羽的公交卡被親姐要走之後,思來想去,還是用約 CNY 1,300 的價格入了一臺全陶瓷月光白尊享版的小米 MIX 2,最起碼可以把深圳通和嶺南通都放進手機裏。但是 MIUI 被稱爲 ADUI 不是完全沒有道理的,正值小米 MIX 2 獲得基於 Android P 的 MIUI 10.4 更新,折騰一番灌入國際版自然是少不了的。
櫻川 浅羽's avatar

真香隨身地圖機,小米平板 4 LTE 頂配開箱及動手玩

淺羽一直想要一臺中尺寸的玻璃板子作爲地圖,解決一下路癡問題。當時是 2015 年,淺羽試過友人的 iPad Air 後,覺得各方面的體驗都還不錯。當年下半年,淺羽就入手一台 iPad Air 2 64G Cellular + Wi-Fi。過了這麼多年,iPad 依然可以滿足輕量使用,只是略顯卡頓的系統和巨大的發熱,讓淺羽有了換機的想法。前思後想,既然現在的 iPad 還能用,不如再入一臺小的 Android 平板,高低搭配使用吧。
櫻川 浅羽's avatar

SONY Xperia 1 Joy 擼背殼硬質保護套開箱

一直以來淺羽對保護套的追求是以沙雕好看爲主,這樣馬雲家就有很多很可愛的手機殼可選,而且想湊情侶款也容易得很。

沙雕芝麻狐全家福

這種廉價背殼對付後置指紋就是開個孔,也沒什麼可說的;但如果是 SONY 一樣的側面指紋,那麼要麼背殼取消掉一邊放棄保護,要麼指紋體驗就要受到影響了。另外很多保護套的手感本身就很有問題,所以淺羽偶爾還是有換個背殼的想法。既然要買買買,那麼當然先看看 RASTABANANA 和 Devilcase 之類的,不過因爲實在是窮困所以都沒有下手。偶然看到 Joy 擼背殼出了 Xperia 1 保護套,價格在 CNY 56 左右尚可接受,乾脆就下單了。

Joy 擼背殼是 @[email protected] 爲了證明自己是個索粉親自操刀爲 SONY Xperia 系列準備的背殼。具體到 Xperia 1 來說,它的邊框是 TPU 材質有三種顏色以適配 Xperia 1 的四種配色(就哪裏不對?);後蓋則都是硬質 PC 塑料,並且還分爲磨砂和透明兩種後蓋。紫色款一開始還沒有磨砂款,據說是因爲「不搭」,後來還是乖乖加推了。

按鍵部分是單獨可以活動的,這樣保證了明確的按鍵反饋感,但採用了撞色設計……撞色其實也很有個性,但是紫加橙和紫加綠配色方案實在是太神奇,略微超過了淺羽的就接受範圍。而且各色的按鍵還不能單買,客服又愛搭不理的也死活不願意正面回答問題。正好趕上買三支包郵的店鋪活動,所以乾脆買紫色的磨砂和透明兩款換着用,並且爲了紅色按鍵再買一支黑色磨砂殼。

到手之後就是很普通的盒子,拆開就是殼加上按鈕,按鈕需要自己裝上去。因爲側面是軟硅膠,直接把按鈕暴力插進去並且捋平開口處就可以。紫色配紅色稍微能看一些了。

機器放進去,紫色款調得還是和真機挺像的。Xperia 1 的紫色是大家公認的難拍,調色的難度恐怕也不小。不過鬱於材質,光澤感就沒有辦法模仿了,RASTABANANA 的背殼在這方面應該會好一些。

背面攝像頭開孔非常準,左右對稱看着很舒適。攝像頭的邊緣略高於背板平面,對平放幾乎沒有影響,而且可以防止掛擦;放包裏還是要自求多福。

最後,充電口開口足夠大,用原裝線纜完全沒有問題,一些奇奇怪怪的磁吸轉接口應該也不會受到影響。

就 Xperia 1 款來說,背面的磨砂手感相當好側面的硅膠也很乾爽不會有一些所謂「液態硅膠套」的黏黏乎乎的感覺或者是摸上去總有一層灰塵的感覺按鍵的反饋感清脆得甚至超越裸機,這是淺羽沒有想到的。正面的邊框高度是嚴格看起熒幕的,據說不會影響側邊手勢,但淺羽已經關掉的這個功能……不過側面滑動的觸感確實很棒。實際上它的開孔幾乎都是嚴絲合縫的非常準確,只是指紋體驗不出意外地略有影響。非要說問題的話,大概就是按鍵配色最好還是改進一下吧。

一言以蔽之:手感真〇〇爽!

其實 Joy 擼背殼之前也推過 XZ Premium 的殼子,而且有紅色款。不過淺羽當時並沒有關注,而現在想要也已經找不到了。如果有機會真希望能湊齊一套紅色的 Xperia XZ Premium。

icebound's avatar

杂记

昨天考完试,突然有种高考完了的感觉,十点多在电脑前面坐了一会,就觉得上下眼皮打架,早早就睡了。早上7点的时候准 […]
櫻川 浅羽's avatar

羅技 Logitech K380 及 K600 TV 開箱與動手玩

前些時間,淺羽買了一個桌上用書架,並把筆電接到顯示器上嘗試「站立辦公摸魚」。有了架子,滑鼠用之前的 Microsoft Bluetooth 3600 湊合,但鍵盤總不能拿其他電腦的 HHKB 到處配對,於是還是花一點額外的錢入一把鍵盤,也給 iPad 和 Chromebook 等作爲備用。
櫻川 浅羽's avatar

土製雙系統 Chromebook 使用體驗與踩坑

淺羽最常用平板電腦做什麼?瀏覽網頁、看視訊、聊天和寫文和查看照片。現在一臺 iPad Air 2 就能大體上滿足淺羽的需求,那麼有完整的桌面版 Chrome 本身就解決了瀏覽網路的最大需求,而 Linux Apps 與 Android Apps 又豐富和完善了生態。加之 Chrome OS 本身對鍵盤滑鼠的良好支援,一臺可以拆卸鍵盤的 Chromebook 可能是淺羽用來替換掉 iPad 的最好選擇。
linkthis's avatar

RSShub配置记录

天下没有免费的午餐。
icebound's avatar

HBCPC2019题解

Solution A. Battle of Balls 球的半径为 ,为了不让球碰到障碍点,就要保证,球心到障 […]
linkthis's avatar

mpv使用记录

偷懒一时爽,查错火葬场。
icebound's avatar

HBCPC2019游记

现在是2019年5月15日凌晨,本来肝完java大作业打算睡觉,看了一眼知乎,看到又有人说【出题人不了解河北省 […]
李春光 (Chun-Guang LI)'s avatar

学术讲座通知​:From Shuffled Linear Regression to Homomorphic Sensing

题目:From Shuffled Linear Regression to Homomorphic Sensing
报告人:Dr. Manolis Tsakiris, 上海科技大学
时间:2019年5月30日14:00-15:30 (星期四)
地点:教三 308  主持人:李春光

摘要:
A recent line of research termed Shuffled Linear Regression has been exploring under great generality the recovery of signals from permuted measurements; a challenging problem in diverse fields of data science and machine learning. In its simplest form it consists of solving a linear system of equations for which the right-hand-side vector has been permuted. In the first part of this talk I will present a provably correct method based on algebraic geometry together with its associated algorithm, the latter being a first working solution to this open problem, able to handle thousands of noisy fully permuted measurements in milliseconds. In the second part of the talk I will discuss the issue of uniqueness of the solution, in a general context which I have termed Homomorphic Sensing*. Given a linear subspace and a finite set of linear transformations I will present dimension conditions of algebraic-geometric nature guaranteeing that points in the subspace are uniquely determined from their homomorphic image under some transformation in the set. As a special case, this theory explains the operational regime of Unlabeled Sensing, in which the goal is unique recovery of signals from both permuted and subsampled measurements.
*Has been accepted by ICML2019. Preprint: https://arxiv.org/abs/1901.07852

报告人简介:
Manolis Tsakiris is an electrical engineering and computer science graduate of the National Technical University of Athens, Greece. He holds an M.S. degree in signal processing from Imperial College London, UK, and a Ph.D. degree from Johns Hopkins University, USA, in theoretical machine learning, under the supervision of Prof. Rene Vidal. Since August 2017 he is an assistant professor at the School of Information Science and Technology (SIST) at ShanghaiTech University. His main research interests are subspace learning methods and related problems in algebraic geometry. For more information, please visit his homepage.

本次报告为学术前沿报告,欢迎各位老师和学生积极参加!

Molunerfinn's avatar

用setTimeout和clearTimeout简单实现setInterval与clearInterval

这个问题其实是前一段时间舍友的一道面试题。我觉得类似用reduce实现map、用xxx实现yyy的题目其实都挺有意思,考察融会贯通的本领。不过相比之下这道题可能更有实际意义。比如我们经常会用 setTimeout 来实现倒计时。下面来说说我对这个问题的思考。

icebound's avatar

HBCPC2018标程

最近好多人找我要标程。。。 贴在这里了! 链接: https://pan.baidu.com/s/1-tzOo […]
Molunerfinn's avatar

我的2019春招(暑期实习)记录

今年的春招(暑期实习)批已经过去大半了,相信不少同学已经拿到了心仪的offer了~本来打算暑假有空再写写这段经历,不过今天晚上正好有空就记录一下吧,希望能给正在或者今后要找前端实习、工作的同学一点点启发和建议。(由于我妹子在北京读书,所以实习的话我只想着申请北京的实习机会,这是本文的大前提)。

我自己是北邮研二的学生,「主修」前端。我自己的面试经历不多,从1月份到现在总共只面了3家:头条,腾讯·微信和蚂蚁金服·支付宝,很幸运都拿到了offer。其实我觉得主要还是内推对我的帮助特别大,没有内推的话我估计也很难拿offer了。所以经验第一条:能找内推尽量通过内推来获取面试资格。帮你内推的学长学姐一般会帮你查看(甚至修改)简历,有的可以直接部门直推给leader,等于省去了HR筛简历的步骤,所以能找到内推就尽量走内推而不是单纯走网申吧。

Molunerfinn's avatar

Electron-vue开发实战7——命令行调用与系统级别右键菜单的实现

前言

前段时间,我用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. 命令行调用与系统级别右键菜单的实现
  9. 想到再写…

说明

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

如果之前的文章没阅读的朋友可以先从之前的文章跟着看。本文主要是基于PicGo v2.1.0版本更新的重要内容做的讲述。

icebound's avatar

洛阳游记

旅行,是一次社会性的濒死体验。 你从熟悉你的城市中抽离,从你熟悉的城市中死去。你重生在其他不同的地方,就像你的 […]
icebound's avatar

学习java时的小思考

写java的时候遇到一点小问题,关于方法(函数)传值还是传址的问题。 比如下面一段代码:输出结果为abc 这段 […]
's avatar

浪费npm包名

开篇废话

好长时间没有写过任何东西了,并不是因为这期间我什么都没干,天天咕咕咕,而是觉得真的和各位大佬之间的差距太大了,有事被催着干活,没事躺尸看海绵宝宝。最近跟着高先生写一个扶贫的项目,本来挺简单的项目,愣是给写出花来了,还由此诞生了一个npm包,浪费了koa2-auth的包名,实在惭愧。

大半夜的就分享一下这个事情吧

来历

碎碎念警告,如有不适请跳过

开学之前,高先生找到我,叫我接一个后端的项目,就是上学期由于出去浪而错过面试的项目。当然,这种自己找上来的,大概率不是什么好事,你不能说叫我接我就接嘛,起码我要先体验下。

在看了看代码之后,嗯~不愧是合作多次的高先生,还是熟悉的味道,就接了下来。本来已经开发完成的项目,蹭了高先生的光,过来修修补补,顺便蹭蹭志愿时长,简直不要太舒服。

由于没有什么新的产品设计上的需求了,我就转向去做做代码维护的事情,为了让自己之后的代码调整等大更新可以顺利通过,最重要的事情就是开始写单元测试。

渐渐的,单元测试覆盖了100%的正常访问情况和30%的错误拦截情况,基本就可以了,毕竟错误拦截基本上也是权限错误,这是一个前后端分离的项目,除非有人故意搞破坏想投数据,要不也不会出现权限不对的问题,毕竟小项目。

然后就是把通篇的显式定义的new Promise替换成了Mongoose自带返回的样子,大砍特砍,多亏了上面写的单元测试,也就省了高先生的代码审核了。与此同时,自动部署也被我摸清楚怎么用了,上传的代码自动测试,合并到测试/主分支上就会被推送部署到测试环境中。

然后就是我沉迷Docker的时间了,直接改源码部署为镜像部署,同时开了一个集群(没错,单机集群),4个Docker跑在上面,并发理所当然提高了。

然后引库,session缓存上Redis。Gitlab-ci自动测试简直不要太爽。

结果还是没有什么新需求,这时候就开始写花了,这篇水文的主角就登场了。

需求

高先生还是觉得现在的验权实在是太过臃肿(确实,在需要验权的时候全员switch case一个权限都跑不了),然后给我发来了样例:

当时并没有看到这里有一个server层,只看到后面那个冒号分割的东西好帅呀!好简洁!然后我就想到了之前看hapi.js好像有这么个东西,兴冲冲就跑到图书馆翻出了当时借的书,找了一遍发现并没有。略失望。然后就开始自己实现呗。照葫芦画瓢的技术还是可以的。

就算画也得有个参考吧,语法风格就定下来了,使用这种双冒号分割的方式来验权。然后有借鉴了一下路由的分级解析,就有了现在这个koa2-auth

我最终的实现效果:

1
await ctx.auth.must(`Item::${ctx.params.id}::write`);

还是有点差距的,但是跟之前的画风比,这样子很不错了(开始自夸)。

成品

我就不在这里粘README了,毕竟已经浪费了一个包名了,各位可以直接去npmjs.org网站搜索查找。

传送门:koa2-auth

关于npm包发布维护的东西还不太会,最后感谢来自高先生的友情翻译,和高先生的提携。

最后大字宣传他的博客:

高渐离の屋

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插件系统构建的朋友,需要先行阅读,本文涉及到的部分内容来自上一篇文章。

Roy Binux's avatar

Zerotier Nat 网关出口 和 iptables 调试

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

赵坤's avatar

RocketMQ 主备同步

介绍 RocketMQ 的主备同步机制 !

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的主进程)应该还是能学习到相应的知识的。

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

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

保持简单

一件事情如果过于复杂,那么一定是哪里出问题了 —— 大部分情况下是对问题的理解出现偏差。 — Erlang 语言的开发者 Joe Armstrong

赵坤'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等。

linkthis's avatar

Rsync使用文档

由于太菜导致反复翻车
linkthis's avatar

Telegram RSS机器人

信任Systemd的人,最终……

搭建一个Telegram的RSSBot,可以方便地订阅自己感兴趣的信息源,并实时接收RSS消息推送。

准备Telegram Bot

首先需要申请一个Telegram的机器人,即Bot。在Telegram中找到@BotFather,开始对话并根据提示创建一个新的Bot即可,在创建过程中生成的API TOKEN需要记住以便使用。
然后输入mybots找到刚才创建的Bot并选择,点击Edit Bot,选择Edit Commands输入RSSBot的命令:

rss       - 显示当前订阅的 RSS 列表,加 raw 参数显示链接
sub       - 订阅一个 RSS: /sub http://example.com/feed.xml
unsub     - 退订一个 RSS: /unsub http://example.com/feed.xml
unsubthis - 使用此命令回复想要退订的 RSS 消息即可退订, 不支持 Channel
export    - 导出为 OPML

安装RSSBot

使用iovxw开源的项目
选择使用预编译版本以节约时间,Linux版本为musl静态链接, 无需其他依赖。

1
2
3
apt install unzip
wget https://github.com/iovxw/rssbot/releases/download/v1.4.3/rssbot-v1.4.3-linux.zip
unzip rssbot-v1.4.3-linux.zip

解压完成之后即可运行:

1
./rssbot DATAFILE TELEGRAM-BOT-TOKEN

DATAFILE为数据库保存路径(JSON文件,无需手动创建)。TELEGRAM-BOT-TOKEN为刚才创建的机器人对应的Token

Systemd配置

为了保证RSSbot持续运行和管理,使用Systemd进行操作。
执行vi /etc/systemd/system/rssbot.service,参考以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=A RSS Bot
After=network.target
Wants=network.target

[Service]
Type=simple
WorkingDirectory=/home/rss
ExecStart=/home/rss/rssbot DATAFILE TELEGRAM-BOT-TOKEN
Restart=on-failure
RestartSec=10
User=rss

[Install]
WantedBy=multi-user.target

然后执行:

1
2
3
systemctl daemon-reload
systemctl enable rssbot
systemctl start rssbot

如果需要定时重启等操作,编写对应的Time文件即可。

Bot命令示例

个人订阅:/sub <RSS 地址>
频道订阅:/sub @channelname <RSS 地址>
查看个人订阅列表:/rss
查看个人订阅列表并显示订阅链接:/rss raw
如果需要把机器人加入频道,则机器人的身份需要为管理员

Systemd真香。
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-05-29-Wednesday-08:45:53 PM

linkthis's avatar

Openwrt IPv6 配置

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

OpenWRT IPv6

之前一直只有教育网或者局部地区测试的IPv6现在已经大范围推开,大部分地区的ISP均正确部署了IPv6。通常来说,Openwrt获取IPv6的方式有三种:中继、穿透和NAT,由于ISP已经提供了IPv6和某些方案的缺陷,择优采取中继的方案。

准备

首先将光猫的模式调为桥接或者混合模式,然后通过电脑拨号确认ISP是否已经正确配置IPv6。
然后升级路由器的Openwrt的版本,最好不要低于17.01,否则odhcpd可能会出现问题,当然更老的版本也能正确获取IPv6,不过可能需要每隔一段时间就重启一次odhcpd

配置

从Openwrt 15.xx(即CC版本)开始,默认的初始设置中就会含有wan6,无需安装其它软件包。
由于Openwrt默认分配IPv6私网网段,首先应该删除网络>接口页面内IPv6 ULA 前缀配置自动生成的fd开头的/64随机IPv6地址段并保存生效。其实这个时候,在较新版本的Openwrt上面应该已经成功获取了IPv6
然后我们需要修改/etc/config/dhcp文件,使用无状态地址自动配置(SLAAC)IPv6,而不是DHCPv6。配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option ra_management '1'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'
        option dhcpv6 'disabled'
        option ndp 'relay'
        option ra 'relay'
        option master '1'

config dhcp 'wan6'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'

配置完成之后需要重启network服务,以便接入终端获取IPv6地址:

1
/etc/init.d/network restart

至此所有的客户端包括路由器均可获得可用的IPv6地址,不过在Windows下面,由于祖传BUG的原因,可能无法正常使用获取的IPv6,需要在CMD中执行如下命令:

ipconfig /release6
ipconfig /renew6

之后无需重启,是否有效需要看具体网络配置。

体验

体验较差:客户端的地址无法ping通;访问海外地址也出现问题;部分客户端有1分钟左右的延时。本质鸡肋,所以只在路由器上面保留了IPv6地址。

咸鱼IPv6立即关闭,获取更好的网络体验。
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-10-02-Wednesday-04:49:29 PM

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

Luty's avatar

TensorFlow从入门到入坟

记录对这个框架的基本理解,一些重要的API和一些工程实践。

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加锁。
当然你也可以直接解锁后删掉,这样损失了一定安全性,对于小项目或者本地项目倒没什么意义了。

Molunerfinn's avatar

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

2018-11-11 WEEK210 网络迷踪

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

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

CTF题解记录-web篇

前言

好好学习,天天向上,目录如下:

WEEK 1

  • 加了报错的注入
  • 后台登录
  • 上传绕过

WEEK 2

  • 没时间解释了
  • welcome to bugkuctf
  • never give up

WEEK 3

  • shrine
  • SSTI
  • 沙箱逃逸

WEEK 4+5

  • Flask真香
  • Flask Plus
  • 基本操作
Luty's avatar

Scrapy豆瓣ADHD小组爬虫实例

前言

搞这玩意让自己熟悉数据资源获取->数据持久化并整理->数据可视化的数据处理流程,顺便记录下Scrapy的框架的使用过程。

's avatar

硬改hexo-generator-feed使某些文章不被rss推送

前言

由于鄙人博客的rss加入了北邮人博客圈这么大佬的博客圈,所有的博客更新都会被整合。由于我太菜了,有些文章实在是拿不出手,放上去十分丢人,但是想作为自己的积累写下来,老是扔在草稿区也不是个事,所以就有了这么个想法。

前排提醒: 实现方式十分不优雅,有更好的方式还请各位指教

实现方式

RSS的文件生成应该和hexo是一个模式–模板渲染,直接在node_modules\hexo-generator-feed找到这个包

负责渲染每个文章的是

{% for post in posts.toArray() %}

存储需要渲染文章的是posts

在这个目录下搜索posts,在lib\generator.js找到

1
2
3
4
5
6
7
8
9
10
11
12
// @ line: 28
posts = posts.filter(function(post) {
return post.draft !== true;
});
// @ line: 40
var xml = template.render({
config: config,
url: url,
icon: icon,
posts: posts,
feed_url: config.root + feedConfig.path
});

filter函数是筛选器,大致用法:

1
2
3
4
5
var arr = ['A', '', 'B', null, undefined, 'C', '  '];
var r = arr.filter(function (s) {
return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
});
r; // ['A', 'B', 'C']

修改如下:

1
2
3
4
// @ line: 28
posts = posts.filter(function(post) {
return post.draft !== true && post.DontInRss !== true;
});

这下,一会后不想加入RSS的文章只需要在文章属性上加上DontInRss: true就可以了。

瑟瑟发抖

作为一个在大佬之间瑟瑟发抖的萌新,只能瑟瑟发抖了。。。

's avatar

记一次痛失域名的经历

声明

我自己域名到期没续期,并且freenom已经给我发过邮件提醒我续期,但是我没看见,我自己的锅。

PS: 本站从之前域名(xice.cf)正式迁移到(xice.wang)现在已经完成了大部分服务的迁移工作,新域名的工信部备案已经完成,公安备案正在审核。

自己没看见,能赖谁?没有检讨自己就妄下结论实在不妥。freenom为我们提供免费的域名,实在是感谢,我也借此机会直接切换到可以备案的域名。

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

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


's avatar

记在Windows平台上将proto翻译为JS的一个小坑

研究gRPC的时候,接触到了proto文件,现阶段我觉得这应该是一个可以翻译成各种语言、并且可以使用gRPC进行极其方便的远程调用的描述数据结构的文件。这次记录一下自己的愚蠢行为。

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)笔记:快速排序


原理

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

浅谈注入攻击及小结

前言

科三考试临近,眼看疲惫的练车时光就要结束,彩六也是打到手酸才突然想起要学习,回想起TSCTF那个卡了我半天(真的是半天,为什么我会去构造XSS)的注入题,于是我决定挤出了点时间研究下sql inject,在这里做下记录和小结。

什么是注入?

注入(inject)攻击产生的本质原因是输入过滤机制的不完善,导致攻击者可以利用输入数据构造执行代码,从而造成信息泄露、数据损坏、服务宕机等一系列问题。由于注入(inject)攻击常常导致严重后果,进一步催生了`一切输入有害的重要安全思想。

注入如何产生?

个人认为注入攻击产生的本质是:当一段输入数据需要添加到另一端执行指令或代码中时,攻击者可以根据指令或代码的语法刻意构造一段输入数据,造成的输入数据作为指令执行的错误。

例如在PHP + MySQL平台下:

1
2
3
4
5
6
7
8
<?php 
$name = $_POST['name'];
$con = mysqli_connect("127.0.0.1","root","","test") or die("error");

$query = "SELECT * FROM person WHERE name='$name';";
$result = mysqli_query($con,$query);
while($row=mysqli_fetch_assoc($result))
echo $row['age'];

这是一个用户通过输入name从person表查询对应age的场景,但是代码中没有对输入变量$name进行任何检测和过滤,如果我们构造$name为1'or'1'='1,那么查询语句$query就会变成:"SELECT * FROM person WHERE name='1' or '1'='1';",然而该查询语句恒成立,意味着这样的输入将会爆出数据库person表中所有人的age,造成信息泄露。

在上面这个案例中,如果我们对$name或者$query进行过滤,比如将'"转义,或者字符处理掉=,那么上面构造的输入数据不会被执行。这只是一个最简单的案例,想了解和实践更多可以部署DVWA进行本地或者远程测试。

SQL注入

根据是否有直接反馈信息分为 普通注入 和 盲注,盲注往往要利用sleep()时间盲注或者利用ascii()进行布尔盲注。

大概流程是这样的:
1.注入POC
2.猜字段数
3.猜字段顺序
4.爆数据库名
5.爆表名
6.爆字段
7.脱裤

有些步骤根据实际情况可有可无的,爆库过程中需要用到information_schema,在这里我就不XJB说了,具体参考:
DVWA-1.9全级别教程之SQL Injection
DVWA-1.9全级别教程之SQL Injection(Blind)

SQL注入绕过

我参考文章做了一些本地测试,记录了一些可能常用的绕过方法,环境为lamp,以下就算是是笔记了,一开简单记录,后面有时间会细化。

  1. 空格:/**/ %a0 ()
  2. '引号:hex() urlencode()
  3. =等号:like rlike regexp
  4. <>比较符:greatest() least() strcmp() in between
  5. ,逗号:substr()mid()from to代替,limitoffset
  6. 其他绕过: 大小写、字符嵌套、内联注释等
    还有一个没看懂的先mark:一些报错注入

宽字节注入
这个注入方式比较特殊,有两个产生条件。

  • 涉及到gbk编码 (iconv等含有编码转化功能的函数)
  • 涉及到转义\(魔术引号、addslashes、htmlspecialchars)

原理大概是,正常字符为2字节,汉字字符为4字节,在gbk的编码环境下可以%df\这样的字符,应为\的编码是%5c,结合起来为%df%5c,解码结果为汉字,从而绕过了\的转义消毒。
注:gbk2312应不存在低位范围无法进行宽字节注入,具体参考这里

后续会慢慢添加实例帮助理解和实践。

参考:
SQL注入绕过技巧
sql关键词绕过【积累中】

小结

无论是XSS、sqli还是commandi,只要有输入数据添加到指令的场景,就有注入攻击发生的风险,开发者也在努力寻找通用性解决方案。
PHP和python中不正确的使用system() exec()等函数会导致命令注入,前段不对js代码进行过滤会导致XSS,windows平台还有dll注入(不明觉厉),感觉都很刺激啊。
PHP5.4后使用的PDO技术和Mysqli几乎已经杜绝了sql注入,其他平台的防御策略也越来越完善,所以sql在实际渗透环境中可能作用并不大,但是这种思想还是很有意思的。


吐槽几句,贵阳这天气是魔鬼吗,阳光直射出门半小时后大暴雨,学车能遇到军事行动,四妹又在发情期,真是每天都有新乐趣hhhh

```

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


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

Brian Lee's avatar

队列

《Algorithm》(Sedgewick)笔记:队列

目的

用集合保存元素的同时保存它们的相对顺序:使它们入列顺序和出列顺序相同

特点

  • 基于先进先出(FIFO)策略

API

public class Queue<Item> implements Iterable<Item>

Queue()创建空队列
void enqueue(Item item)添加一个元素
Item dequeue()删除最早添加的元素
boolean isEmpty()队列是否为空
int size()队列中的元素数量

实现

public class Queue<Item> implements Iterable<Item> {    private class Node {        Item item;        Node next;    }    private Node first; //指向最早添加的结点的链接    private Node last;  //指向最近添加的结点的链接    private int N;    public boolean isEmpty() { return N == 0; }    public int size() { return N; }    //向表尾添加元素    public void enqueue(Item item) {        Node oldLast = last;        last = new Node();        last.item = item;        last.next = null;        if (isEmpty())            first = last;        else            oldLast.next = last;        N ++;    }    //从表头删除元素    public Item dequeue() {        Item item = first.item;        first = first.next;        if (isEmpty())            last = first;        N --;        return item;    }    public Iterator<Item> iterator() {        return new Queue.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_9_Queue

's avatar

使用valine为博客添加评论功能

前言

昨天被高渐离嘲笑没有评论功能,本来是不太想加的,因为加了可能也没人用,放着怪冷清的,不过 真香。

既然高先生都使用了Gitalk为博客添加Gitalk评论插件–高渐离)我就不能用一个一样的是吧(手动滑稽。再看了看对于几个常见的评论系统的使用报告之后,我决定使用valine为我的博客提供评论功能。

's avatar

《高校微信小程序开发大赛》入围作品个人盘点

前言

个人也自不量力去和高渐离大佬组队参加了这次比赛,结果不出意料的一轮就被刷下来了。这次比赛产生了不小的争议,我也挺好奇入围的作品到底长啥样的,所以就以我个人的感觉,一个用户的感觉评论一下。评论的时候我已经把队员名字以及学校都去掉了,但是也不保证绝对公正。

个人向的评论难免有失偏颇,请各位谅解。我达不到他们的高度,但是也应该有权发表一下自己的见解。

如果有哪里错误的地方还请多多谅解,本人能力有限,谢谢。

icebound's avatar

如何入门算法竞赛

朋友,你听说过算法竞赛吗?著名算法竞赛选手、教练刘汝佳曾说过,算法竞赛是一种【思维的体操】。在每年的春天,学校都会有归队赛、新生赛、校赛,筛选一批优秀选手进入ACM集训队。在集训队中,会有去过world final的大佬带着我们训练,每年暑假的集中训练是提升个人水平的最好机会!相比其他学校,北邮的编程气息浓厚,几乎所有人都会写代码,这也会对你的学习有帮助。

如何入门算法竞赛 原载于 BYRIO

's avatar

Vuex使用笔记

Vue-cli虽然好用,但是各个模块之间、各个页面之间的数据传递非常繁琐。所以才有了这个Vuex模块,用来管理Vue项目中的全局变量。既然都有全局变量了,谁还要局部变量呢?

这篇笔记本着够用就行,能用就行的宗旨,尽量以最少学习代价在实战项目中使用Vuex。

Ps:文中漏洞百出,还请各位批判阅读。

第一步 安装

npm包层面

1
$ npm i vuex -S

良好的目录结构

为了有一个良好的目录结构,防止被同事打死方便维护,新建目录结构(加星号部分)

1
2
3
4
5
6
/
|- src
|- store *
|- index.js *
|- modules *
|- <modelsName>.js *
  • src/store 用来存放所有的全局变量相关文件
  • src/store/index.js 用来引入vuex模块并导入所有的全局变量模块
  • src/store/modules 用来存放所有的全局变量模块
  • src/store/modules/<modelsName>.js 一个全局变量模块

引入

修改 src/main.js 添加

1
import store from './store'; // 引入全局变量组件

src/store/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from 'vue'
import vuex from 'vuex'

Vue.use(vuex);

import <modelsName> from './modules/<modelsName>' // 引入所有的模块

export default new vuex.Store({
modules:{
<modelsName> // 把所有的模块引入
},
state:{
// 这里可以添加一点 真·全局变量 ,比上面的少一层,下面引用可知
}
})

全局变量模块化的用处是防止变量重名,并且可以明确所属关系。

src/store/modules/<modelsName>.js

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
export default {
state:{ // 这里用来定义所有的全局变量
cookie:null,
login:false,
show:false,
nick_name: null,
avatar_url: null
},
mutations:{ // 这里的方法必须同步!
switch_dialog(state){//这里的state对应着上面这个state
state.show = state.show?false:true;
//你还可以在这里执行其他的操作改变state
},
// 调用方式:$store.commit('<modelsName>/switch_dialog')
increment (state, payload) {// 这是一个可以传参数(真名:载荷-payload)的方法
state.nick_name = payload.nick_name // 传进来的参数可以是对象
}
// 调用方式: $store.commit('<modelsName>/increment', {nick_name: 'asdf'})
// 或: $store.commit({type:'<modelsName>/increment', nick_name: 'asdf'})
},
actions:{ //这里放异步操作
switch_dialog(context){//这里的context和我们使用的$store拥有相同的对象和方法
context.commit('switch_dialog');
//你还可以在这里触发其他的mutations方法
},
// 调用方式: $store.dispatch('<modelsName>/switch_dialog')
},
getters:{ // state的派生属性
not_show(state){//这里的state对应着上面这个state
return !state.show;
}
// 调用: $store.getters.not_show
// 这就像一个值一样,不用加括号进行调用
}
}

第二步 使用

现在你已经基本完成了整个全局变量的框架建构,现在可以开始滥用使用了。

关于各种方法的使用请参照上面的文件,这边就简单写一下数据的使用吧。

this可以取到data的地方

1
that.$store.state.<modelsName>.nick_name

模板渲染的地方

1
{{$store.state.<modelsName>.nick_name}}

后记

基本上这样就可以足够应付大多数的情况了。另外Vuex还有很多的好用的功能(虽然我没用过)。

更多信息请看Vuex 是什么?

's avatar

论 如何把NoSQL用成RDBMS

好好的Mongodb,本来是一个非关系型数据库,楞是让我用成了强关系型,我也是很懵逼呀。到现在接手的一个项目(迄今为止仅有的一个项目)用的Mongodb作为后台,就是我们小程序的项目。

明天要考英语了,背单词是不可能背单词的,心里烦就回顾一下我是怎么在Nodejs里用Mongodb的吧。

本文中操作Mongodb使用的包为 mongoose

's avatar

五子棋AI边缘试探

开头声明:

关于机器学习方面的代码是完全复制自:AlphaZero实战:从零学下五子棋(附代码)-知乎,我就是用qt写了一个简易的GUI,然后花了60+块大洋租了一台阿里云的服务器,跑了3K轮的19*19棋盘下的人工智能。

初来乍到,仔细研究了MIT许可证的限制具体应如何执行,但如有侵权还望指正。

linkthis's avatar

Sony Z5P Dual升级系统并获取Root权限记录

Sony今天破产了吗?

准备工作

如果手机的版本并没有升级到最新版本的话,可以通过强刷先将手机更新到最新版本。首先通过XperiFirm下载适合自己机型的文件,一般来说,除了日本地区的ROM之外,索尼机型的ROM都支持通刷。然后使用Flashtool解密文件并打包为FTF固件,在打包时可以移除SIMLOCK文件,以免刷机时导致机器锁死(在较新版本的Flashtool当中SIMLOCK已不是可选项目)。在安装Flashtool Drive文件夹内的驱动时,Windows8和Windows10需要事先使用高级启动禁用强制驱动签名。
如果需要Root手机的话,必须首先在索尼官网申请解锁码解除BootLoader,然后通过fastboot命令解锁。
索尼的内核有保护措施,所以为了顺利Root,需要自行制作内核。同时,因为解锁之后会导致相机等的优化算法丢失,所以内核中应该包含如下内容:

  • Sony-ric
  • Dm-verity
  • Drm-fix
  • Fully /system read&write access

而且索尼没有官方Recovery,所以需要准备对应机型的Rec,如果机型不对,将导致无法进入系统。Sony Z5P Dual的代号为Satsuki

升级

打开Flashtool,第一次打开可能需要较长时间同步机型,如果同步失败,则可以打开UserFlashtool device文件夹使用git命令自行同步(建议关闭自动同步)。然后点击闪电图标选择Flashmode,然后选择之前制作的FTF固件即可,注意,一定不能勾选Wipe Misc TA下的SIMLOCK,如果勾选,将导致设备变砖。手机应在开发者模式下开启USB调试模式并授权你使用的电脑,然后在关机的情况下按住音量减键然后连接USB,此时手机呼吸灯应该为绿色,然后自动开始刷机,整个过程大概需要10分钟左右。

Recovery & Root

在刷入Recovery之前,请保证手机已经解锁且开启并授权了USB调试。在关机的情况下按住音量加键然后连接USB进入Fastboot mode,此时呼吸灯应为蓝色。首先在命令行内用Fastboot命令刷入自定义内核,之后重启,然后使用命令刷入Recovery并重启。
Root应用选择Magisk,在Recovery中使用Mount挂载SD卡或者网络储存空间(如Samba),然后刷入对应的ZIP包即可完成Root。

Magisk模块

Xposed

推荐使用Systemless Xposed,可以通过Magisk Manager安装,而且开机速度快,但是需要注意Systemless Xposed无法通过SafetyNet检查;XposedInstaller也应该使用Systemless Xposed提供的版本。

NotoSansCJK

通过Magisk Manager安装,提供全字重中日韩字体因为傻逼Google只提供了Regular字重,可以很好地改善字体的显示效果,不过这个模块只支持Android 7.0+。

Unicode字符缺失

Google在Android 8.0更新了系统的Symbol字体,而一些软件使用了较新区码的字符,导致Android 7.0无法正常对应显示。
Google更新的字体为NotoSansSymbols-Regular-SubsettedNotoSansSymbols-Regular-Subsetted2版本号并没有变,一直是Version 1.09uh,只需要自行替换位于/system/fonts/下的同名字体即可正常显示。操作需要在Recovery下进行,同时字体的权限应设置为644

刷机有风险,作死需谨慎。
有了Magisk和Xposed就能乱整了~有Recovery怎么会翻车
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-03-03-Sunday-11:14:03 AM

Molunerfinn's avatar

PicGo的star数破1000的心路历程

大概半年前(2017年11月28日)我在GitHub上开源了一个基于electron-vue的开源桌面应用PicGo。其出发点是为了改善我在写博客的时候贴图困难的问题。在经过了半年的持续维护和一些宣传(《PicGo:基于 Electron 的图片上传工具》《图床上传工具PicGo v1.5更新:支持腾讯云COSv5版本、支持GitHub图床、支持上传前重命名文件等等》等等)后,6月12日,它的star数也终于突破了1000的关卡。在这过程中我也学习了不少东西。在和大家交流的过程中,我才发现原来大家都有着这些需求,才发现我一开始的实现思路并非到位等等。谨以此文记录与PicGo有关的我的心路历程。

赶巧前不久也有一个开发者chyingp的开源项目破了1000star,也有着类似的文章,祝贺!

Molunerfinn's avatar

小记VSCode插件amVim的改进以及插件开发

前一段时间在Mac上用VSCode的时候,发现VSCodeVim这个插件严重拖慢了我的开发效率。本来用Vim模式难道不应该是提高效率么?问题是在Normal模式下,光标的移动会有肉眼可见的长延时。比如我按着j,等我松开j后,光标还在移动,而且还移动了一会儿。预期的效果应该是按下移动,松开停止。为此我查了一下相关issue,发现跟我一样的情况的人还不少。(不过也有不少人没有这个问题,貌似跟显卡有关系?我的mac是集显的)。

卸载了VSCodeVim之后,光标移动的速度又恢复了正常,不过没有Vim模式的话非常别扭。所以我就开始看看VSCode还有没有其他Vim模式的插件。于是我又试了另外两个插件:vimStyleamVim。最终我选择了后者。不仅是支持的Vim命令更多,还有就是开发者的维护一直在继续。而且很关键的一点,amVim的光标移动体验就是 如丝般顺滑

不过它有个让我很不习惯的地方:不支持:号调起VSCode的Command Line窗口,实现诸如:w保存,:wq退出等常见功能。这些功能在VSCodeVim里是支持的。于是我就在想有没有办法「移植」一下VSCodeVim的功能到amVim来,既能保持光标移动体验顺滑,又能用上Command Line的一些常用命令。所以开启了魔改模式,并在跟开发者的一系列交流后最终我提交的PR被merge了。

本文记录一下我第一次对VSCode插件(修改)开发的过程。

櫻川 浅羽's avatar

幕後:在爭吵中成型的 SOSCON 2018 講稿和投影片

BYRIO @ SOSCON 18 大事記 6 月 8 日,SOSCON 18 的前夕,BYRIO 終於(在浅 […]

幕後:在爭吵中成型的 SOSCON 2018 講稿和投影片 原载于 BYRIO

Dimpurr's avatar

如何在 Krita 中创建材质笔刷

Krita 是 KDE 基金会项目下的一款专注于数码图形绘画 (Digital Art) 的跨平台开源软件。

在 Krita 官方讨论区 Krita Tutorial & Resources 板块和官方文档 Resources 页面可以获得许多有用的材质和笔刷。本文主体内容改编翻译自 https://forum.kde.org/viewtopic.php?f=274&t=140349

钉子的知识库: http://note.dimpurr.com/#艺术和动漫绘画学习索引

今天我将教你们如何创建一个酷炫的材质笔刷。如果你需要一些类似 Photoshop 的双重画笔一样的工具,那就是这个没错了。我想这是材质绘制的极佳方式。让我们开始吧:

首先创建一个基本笔刷贴图尺寸的文件(我使用 300*300px)并删除背景。

插入(或者手动绘制)「基础」贴图。这个贴图会决定笔刷贴图的形式、尺寸、比例并仅用于创建选区。随后右键点击该图层,在菜单中选择「选择不透明度 (Select Opaque)」。

image

隐藏这个图层,并创建 5-10 个新图层。

选择某个材质笔刷,并在空白图层上绘画。使用随机的分散/镜像/旋转设置以增加贴图的多样性。对每个图层都这样做。你可以设置分离图层(Isolate layer)或者 Alt + 点击 切换单独绘制每个图层让这个过程舒服一点。

image

现在让我们创建新的动画笔刷材质。点击 +印戳 (+Stamp) 按钮并选择 风格:动态 ,模式 :随机 (当然你也可以是用别的)。

image

这将会使用目前所有的可见图层作为笔刷的贴图。不要使用自动间隙(Auto Spacing),记得为笔刷命名。你需要反复尝试让笔刷变得正常,可以直接在画布上测试你的新笔刷。

image

于是我们有了一个还未经设置的笔刷贴图,接下来进行一系列配置吧。对于方形笔刷贴图,我建议你使用镜像(Mirror)以增加多样性。对圆形笔刷贴图你也可以使用旋转(Rotation)。你也可以调节空隙曲线增加某种动态笔压,我以这种方式让高压力时能画出厚重的线条。

image

别忘了设置你还可以使用滤镜(filters),有时候我会使用非锐化蒙版(Unsharp)、模糊(Blur)、色彩调整曲线(Color Adjustment Curves)。色彩调整曲线(Color Adjustment Curves)在透明通道(Alpha channel )绘制的时候特别有用(当然平常也有效)。

后面是最终效果的一些例子。在我的笔刷包中,我做了许多有用的基本笔刷、材质笔刷并做好了预设。

image

本文来自 钉子の次元 - Dimpurr - 千里之行,始於足下。 ,原文地址 如何在 Krita 中创建材质笔刷

linkthis's avatar

调整Linux I/O调度器优化性能

Linux I/O 调度器是Linux内核中的一个组成部分,用户可以通过调整这个调度器来优化系统性能。

Linux I/O调度器

目前主流的Linux发行版本一般提供以下三种I/O调度器,下面进行简单的介绍:

CFQ

CFQ全称Completely Fair Scheduler,中文名称完全公平调度器,它是目前多数Linux发行版默认使用的调度器,其由内核默认选择。CFQ将由进程提交的同步请求放到多个进程队列中,然后为每个队列分配时间片以访问磁盘。对于通用的服务器是最好的选择,CFQ均匀地分布对I/O带宽的访问。CFQ为每个进程和线程,单独创建一个队列来管理该进程所产生的请求,以此来保证每个进程都能被很好的分配到I/O带宽,I/O调度器每次执行一个进程的4次请求。该算法的特点是按照I/O请求的地址进行排序,而不是按照先来后到的顺序来进行响应。简单来说就是给所有同步进程分配时间片,然后才排队访问磁盘。

DeadLine

Deadline为截止时间调度器,是对Linus Elevator的一种改进(在2.4内核中使用的第一种I/O调度器。主要作用是为每个设备维护一个查询请求,当内核收到一个新请求时,如果能合并就合并。如果不能合并,就会尝试排序。如果既不能合并,也没有合适的位置插入,就放到请求队列的最后),可以避免有些请求太长时间不能被处理,并可以区分对待读操作和写操作。Deadline分别额外为读I/O和写I/O提供了FIFO队列。
在Debian9系统下,如果使用官方提供的4.16版本内核,将会同时默认启用mq-deadline,其可以并行执行I/O调度,提高执行效率。

NOOP

NOOP全称No Operation,中文名称电梯式调度器,其实现了最简单的FIFO队列,所有I/O请求大致按照先来后到的顺序进行操作。NOOP实现了一个简单的FIFO队列,像电梯的工作主法一样对I/O请求进行组织。它是基于先入先出(FIFO)队列概念的Linux内核里最简单的I/O调度器。此调度程序比较适合固态硬盘。

查看使用的I/O调度器调整

查看系统支持的I/O调度器:

1
2
3
4
dmesg | grep -i scheduler
[    1.092429] io scheduler noop registered
[    1.092431] io scheduler deadline registered
[    1.092582] io scheduler cfq registered (default)

结果显示,CFQ是目前使用的I/O调度器。
查看某块硬盘使用的I/O调度器:

1
2
cat /sys/block/sda/queue/scheduler
noop deadline [cfq]

结果显示,CFQ是此硬盘使用的I/O调度器。
注意,此命令在VPS上可能无法执行。

修改使用的I/O调度器

修改linux的调度器十分简单,可以通过shell命令或者修改grub配置文件来达到目的。

Shell

此方法可以随时更改I/O调度器而无需重启计算机。

1
echo deadline > /sys/block/sda/queue/scheduler

注意,此命令在VPS上可能无法执行。

GRUB

此方法将永久修改默认的I/O调度器,与使用shell命令的临时修改不同,系统重启后,修改的调度器不会失效。 修改/etc/default/grub,在GRUB_CMDLINE_LINUX_DEFAULT内增加:

1
elevator=deadline

保存之后执行update-grub命令,然后重启计算机即可。

用户需要根据自己的需求来选择适合自己使用环境的I/O调度器,每种调度器只有在合适的硬件上才能发挥最优的效果。
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-02-03-Sunday-03:22:20 PM

LinkAdrifting's avatar

SOSCON 18 前线纪实

由重庆大学 Continue 社区举办的第 0 届 SOSCON 大会就这样圆满结束了,作为中国大陆境内首个由 […]

SOSCON 18 前线纪实 原载于 BYRIO

dimpurr's avatar

北邮人 BYRIO 小分队从重庆 SOSCON 18 学生开源年会胜利归来

今年的 SOSCON 18 学生开源年会由重大 CONTINUE 技术社区在重庆大学成功举办,我们北邮人和 BYRIO 社区也派出小分队参与了活动。

活动 Day2 上午 10:30 ,在位于重大民主湖报告厅的主会场,来自我们 BYRIO 社区的 @LinkAdrifting 聂沫予同学进行了名为「为了创意者——开源社区与精神的拓展和延续」的演讲,讲稿地址位于: https://byrio.org/soscon18/ 。讲到「卡巴基佬」的出身时,台下一时洋溢着快活的空气;讲到 Eric S. Raymond 和如何提问时,引起了活动群的热烈讨论;讲到关于如何用「我是游戏设计师」的咒语打破参与开发创造的心理避障时的「单口相声」获得了好评,有人回复:

这个好,只要心中有诗,即使吟不出诗,我也已经是一个诗人了
即使不会弹尤克里里,我也觉得自己已经是一个吟游歌手了

by 0x01.me

另一侧位于重大主教学楼 506 室,于 11:20 开始的女性专场中,我们的代小岱学姐进行了名为「Deep Learning Frameworks’ Tower of Babel」的演讲。学姐目前正在 MSRA 实习,令人敬仰令人敬仰。她介绍了深度学习框架的差异和各自生态及结合,数据科学和机器学习中的一些实践,并在观众提问时回答了获取收费数据集和模型 「调参玄学」的问题。

两位来自北邮的优秀讲者的活动照片如下:

聂沫予与 BYRIO 社区

北邮聂沫予「为了创意者——开源社区与精神的拓展和延续」

聂沫予的演讲信息

北邮代小岱「Deep Learning Frameworks’ Tower of Babel」

女性专场的听众情况

代小岱的演讲信息

另外值得一提的是, BYRIO 小分队在入住会方提供的青旅住宿时,还遇到了来自成电、青海大学的亲切的小伙伴。为了愉快度过两天共宿时间, BYRIO 社区的 @Dimpurr 同学还在房间的门口贴了一张充满恶趣味的纸条:

BYRIO 在 SOSCON 青旅的小纸条

最后共宿的大佬们

目前,北邮人 BYRIO 小分队已经胜利抵达重庆江北机场,开始回程并即将不得不爆肝准备期末考,以弥补作死准备演讲所花费的时间。让我们感谢并祝福他们。

随后,全程参与了演讲稿修改、制作了直接拉高了当日活动设计水准的超·幻灯演示的 BYRIO 社区吉祥物 @SakuragawaAsaba 同学将会撰写一篇活动后日谈,敬请各位期待。

本次 SOSCON 年会的其他活动和演讲同样非常有趣,欢迎访问大会官网 http://soscon.top/ 、活动直播地址大咖说了解。

感言

重庆太酷炫太科幻太赛博朋克了!重庆的萝莉太可爱了!逛完重大和南开中学后的感想是:校园大是可以为所欲为的,在公园里修大学是可以为所欲为的。三峡博物馆和 WFC 顶楼观景台都很棒,看完博物馆的梅兰竹菊画作特展后,在洪崖洞咖啡厅就拿 Krita 在 Surface 试画了一幅竹,这很开源。

Dimpurr

两天的周末旅游真的很短暂,但我们忙里偷闲,利用一个白天、两个晚上,还是把主要景点都转了转,重庆是个很有意思的城市。不过更重要的是SOSCON18圆满成功,我的演讲效果也不错,就这样

LinkAdrifting

会议记录

以下是 Dimpurr 在会议过程中的全程 OneNote 笔记,可供参考:

Dimpurr 的 SOSCON 18 全程笔记

北邮人 BYRIO 小分队从重庆 SOSCON 18 学生开源年会胜利归来 原载于 BYRIO

LinkAdrifting's avatar

SOSCON 18 演讲:为了创意者——开源社区与精神的拓展和延续

本文为@LinkAdrifting 在SOSCON 2018大会上的演讲稿全文,感谢 @Dimpurr Che […]

SOSCON 18 演讲:为了创意者——开源社区与精神的拓展和延续 原载于 BYRIO

linkthis's avatar

Fail2ban使用记录

Fail2ban是Python语言开发监控软件,它可以监控系统的日志文件并根据检测到的任何可疑的行为自动触发不同的操作。

Fail2ban安装

可以采用apt直接安装Fail2ban

1
apt install fail2ban

但是源的版本往往不够新,所以可以通过源码来安装:

1
2
3
git clone https://github.com/fail2ban/fail2ban.git
cd fail2ban
sudo python setup.py install

这样会将Fail2ban安装到Python的库目录下,可执行脚本位于/usr/bin,配置文件位于/etc/fail2ban
需要注意,从源码直接安装时,并没有将Fail2ban自动配置为服务,在Debian下需要执行如下命令:

1
2
3
cp files/debian-initd /etc/init.d/fail2ban
update-rc.d fail2ban defaults
service fail2ban start

apt安装的Fail2ban默认开机启动,手动安装如果需要自行设置:

1
update-rc.d fail2ban enable

如果需要对IPv6地址进行匹配,Fail2ban的版本需要大于0.10

Fail2ban配置

为了避免在升级时配置被覆盖,首先复制配置文件:

1
2
cd /etc/fail2ban
cp jail.conf jail.local

常用的配置参数有:

名称 默认值 描述
filter   jail检测匹配时使用的过滤器名称。过滤器每成功进行一次匹配,对应的jail内的计数器加一
logpath /var/log/messages 过滤器使用的日志文件的路径
maxretry 5 IP触发操作的匹配次数(即计数器的值)
findtime 600 sec 如果在设置的时间内未找到匹配值,则将计数器置零
bantime 600 sec IP被禁止的时间。负数为“永久”禁止。

一般情况下的完整配置文件如下:

1
2
3
4
5
6
7
8
9
10
[DEFAULT]

ignoreip = 127.0.0.1/8 #忽略的IP地址
bantime  = 604800
findtime = 600
maxretry = 5

[sshd]

enabled = true

这个配置为SSH的配置(如果自行修改过端口,则必须指定修改后的端口),其他的配置可以参加jail.conf。如果需要使用,需要将enabled设置为true,并且配置action,指定需要匹配的端口等。loglevel可以设置日志级别,sendmail可以设置邮件提醒。

Fail2ban常用命令

显示fail2ban的活动列表:

1
2
3
4
fail2ban-client status
Status
|- Number of jail:	1
`- Jail list:	sshd

显示特定jail的状态:

1
2
3
4
5
6
7
8
9
10
fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- File list:
`- Actions
   |- Currently banned:	0
   |- Total banned:	0
   `- Banned IP list:

需要注意,如果停止了Fail2ban服务,那么所有的IP地址都会被解锁。当你重启Fail2ban时,其会在/var/log/auth.log中查找异常的IP地址,如果这些异常地址的产生时间仍然在禁止时间内,那么Fail2ban将会重新禁止这些IP地址。

更多用法咕咕当中 && 一般不会有人踩的坑咕咕当中。
Fial2ban只能降低风险,提高安全性。
本文采用CC BY-NC-ND 4.0许可协议进行许可,转载请注明出处。

本文最后更新时间为:2019-02-03-Sunday-03:22:20 PM

Volgorabgle's avatar

如何入门绘画 (Ver. Volgo)

本文分为两部分,前部分是一些工具推荐以及学习资料。后部分介绍我 (@Volgo) 的绘画经历。还请根据喜好酌量 […]

如何入门绘画 (Ver. Volgo) 原载于 BYRIO

dimpurr's avatar

首届学生开源年会 SOSCON 将于6月在重庆大学举办,现征集北邮人组队前往

现征集北邮对开源技术感兴趣的小伙伴们组队前往 SOSCON 18 学生开源年会,会方提供住宿,路费还有一定比例报销哦。

另外,我们北邮将会有一场以上的演讲名额,讲者报销一半以上往返路费,有兴趣挑战一下的同学也可进群联系我们,或者通过大会官网自行报名。

  • 时间:2018年6月9日、10日
  • 地点:重庆大学A区主教国际会议中心
  • 活动官网:https://soscon.top/

感兴趣请扫码加微信群:

官方介绍推送如下:

学生开源年会

学生开源年会 ( Students Open Source Conference ) 是中国大陆首个由学生自发组织举办的开源技术峰会,峰会基于开放源代码的理念,每年举办一次,举办地点为在各个城市轮办。峰会的主旨是希望引导和鼓励学生了解、参与、贡献开源;并且在开源项目中,结识更多的朋友,同时也让长期参与开源项目和认同开源理念的同学能够有交流技术、分享经验的机会。

学生开源年会和台湾的 SITCON 以及香港的 SITCON HK为姊妹会议,合为两岸三地华人社区三大学生技术会议。也是中国大陆首个面向学生的开源会议,从讲者到工作人员到听众绝大部分都是学生,享受开源乐趣,参与开源贡献,关于畅想未来这件事情,我们学生更有感觉。

年会展望

SOSCON 2018 将于 2018年 6 月9日-10日在火热的重庆举办,来自全国各地的学生届时将齐聚一堂,想必是一场技术与思考的饕餮盛宴!

我们也希望SOSCON所聚集而成的社群会作为一个长期的舞台,活跃在各地,成为学生交流技术、开放讨论的平台,使得开源理念能够在学生群体中茁壮成长。

会议期间希望学生能积极交流,让学生站上舞台,展示诞生在实验室里的创想,分享蕴含在编码中的激情,畅聊属于开源理念的未来。也期待参会者能继续发挥自己的影响力,让周围更多的人为开源做贡献。

峰会主旨

希望引导和鼓励学生了解、参与、贡献开源;并且在开源项目中,结识更多的朋友,同时也让长期参与开源项目和认同开源理念的同学能够有交流技术、分享经验的机会。同时也欢迎到官方网站报名志愿者和演讲者。

招募志愿者

希望引导和鼓励学生了解、参与、贡献开源;并且在开源项目中,结识更多的朋友,同时也让长期参与开源项目和认同开源理念的同学能够有交流技术、分享经验的机会。https://soscon.top/apply

开放演讲提交

所有跟开源有关的话题和议题都是被鼓励的。包括:Linux、编程语言、云计算、人工智能等等;大会采取多轨道方式同时进行,涵盖但不限于以下内容,也非常欢迎随时跟我们分享你的新鲜想法。

  • 学生自己做的开源项目分享。(譬如自己做的玩具项目、校园项目)
  • 跟大学计算机、软件、网络相关的课程学习分享,譬如数据结构、操作系统等。(需与开源结合)
  • 前沿领域的开源技术、开源项目分享,譬如最新的人工智能、区块链等。
  • 自己参与的国际开源项目分享,譬如 Linux、GNOME、Python等等。
  • 女性专场。(供女生参与及申请,与开源和计算机、软件相关的话题)
  • Workshop 工作坊,手把手带你读源代码、带你折腾代码、或者贡献开源项目。

演讲者以学生为主,大会同时考虑对优秀的学生讲者进行一定的差旅补助,申请地址 https://soscon.top/apply

征求赞助商

活动的举行离不开赞助商的支持,欢迎有意支持学生开源发展的公司与我们联络:[email protected]

时间地点

主办:开源工场
时间:2018年6月9日、10日
地点:重庆大学A区主教国际会议中心
官网:https://soscon.top

蒹葭苍苍,白露为霜;开源工场,在水一方。
欢迎关注学生开源年会,与你不醉不会

电报群:http://t.me/soscon
QQ群:202790710

Weibo:http://weibo.com/openingsource
Facebook:https://facebook.com/openingsource
Twitter:https://twitter.com/openingsource
Google +:https://google.com/+OpeningSource

SOSCON AD

首届学生开源年会 SOSCON 将于6月在重庆大学举办,现征集北邮人组队前往 原载于 BYRIO

dimpurr's avatar

如何入门前端

通俗的来说,前端就是「写网页」。稍微严格一点说,前端指的是 Web 开发中,主要与用户所看到的界面打交道的,以 […]

如何入门前端 原载于 BYRIO

linkthis's avatar

Debian使用记录

本记录主要对应的是桌面版Debian,而且由于系统的特性,本文所叙述之内容只能尽量保证在同一个版本之下的有效性,其它版本系统采用时请多加注意。
Molunerfinn's avatar

基于Koa2开发微信二维码扫码支付相关流程

前段时间在开发一个功能,要求是通过微信二维码进行扫码支付。这个情景我们屡见不鲜了,各种电子商城、线下的自动贩卖机等等都会有这个功能。平时只是使用者,如今变为开发者,也是有不小的坑。所以特此写一篇博客记录一下。

: 要开发微信二维码支付,你必须要有相应的商户号的权限,否则你是无法开发的。若无相应权限,本文不推荐阅读。

Molunerfinn's avatar

【NOTE】观察者模式VS订阅发布模式

最近在看了一篇《不好意思,观察者模式跟发布订阅模式就是不一样》的文章之后对于这两个模式产生了比较浓厚的兴趣。不过奈何我的水平有限,看完那篇文章还是不能理解。不过在和朋友讨论之后,我想我应该是弄懂了。所以特地记下一篇笔记,以便回头翻阅的时候能够想起来。如果理解有误,欢迎在下方评论指出,一起讨论!

Molunerfinn's avatar

【NOTE】进程-线程-协程 关系与区别

在平时总会听到「进程」、「线程」,甚至最近由于Golang的火热我还听到了「协程」。但是平时我对这三个概念并不能很好的理解,甚至不知它们之间的区别和联系。所以专门找了时间了解了一下它们。本文仅为个人笔记,如有错误或者侵权行为请及时在下方评论里指出!感谢。

进程

一个进程好比是一个程序,它是 资源分配的最小单位 。同一时刻执行的进程数不会超过核心数。不过如果问单核CPU能否运行多进程?答案又是肯定的。单核CPU也可以运行多进程,只不过不是同时的,而是极快地在进程间来回切换实现的多进程。举个简单的例子,就算是十年前的单核CPU的电脑,也可以聊QQ的同时看视频。

电脑中有许多进程需要处于「同时」开启的状态,而利用CPU在进程间的快速切换,可以实现「同时」运行多个程序。而进程切换则意味着需要保留进程切换前的状态,以备切换回去的时候能够继续接着工作。所以进程拥有自己的地址空间,全局变量,文件描述符,各种硬件等等资源。操作系统通过调度CPU去执行进程的记录、回复、切换等等。

线程

如果说进程和进程之间相当于程序与程序之间的关系,那么线程与线程之间就相当于程序内的任务和任务之间的关系。所以线程是依赖于进程的,也称为 「微进程」 。它是 程序执行过程中的最小单元

一个程序内包含了多种任务。打个比方,用播放器看视频的时候,视频输出的画面和声音可以认为是两种任务。当你拖动进度条的时候又触发了另外一种任务。拖动进度条会导致画面和声音都发生变化,如果进程里没有线程的话,那么可能发生的情况就是:

拖动进度条->画面更新->声音更新。你会明显感到画面和声音和进度条不同步。

但是加上了线程之后,线程能够共享进程的大部分资源,并参与CPU的调度。意味着它能够在进程间进行切换,实现「并发」,从而反馈到使用上就是拖动进度条的同时,画面和声音都同步了。所以我们经常能听到的一个词是「多线程」,就是把一个程序分成多个任务去跑,让任务更快处理。不过线程和线程之间由于某些资源是独占的,会导致锁的问题。例如Python的GIL多线程锁。

协程

协程在线程中实现调度。你可以理解为它是 「微线程」 。它的调度不来自于CPU,而是完全来自于用户控制(可以理解为用代码控制流程)。协程的执行效率非常高,它的切换不是线程切换,没有线程切换的开销。而且只要线程越多,协程的性能优势就越明显。协程不需要多线程的锁机制,只需要判断状态即可。不过协程本身无法利用多核CPU,因为它基于线程,而线程又依赖于进程。

在JS里,常见的协程就是ES6的yield Generator或者ES7的async await。我们知道JS引擎是单线程的。所以在处理异步任务队列的时候,以往我们会陷入「回调金字塔」或者「回调地狱」。而有了协程之后我们可以在代码层面上来控制我们的程序。

比如我们有这么一个需求,等两个请求都返回之后,用它们的返回值共同做些事。(此处不用Promise.all()来实现,不是说不行,而是为了更好地说明主题)

ES6 + co 的写法:

1
2
3
4
5
6
7
const axios = require('axios')
const co = require('co')
co(function* (){
const getData = yield axios.get('xxx')
const postData = yield axios.post('xxx')
console.log(getData, postData)
})

ES7 的写法:

1
2
3
4
5
6
const axios = require('axios')
(async function () {
const getData = await axios.get('xxx')
const postData = await axios.post('xxx')
console.log(getData, postData)
})()

上述用「同步」的方式写的代码实际上依然是异步执行的。不过因为了有协程,在单线程的JS里也能够让我们在代码层面上实现了任务调度。

总结

可以说三者虽然是不同的东西,但是有着很密切的关系和类似的特性。它们的关系是从大到小,从上而下的。没有进程也就没有线程也就没有协程。总的来说,在多核处理器的情况下,多进程+多协程可以发挥最优的性能。

参考文献

  1. 进程,线程,协程与并行,并发
  2. 进程和线程、协程的区别
  3. 进程、线程和协程的比较
  4. 线程、进程与处理器
Molunerfinn's avatar

基于Electron-vue的图床上传工具PicGo v1.5更新说明

经过一个多月的努(lan)力(duo)开发,基于electron的图床上传工具PicGo终于迎来了一个minor版本的更新。如果你对此感兴趣,不妨看看都更新了哪些有趣而实用的功能吧。

Molunerfinn's avatar

Electron-vue开发实战4——通过CI发布以及更新的方式

前言

前段时间,我用electron-vue开发了一款跨平台(目前支持Mac和Windows)的免费开源的图床上传应用——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的主进程)应该还是能学习到相应的知识的。

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

cengxu's avatar

如何入门产品设计

版本 201804 Muji 不是卖产品,而是卖人生的 8000 种角色。它帮助人们拥有一个每天快乐多一点的人 […]

如何入门产品设计 原载于 BYRIO

dimpurr's avatar

BYRIO::helloWorld()

你好, BYRIOSC ,北邮学生互联网与开源社区! BYRIOSC 社区尚处于初生阶段,需要你的支持和参与!

__meta__

BYRIOSC 是一个围绕互联网技术与开源文化,主题涵盖科技、开发、设计、媒体,由开发者和创意工作者组成的线上交流、线下活动的学生社区。 我们力求吸引富有热情和兴趣的开发者、创造者们加入,凝聚北邮各大学生技术组织的力量,建设成为最富有活力和创造力的学生技术社区。

toStudents()

欢迎来到 BYRIOSC 。在这里,你可以发现同好伙伴,交流技术话题,找到学习路线,参与项目实践和获得更多的机会。立刻:

  • 加入我们的 QQ 群 (NzUzMTExMzI2, Base64) 或者 Telegram 群 (https://t.me/byriosc) 并参与讨论!
  • 留言板留下你想说的话!
  • 阅读 如何入门 一门技术的文章,开始学习并加入对应的 兴趣小组
  • BYRCIRCLE 拥有你的个人页、标记你的技能点和参与项目的意愿,认识前辈和技术同好,并在 BYRIDEA 提出想法、组队实现或者参加竞赛。 – 在 BYRCAFE 一览最新的活动资讯和技术干货、北邮人论坛讨论和各大校内学生组织的公众号内容聚合精选(建设中)。
  • BYRPLANT 博客圈阅读社区成员的文章,或者 登记你自己的个人主页和博客 以便我们收录。
  • BYRWIKI 了解北邮学生活动的历史、创新和创业文化以及技术类学生组织和社团,并参与其中(建设中)。 如果你有能力,并想参与我们的项目开发或者社区建设,欢迎:
  • 阅读我们的 项目小组 列表 ,选择你有兴趣的项目并联系负责人加入。
  • 阅读我们的 社区宣言组织结构 文档,参与讨论、提供建议,或者成为社区负责人的一员。

toOrganizations()

我们欢迎各类具有技术和创意性质的学生组织,加入北邮学生互联网与开源联盟成为成员组织,或者校外的技术和开源社区与我们合作。

  • 在 BYRWIKI 拥有自己的组织介绍书,记录自己的历史、发展和产出成果。
  • 利用 BYRIOSC 联盟平台和其他组织共享人才和资源、联合举办活动。 – 利用 BYRIOSC 的学习引导基础设施培养新人,补充新鲜血液。
  • 利用 BYRIOSC 富有活力的社区招募优秀人才、利用 BYRIOSC 的媒体和信息渠道曝光和宣传。 请联系我们的社区负责人讨论具体事宜,北邮的学生技术文化发展的需要凝聚所有方向一致的力量!

@import how-to

从这里开始了解你感兴趣的技术方向并深入学习,或者阅读 如何撰写「如何入门」系列文章 成为投稿作者!

BYRIO::helloWorld() 原载于 BYRIO

Molunerfinn's avatar

浅谈前后端路由与前后端渲染

最近经常会遇到有人问诸如类似下面的问题:

  • 为啥我写的Vue应用在开发阶段都没问题,部署到服务端之后访问不了除了/的页面呢
  • 为啥我写的SPA页面的路由用hash模式都没问题,改成history模式就问题百出呢
  • 啥是前端路由啥是后端路由,要怎么配后端才能支持我的前端路由呢

这个问题是很多初学者会问的问题,于是结合我自己的学习经历也来简单的讲解一下这二者的区别与联系,希望能对你们有所帮助。

老手可以绕道,去看些更有用的文章吧~

Molunerfinn's avatar

Electron-vue开发实战3——跨平台的一些兼容措施

前言

前段时间,我用electron-vue开发了一款跨平台(目前支持Mac和Windows)的免费开源的图床上传应用——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的主进程)应该还是能学习到相应的知识的。

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

Molunerfinn's avatar

hexo-theme-melody v1.5 supports slides & iframe

hexo-theme-melody v1.5

Supports iframe & slides. You can use a layout called slides to enabled the slides layout.

Also you can add a iframe front-matter with the slides layout in your md file to enable the iframe page.

===

Steps

1. Add a slides page

1
2
hexo new page slides
cd ./source/slides

===

2. Add the layout type

1
vim index.md

Add a type called slides

1
2
3
title: slides
date: 2018-03-06 20:24:48
type: slides

===

3. Modified the melody.yml

Add slides default config:

1
2
3
4
5
6
7
8
9
10
11
12
slide:
separator: whatever you like
separator_vertical: whatever you like
charset: utf-8
theme: black
mouseWheel: false
transition: slide
transitionSpeed: default
parallaxBackgroundImage: ''
parallaxBackgroundSize: ''
parallaxBackgroundHorizontal: null
parallaxBackgroundVertical: null

See reveal.js config

===

4. Write a md file with slides layout

In _posts folder, add a md file.

For example:

1
2
3
4
5
6
title: hexo-theme-melody v1.5 supports iframe & slides
date: 2018-03-06 19:57:52
layout: slides
---

// balalala...

Then you will get a post of slides type.

===

Slides layout with iframe

If you want to add a website whatever you like within an iframe, try this:

In _posts folder, add a md file.

1
2
3
4
5
title: hexo-theme-melody v1.5 supports iframe & slides
date: 2018-03-06 19:57:52
layout: slides
iframe: https://the-url-whatever-you-like
---

Then you will get a post of iframe.

===

Configurate single slides in md

The slides config in meldoy.yml can change whole slides page.

But if you set the config in the md file, it will effect the single page.

==

For example:

1
2
3
4
5
6
7
8
9
title: hexo-theme-melody v1.5 supports iframe & slides
date: 2018-03-06 19:57:52
layout: slides
slide:
theme: white
transition: zoom
---

// balalala...

===

Enjoy!

Molunerfinn's avatar

用新版的Chrome把PWA网站添加到桌面,获得媲美原生应用的体验

2018.03.06 更新:非PWA网站也能通过独立窗口而非浏览器打开。具体看「注意事项」。

PWA是什么

引用自Harttle.Land的说法:

PWA(Progressive Web Apps)是 Google 最近在提的一种 Web App 形态 (或者如 Wikipedia 所称的“软件开发方法”)。 Harttle 能找到的关于 PWA 最早的一篇文章是 2015年6月 Alex Russell 的一篇博客: Progressive apps escaping tabs without losing our soul让 Web App 从标签页跳出来,同时保持 Web 的灵魂。

如 Alex 所述,PWA 意图让 Web 在保留其本质(开放平台、易于访问、可索引)的同时, 在离线、交互、通知等方面达到类似 App 的用户体验。按 Google 官方的解释 PWA 具有这些特性:Reliable, Fast, Engaging。

它比原生应用更轻量,但是却比现有的Web APP的功能更加丰富。最大也是最关键的区别是它能够脱离浏览器的「束缚」(虽然依然是基于浏览器的技术),能够把PWA网站添加到你的桌面上,不管是PC操作系统还是手机操作系统,类似于一个原生应用一样,并且拥有媲美原生应用的体验。

它也能拥有原生APP应用一般的启动闪屏,它也能像原生APP应用一般能有消息推送——不过要知道,它源自Web,通常只有传统APP的体积的十分之一甚至更小。它不用等待下载安装的时间,打开网页的时候就已经「下载」并且「安装」完毕。

要想体验这项技术,如果你是安卓用户,那最新版的Chrome已经支持;如果你是iOS用户,可以等待3月份的11.3版本更新;如果你是PC电脑用户,那么来看看怎么在电脑上也体验体验PWA吧。

配置Chrome

首先更新你的Chrome版本到64或以上。

然后在地址栏输入chrome://flags,找到Desktop PWAs的选项将其Enabled了,然后Chrome会提示你重启浏览器。

重启浏览器后,PWA添加到桌面的特性就已经具备了。

将PWA网站添加到桌面

我这里使用的是我的博客(基于自己写的hexo-theme-melody主题搭建的)。打开网站,然后在浏览器右侧找到设置的按钮。接下去我针对Windows平台和macOS平台做分开讲解。

Windows平台

Windows平台找到添加到桌面这个按钮,点击,然后会出现一个确认框:

点击添加。然后你就可以在桌面上看到相应的图标:

双击打开:

你会发现打开了一个没有浏览器痕迹的网页,或者说是个应用——这就是PWA了。PWA支持离线启动技术,即使在没网的情况下也能启动应用。不过在需要网络条件下才能发送的请求依然需要网络环境。

macOS平台

相对于Windows平台比较简单的操作,macOS平台的操作相对有点绕弯,不过也大致相同。macOS的Chrome无法一次性就把PWA应用添加到桌面。需要先把PWA网站生成一个app应用,然后你再手动把这个app应用以快捷方式复制到桌面。

接下来是具体步骤:

打开一个PWA网站,此处依然以我的博客作为例子,然后再右侧找到配置菜单,下拉选中添加到“应用”文件夹。然后等待几秒钟,会出现一个对话框:

此时这个PWA应用已经生成完毕了。我们点击添加。之后你就可以在你的应用列表看到它了:

不过如果你要在你的桌面上添加这个应用的话,还需要找到这个app的位置,一般是在/Users/你的用户名/Applications/Chrome\ Apps.localized/这个文件夹下。用finder打开:

然后选中这个应用,按住alt+command键把它拖拽到桌面上,就会生成一个快捷方式啦。这个方法也同样适用于其他应用。

注意事项

如果是非PWA应用,也会有添加到桌面或者添加到应用文件夹的选项。不过当你双击打开它们的时候依然会调用Chrome浏览器去打开,跟以前的书签的作用无差别。

不过,依然可以通过一个小操作来实现。感谢@RiiSan指出我原文的错误。

前置步骤跟之前说的一样,然后打开chrome://apps,找到你制作的应用,然后右键,选择在窗口中打开。那么就能获得跟PWA应用单独窗口的类似体验。不过它是不具备PWA离线打开的能力哦,只是纯粹的一个网页通过独立窗口打开而已。

目前Desktop PWAs还是实验性的功能,所以有可能出现不稳定的情况,依照自己的情况作出决定~

结尾

就目前来说,我能想到的比较理想的使用条件是,在一些功能性网站支持PWA的情况下,是不用再去下它们的桌面客户端了,直接通过PWA添加到桌面,就能像使用原生应用一样使用它们啦。比如推特,比如Medium等。

下面给出一个别人总结的PWA网站列表,可以去体验一波~

https://github.com/hemanth/awesome-pwa

via these people and places