duangsuse::Echo
583 subscribers
4.12K photos
118 videos
579 files
6.13K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
#learn #life #dev #pl #cs 这周的笔记 📓

有些和某些东西有关的我会转发到 Throws,至于图什么的待会发,因为照片转发到电脑上有点不方便...

+ 悲观的 2018 与形式化证明

2019 可能会是过去 10 年里最差的一年,但却是未来 10 年里最好的一年。

如何形式化地论证这个命题成立呢?

因为我现在太菜了,不是很熟练 Agda 的形式化证明,所以这可以说是 #TODO
对不起啊,而且我也怕这花费太多时间

当然,上面我说过的那个东西后来发现其实有错误,我误会了,比如

(有火 -> 有烟) 这个复合命题是说『如果有火,那就有烟』
假设这是既成条件(它已经成立)。
但是我上面的表达是:
(有火 -> 有烟) -> 有火 -> 有虫也

其实我的目的是表示已经证明上面那个有火就有烟成立之后,由
有火 
推出
 有虫也

这是不对的,因为 (有火 -> 有烟) 是既成条件,它已经成立了,而上面那个命题实际上是说『如果』一个既成条件已经成立,这是废话。
当然这么说在上面那个文字里面没错误,但是容易引起误会

当然这些都是很 trivial 的东西,我现在正在为如何独立理解冰封博文教的归纳证明 \forall{xs}.\quad reverse \quad (reverse \quad xs) \equiv{xs} 头晕呢
其实如果不是有这篇博文,我对递归的理解不会有再次的加深,为了理解此归纳证明我以不同的可视化方式对 rev 1 :: 2 :: 3 :: [] 和它相关的东西不断弄了十几次,最后还是没能理解
当然第二天(今天)算是勉强理解了一点,但我还是无法独立证明...

+ 我妈水问题和 #PL 理论的表象类型

我妈水问题... 都知道?

女朋友对你说:我和你妈同时掉到水里,你救谁?

演讲者的意见就是这类问题不涉及实际场景是没有太大讨论意义的

我懒得把他的话再复制一遍,不过这个问题很像你们平时讨论的 C++ 和 #Java 哪个好、MySQL/Percona/MariaDB 和 PG 哪个好,GNU/Linux 和 Windows 哪个好、Vim 和 Emacs 哪个好(虽然很多人连 C-x C-b 在 Emacs 里是干啥的快捷键都不知道)

其实我的意思很明确也相当迫真,就是说,我们抽象讨论的时候就是编译器处理程序的阶段,实际处理问题的时候就是程序实际执行的时候

有些信息只有到了『运行期(runtime)』才会知道,比如一个 Java 这种经典 OOP 里参数实际的类型,而不是简单一个可以被继承,可能有 subtype (子类型)的非 final

所以 JIT 编译可以做一些 AOT 做不了的优化,就比如说数组访问边界检查消除,比如说分支概率预测,比如说一些运行期可以确定信息而不是常量的剪枝
(当然 AOT 也是有自己的好处的,不是 JRockit 这种面向服务器的 JVM 一般都要专门设置 server compiler JIT 编译器才敢多弄点优化措施)

相关的博文 R 大的博客上是有的,推荐阅读。不学习就会死啊!每次想着这个,learn or die 啊,说不定你就愿意学了(当然前提是你要尝试让自己相信,不学就会死,然后或许你会学(

当然,时间的朋友这演讲我觉得讲得还不错。对于一些『做实事』的人都是很有价值的。我觉得值得一看。当然是收费的(其实只是要优酷 VIP),但有价值的东西是值得你为之付费的。
如果你是 Geek 之类有些人会对这种不良心平台『恨之入骨』的,也算了,不过我觉得不是原则性问题一般都能容忍,换句话说,现在也没人能替代优酷,是不?上次知乎 #ZhiHu#China #LGBT 水晶之夜(当然其实本质上是政治正确,不过它太自觉了)

就像是现在过气的新蛤社的 GoliGoli,和以前的 GeekApk,说到 #GeekApk... 绿色... 猴子... 文体两... 多多支持... 停下停下停下 🙃,当然 GeekApk 可能不会复活但我自己这个寒假(20 多天)可能独自会再起一个同样性质的项目,我不作任何担保说绝对会完成,但我相信基于我目前的表现你们会信我有完成它的技术资本。或许如果真的做出来了你们会用?(

就像曾经 @drakeet 吐槽的那样,其实 GeekApk 最大的问题在于过于功利,不像是在做事,而是很多没经验的人在瞎搅合,而真正为它写过一两行真正意义上有用代码的可能只有我和 @zhy0919(losfair) 两个人,当然我自己很冤,因为我本来不是功利的。我开始的计划虽然很幼稚,不像『做事的人』,但起码我也是细化了我的设计的,而且我从来没有计划在它完成之前就拿出去吹,或者找别人一起帮忙开发,我不指望有人能为不是自己的工程做啥贡献。自己的东西有人用都是万岁了。

虽然我那时的确是没有独立走到实现阶段的能力,但我也不只是会弱智地坐在那里想着『创建一个 Geek 社区』而无所行动,起码我是写了东西的,所以我觉得这事,谁开始『幼稚』的时候都会有的,我不后悔。

没有一个一个 '1' 积累起来也达不到 '10',谁都不是空中楼阁。即使是天才也曾经有啥都看不懂的时候。所谓人的经历是有连续性的,不会有现在的天才是『突然开窍』而自己完全没有相关背景的说法

+ 知识的深度和广度

深度优先搜索和广度优先搜索大家都知道吧(当然我不是说这个
不过我不知道现在 #OI 生是不是所有人都会这种简单问题的,据说也有人不会?

当然现在软件工程入门门槛太低了,能模式识别,抄改代码都可以开发很优秀的 Android 应用了... 算法什么的不是必会的,你们就需要知道 Regexp.new("[\u4e00-\u9fff]*").match("字").size 可以拿来统计汉字字数,不需要知道后面 Unicode、Regex 引擎理论之类的(当然这个不是最佳实践,如果要开发实际应用的话 #Unicode 还是有些东西必须处理的,不然字数统计有问题)

所谓深度大概就是从小白(只会玩个游戏)、到用户(基本啥都不懂)、到 Geek(可能有看代码的能力)、到幼稚的开发者(抄改代码)、到普通开发者(至少会自己写复杂一点的代码了)、到企业级的开发者(有一定经验了)、到开发者依赖的开发者(知道自己真正在干什么)、到程序大师

再比如说,一个 #JavaScript 开发者可能在他自己的领域,比如 Xml/Js/AsyncIO 可能有所了解,但如果要去弄逆向工程或者 CTF 这种要求知识面和深度都有的东西,可能就啥都做不了了,他们眼里『二进制文件』和『二进制文件』... 根本没有区别嘛,而相当多一部分包括 ES6 的 JavaScript 开发者可能都没有用过 ES6 新的 ArrayBuffer

而一般来说,C/C++ 开发者的素质都比 JavaScript 开发者的素质高,我们可以认为主要写 JavaScript 的人往往比较难学会写 C/C++/C#,而写 C/C++ 之类的人全都有能力去写 JavaScript,这里我们可以看出一个深度的区别,虽然本质上还是知识面的,但从一些常见的例子看可以理解为是深度一样的东西

也就是说,深度就是从简单顺序结构到循环到递归的差别,广度大概就是同一个层次的东西了解很多,我懒得弄什么形式化定义,你们看懂就好。

最简明的代码例子( #Kotlin ),当然因为我也很小白所以没有特别酷的例子可以弄,但我至少也不至于像王淫那样拿非常简单的 #FP 例程去骗你们说是他觉得最优雅的代码,我到觉得是他在嘲讽你们,这都看不懂 :)
我当时就看不懂,我相信你们很多人(不是写 Scala、Clojure、Eta 的)也看不懂。

假如我们写个最简单的 FizzBuzz 程序

== 这是普通小白会写的代码,当然其实有隐含的事实,就是他们的代码是抄来的(控制结构),自己连 .. 是什么都不知道,可能

fun main(args: Array<String>) {
for (i in 1..100) {
if (i % 3 == 0 && i % 5 == 0)
println(i)
}
}

== 这是稍微有点常识的普通人(上文的『企业级开发者』)会写的代码

fun main(vararg args: String) {
for (i in 1..100)
if (i % 15 == 0) println(i)
}

也可能是

fun main(vararg args: String) {
(1..100).forEach {
x -> if (i % 15 == 0) println(i)
}
}

之类的,看他们的觉悟了,其实这就是属于已经开始理解对算法的表述方法还有程序结构的类型了,至少他们不止了解一些『常用』的方法

== 这是又有点常识的人会写的代码

fun main(vararg args: String) = (1..100).filter { x -> x % 15 == 0 }.forEach(::println)

当然我这么说也有点迫真,其实这个例子举得不好,举例子向来都是最考验一个人技术的。

我技术不好。不过如果要举一个更好的例子,我猜是算法题。
duangsuse::Echo
实在是没有那个力气开几个理论向学习,因为定理证明、PL 理论那些已经够累了... 代数程序逻辑依然在学,反正理论向都是均衡发展但都很薄弱就是了 现在具体来讲就是 The Little Schemer 终于熟悉了一点这个列表处理语言... 不过我觉得还是 Haskell 好,因为 Haskell 更符合直觉(看很多用 Haskell 讲程序分析的论文就知道),Scheme 一类的一大堆 car cdr 让不让人活了 具体就是(拿 foldr 和 foldl 举个例子) Haskell 里(比较简单比较…
顺便说一下,王垠(其实我知道我不应该老是提他,而且相信大家有很多人都只知道王垠,因为很多人在吹他,然后这里面有些人就连轮子哥、Rednaxelafx 大、三锋都不知道)(其实知道又怎么样,你们不会看他博客的...)一些人是 fold 都不知道是什么就在那瞎用

其实嘛,我想了一下发现我自己就有点这个意思,不过我是搞得懂 foldr 然后暂时搞不懂 foldl

当然,对一些比较崇拜淫王的人来说(其实我现在因为选择了放松一点自己这方面发展就没有那么神经质了(之前我总是觉得会有 #Android 开发的前端来喷我,现在不会有这种臆想了
我对王垠真的是没有什么看法,和大家一样,都只是相对客观的就事不就人评价而已
不过我绝对不会把他当成偶像什么的去膜拜,在我看来他是大佬,但就如他的博客名当然我在扯淡一样,我不知道他到底哪些东西会不会是在扯淡,在跟你们开玩笑
当然我就他所展示的经历而言非常羡慕出国留学的经历。就这样。That's all

#dev 能做应用层的人也就是永远只会去做应用层吧... 因为你们对这些不感兴趣,也没什么,扯不到什么优秀不优秀上面去,各有所好而已(其实也不然,我发现很多老一点的程序员后来都会从脚本小子步入理论或者更底层的工程,看你们的性格了)

不过是我游戏都懒得玩成天弄这些东西,然后你们放松就是玩 Ingress、然后其他游戏什么的... 玩 Android 的也有,我也非常喜欢玩 Android #CoolApk #GeekApk (当然别喷这个了,都过气了)(再者,士别三日即更刮目相看,我已经不是 18 年的我了)

当然也有人喜欢用自己应用、看自己应用得奖、发展,卖到钱时候的成就感,喜欢和自己的用户插科打诨,有人只是单纯喜欢写应用,或者喜欢练习写应用,反正都没什么的,各有所好。

这个 foldl 就是 foldLeft,Kotlin 里当然也有(说明 Kotlin 其实也蛮函数式的,删除)(因为是废话啊)(Kotlin 显然比 Java 8 什么的更函数式,当然 Java 9 比 8 其实变化不大,主要还是方法本地变量支持类型推导不用明写了)(所以冰封哥会说垃圾 Jawa)
(当然我还赶不上去年他的水平,我都不知道他到底上不上学... 怎么就有这么多时间拿来玩这些东西,真 TM 是好知者不如乐知者)(看看这篇 Agda 教程博文,还是他讲『简单』东西的,然后 2017 的他写的 9012 年的我都看不太懂)(成都的学校都这么优秀么,这还有没有天理了...)(好吧,就是比你优秀,不服拉黑...)

(我可没有这么智障,不服拉黑什么的)(那可真是智障)(接下文)
duangsuse::Echo
GeekApkSpecShort.pdf
懒得整理了,就用这个(接近 5 个月之隔

https://start.spring.io/

如果弄好了,那就临时以一个早已死去的并且不会进化的早期 #GeekApk 的名义(反正我也算是早期成员吧,呵呵)自己部署然后试用,寒假可能会稍微包装一点拿来暂时用一下(H2O2 能用之前)

我以为我现在的工程能力,包括 Trumeet 那个 MiPushTester Vertx Server 我都完全能理解,并且流程我都会走,Future(就是 Promise) 、HTTP、JSON 之类的都不是事(而且部分技巧我现在还不需要会,只是 trivial 的描述一下模型和要做什么就可以了)... 和 Dockerfile 一样,即学即用,比 Haskell 的自动 HM 类型推导算法好学『使用』多了


说的也是,JavaEE 一直以来的问题就是难以开启一个新项目(不是我说的,这可是 JBoss 项目的某个 dalao 的看法)
Spring Boot 可以说是完全解决了这个问题,非常的简单,实现上面那个 pdf 里的服务需要什么模式一条消息文本长度限制内都可以解说明白
duangsuse::Echo
类似这样,当然都是很模式化的代码不必说
#GeekApk 打算重构,不过这几天我肯定要先讲点东西休息一会... 过几天才继续
duangsuse::Echo
考完试回来看看这个... 其实嘛,有时候我会觉得理论或者说学术、工程或者说实践并非是平级的东西 #tech #dev #CS 有的时候大家或许能感受到,很多理论非常 NB 的大佬工程都很 NB,而且他们从来不把他们 NB 的工程当成什么(举个例子,从 09 年开发到现在的 G'MIC 计算机图形学系统,很多滤镜插件的发布就简单一篇帖子,开发从来没有专门讨论什么或者写什么博文,非常低调) (说到这里,我现在开始有点不是特别相信 WWW 上会传给大家的知识了,不得不指出,现在如果单单用那些 General…
#INFO #GeekApk #backend #web #dev

因为放假回来第三天 duangsuse 已经讲得十分痛快了,而且没有啥特别要紧的事情,考虑到有些东西时效性很重要,所以 GeekApk 继续设计重构。
实际上因为我没花多大力气去写(这里没有自夸的意图,你们看看我被那群数学天才们逼到什么地步了...),我打算后来完全重写,为了效率会考虑使用 SpringBoot 先,然后再重构。

期待 GeekApk 的出现。

— duangsuse, Feb 1, 2019
#GeekApk emmmm...
#GeekApk #GitHub #Dev 百提交留念(
Forwarded from duangsuse Throws
#GeekApk #Backend
当然,这不意味着我会等到写前端的时候又折回来解决后端有 bug 甚至根本没法用的问题,目前我觉得还是先弄个 Ruby 的 client library,然后我可以用 Ruby 客户端手工测试、或者使用测试脚本(因为我让 Hibernate 每次服务器重启都 create-drop tables 了,所以是 repeatable 的,很不符合 ACID 的 D 但是很符合它的 C,跑)来黑盒接口测试

至于这个客户端的编写,当然是直接在 GeekApk SB (滑稽)这个项目里继续写... 所有真正的 JsonRPC 接口绑定代码都会使用 GeekSpec 和 Ruby 元编程自动生成(因为 Ruby 是一门非常灵活的语言,真心的,反正现在弱类型就是****)

(所以使用 GeekSpec 语言定义 HTTP 接口的代码复用好处又在此处显现出来了,跑,这̶个̶可̶比̶一̶些̶强̶类̶型̶ ̶O̶O̶ ̶语̶言̶的̶设̶计̶模̶式̶爽̶多̶了̶)

那么就这么愉快的决定了(恳愿)
#GeekApk https://github.com/duangsuse/GeekApk/commit/ca554b78c042da018366f5138c6799bfe3707522

控制器逻辑的最后一道坎🤔
写完,就开始正式实现控制器逻辑了。

管理员用户验证已经实现了,手工测试正常(但是目前服务器好像不会自动创建第一个管理员用户,是个问题)

用户验证部分,估计一时间考虑的不周全,有些验证应该抽出来单独做的,然后有一个 general 一点的逻辑的可以用 middleware 实现


现在好像越写越没有信心了,大概是垃圾代码写多了(是真的,好多余赘代码、非常平铺直叙或者莫名其妙),时间拖长了(绝望)

我不想重构重构重构... 能用就可以,等待 v2 重写吧(绝望)

有没有愿意帮忙一起实现的(
(先熟悉一下分析环境,CoolApk 的 API Spec 待会再写) #reveng #GeekApk #CoolAPK #PL
Spectrum 我觉得非常需要重构,我会给 DSL 制定新的语法规范,因为实际使用中,我能看到很多东西并不是开始我设计 DSL 的时候想的那样... DSL 目前有点太混沌了,新的 GeekSpec 1.0 将能兼容 GeekApk v1b 和 CoolApk v6 两款实际应用的 API,一样简洁富有表现力的语法,但会有更清晰的描述语义和更多的特性(比如返回状态 matching)。
所以 CoolApk 的 SPEC 文件我还是要写,但暂时不打算重构 Spectrum 来支持 CoolApk 的新 API 特性,暂时可以用一些 Workaround 方案支持某些 API,感谢 Ruby 的灵活吧(迫真)

====

新的酷安 liba.so 没有很大区别,编译的时候少加了一个不需要的 liblog.so 依赖(实际上它不(向 logd)打印任何 log,这是无用的依赖,但当时我比现在菜所以移除这个依赖甚至对我来说比较难...)

看起来,不过,虽然好像业务代码没有用 C++ 异常,还是依赖了 __cxa_finialize (好吧这点是我弄错了,那不是 landingpad personality 函数(迫真))

我拿到的 liba.so 是 liba 的 x86 版本,因为比起 ARM 我更熟悉 x86,而且 CISC 机器一般更好分析
这个版本是从 coolapk.com 拿到的官方版本,酷安 v8 com.coolapk.market, platformBuildVersionName="8.8.3", versionCode = 0x1ba289, usesSdk: [0x15..0x1c]
(信息使用 ~/Android/Sdk/build-tools/28.0.3/aapt dump xmltree f81b5d8361e1e197cd336a443710532e-0-o_1crp2etomvdkhmr1kfq1ghh18c6-uid-408649.apk AndroidManifest.xml 获得)

== 它包含这些动态链接依赖:
它依赖以下外部函数:memcpy / memset / strlen / sprintf / strcmp / time / strcat
还有这些无关算法本身的依赖:__cxa_finalize / __cxa_atexit / __stack_chk_fail / __stack_chk_guard
它的导出符号:BD / BDL / BE / BEL / MI / MU / MF / r / bd / me / be / Java_com_coolapk_market_util_AuthUtils_getAS

JNI 使用的只有 Java_com_coolapk_market_util_AuthUtils_getAS 这个符号
逆向重写过的只有 BEL 这个函数,它的定义如下(C):

int BEL(int n) { return (4 * (n - 1) / 3 | 3) + 2; }

借助逆向分析 CoolApk X-App-Token 生成算法的机会,我也顺便学习了一些 X86 汇编的知识。

我觉得运行时替换掉这些函数,添加 log 参数和返回值的代码可能有助于分析算法

编译时采用了 stack guard 反溢出机制
cooltok.zip
24.6 KB
第二次,明天就上学了 emmmm #life #school #GeekAPk #reveng #CoolApk
说了这么多,其实我很想试着设计一点简单的 Android 应用了(GeekApk 的事情,其实也是需要这一层的,所以不冲突,而且我不是还有四个月后的暑假么,绝望hhhh),不过我最后还想写几句喜欢的古文:

#PL #PLT #Learn #statement #life #backend #Android #GeekApk 🤔

+ 见贤思齐焉,见不贤而内自省也。 — 《论语·里仁》

每次看到各种各样的大佬,总是乐意岔开自己可能在做的机械的工作而愿意跟着大佬的博客更新、知乎专栏、GitHub 等知识渠道努力跟随大佬学习新知识,步入新的知识体系、新的学习方向,就是说『见贤思齐』

现在随着软件工程的发展,越来越多的人开始进入工程界,相比曾经的软件工程,软件数量上可谓是不再有啥危机了,大数字会说一天内,能查出的新恶意软件数目达到 20k 多个
当然,随着软件工程的门槛越来越低,各色格式中国式培训班学院和垃圾三本院校技校的原学员也会加入实际的『工业界』,这么多不同能力程度的人混在同一个社群圈子里,鱼龙混杂、良莠不齐,声音难辨。
也能看到越来越多娱乐人士在各大娱乐网站发表的蜜汁言论和各种垃圾『代码』,垃圾提问了(比如冰封哥吐槽的弱类型比静态强类型『灵活』的言论)
有的东西,不看就好,有的有点价值的设计不当,应该实时记录下来,告诫自己不能也做某种设计,这就是说『见不贤而内自省也』

+ 路漫漫其修远兮,吾将上下而求索 — 《离骚》

无论是电子电路、嵌入式、位运算、操作系统、信号处理、SIMD 并行化处理、计算机图形学算法的知识,还是 Android 开发/Qt 开发/.NET Form/Java AWT/OpenGL、Web 开发、用户界面设计、艺术设计多媒体处理、网络安全、软件架构,抑或上到 LLVM 编译器框架的 Pass、移植,上到程序设计语言的理论和类型系统最新的研究方向、人工智能算法,都不吝惜花时间学习而提升自己
此谓『上下而求索』

即使这些都是『慢热』的领域,即使可能都要看到数百篇文章甚至大几十页的论文,即使可能每个子程序都得自己写才能学得足够扎实,也不放过一丝提升的机会
即使一点『基础知识』都要数百个小时来学习,每次学习都得努力在脑子里模拟所有流程,或者用计算机辅助画图、找资料、写算法计算也不辞辛苦地坚持继续做下去
此谓『路漫漫其修远』

+ 教学半 — 《书·商书·兑命》

因为学习的理论或者实践方法不总是会经常用到的知识,而且为了验证自己所学的扎实性、进一步升华自己对模型和流程的理解记忆,好的学习者会经常通过类型写博文『教』的方式来巩固强化自己的学习效果,他们会遵照着 Internet 『自古以来』的秉性 — 开放、互联、共享,把自己的知识无私地分享给类似自己的学习者,让后来者可以花更少的时间,得到更深刻的知识

教人是学习的一半,只写代码实践而不设计问题教着别人一起分析解决,你就只得到了知识的一半!

+ 纸上得来终觉浅 绝知此事要躬行 — 《冬夜读书示子聿》

即便是『教学半』了,也依然可能有注意不到的地方,计算机科学最大的魅力就是,你写的算法都是可以被计算机执行,快速地给出相对严谨的结果的。
计算机科学上,绝大部分理论最终的归属还是实践,不实际的设计算法解决问题,难以理解问题的精髓。
此谓『纸上得来终觉浅』

对于算法的学习者来说,通过实际执行来学习编写算法,『执行』的重要性再怎么强调也不为过,而且最好是直接在计算机上执行,实际计算机计算环境与理想环境会让你发现算法核心内容与实现时要做的事情,还是有些许差别,甚至对于一些比较数学的东西还得再设计另外一种算法来达到『计算机移植』的目的
此谓 『绝知此事要躬行』

如果只满足于在纸上的草稿和脑中的模拟而不实际编程的话,有时候会脱离现实世界编程的初衷,离实践越来越远

比如,编译原理里,一个比较常见的问题 — 局部作用域,有时候一些书上教的不是很好,不会很全或者有些没说清的地方(有的书不是专门讲这些的),或者可能不适合实现时的实际情况(比如,希望编译成一种虚拟机的字节码再解释执行),而实际自己写一个支持局部作用域的解释器,才能把诸如 dynamic scoping 的 binding 理论学扎实,还有可能悟出 static scoping 的实现方法

+ 臣之所好者道也,进乎技矣。始臣之解牛之时,所见无非牛者。
三年之后,未尝见全牛也。方今之时,臣以神遇而不以目视,官知止而神欲行。
依乎天理,批大郤,导大窾,因其固然 — 《庖丁解牛》

计算机科学之所以科学的地方,在于用 nontrivial 的眼光看计算机本身,以及它们可以解决的问题,还有实际实践中出现问题的模式和本质

学 Java,开始的时候,大家可能都菜到只会『写』代码,甚至看不透一个简单变量声明的模式,只是知道这个东西『复制粘贴』,修改一下『它的名字』就好了(其实一些人开始的时候还惨一些,不会『写』代码,只能改代码甚至只会看代码,更有甚者连模式识别都做不到,看不懂空格分开的几个单词...)

只是知道那些东西是那么写的,可能一些会写英文句子的人,都会编程吧。

但是后来,有些人开始能看到这些语法结构后面的类们的继承之树,看到继承和重写的本质、看到 OOP 的多态体现、看到字类型系统
虽然他们开始不知道有这些这么多装逼(虽然也没怎么装逼)的名字,但是他们会用!
他们会开始在实际工程中学着把自己的业务(对象)逻辑抽象成类型和静态方法,甚至做成可重用的组件
然后这群人就成了架构师 🤔

另外一些人可能开始试着总结自己看到的模式, if (Exp) Statementwhile (Exp) Statement...
他们也可能会注意到一些小的语法差异细节,注意到『变量』的作用域区分,注意到变量声明还可以加上各种被总结成『flag』(modifier) 的东西(final, public, volatile...)
后来这群人可能就成了编译器工程师 🤔

我只是举个例子,当然不可能这么简单的,除非是天才。 😵

所以呢,技术的提升很多时候应该伴随着视角的提升。
当 John 开始超离『变量要先定义再使用』的魔障,了解空类型安全和类型系统,开始看到 JVM 的全貌之时,他的世界就开始向2宽广化发展了。
羽毛的小白板
极端 https://www.zhihu.com/question/317346252
#backend #GeekApk #SQL select * from yourTable limit 14 offset (4-1)*14;

🤔 我之前设计的 GeekApk 还没写 Database service 层,可是我居然因为没写到最后就不知道这个东西... 虽然我知道 SQL LIMIT,但我所想的却是 先 LIMIT 查询了之后,结果上 JVM 再去 subsequence...

我甚至还真把这个当回事了,还以为得专门抽提一个函数完成分页功能(geekapk API 的分页是很灵活的,使用的参数基本等价于 LIMIT 和 OFFSET)

还有,我刚才居然以为 LIMIT OFFSET 的 LIMIT 是基于整个关系行表头位置来说的偏移量,也就是说得 SELECT * FROM _ LIMIT (4-2)*14 OFFSET (4-1)*14... 简直毫无脑子

A, B, C, ... 都是关系元组

Table = [A | B | C | D | E | F]
SELECT * FROM Table LIMIT 1;
[A]
SELECT * FROM Table LIMIT 1 OFFSET 2;
[B]

(define pageSize 3)
(define collect-page' (pageSize page)
SELECT * FROM Table
LIMIT ${pageSize} OFFSET ((${page}-1)*${pageSize}))
(define collect-page (n) (collect-page' pageSize n))

(collect-page 1) = SELECT * FROM Table LIMIT 3 OFFSET (1-1)*3
[A | B | C]

(collect-page 2) = SELECT * FROM Table LIMIT 3 OFFSET (2-1)*3
= [A | B | C <OFFSET:3> D | E | F] Read 3
= [D | E | F]

== UPDATE: 我刚才用 SQLite 3 测试了一下,SQLite 其实是从 0 开始索引的,所以上面的是错的,我应该再减去 1...
至于为什么他们自己的就没有问题,是因为第一个 (1-1) 碰巧是 0,forall n in {R}. 0*n = 0,但是如果不为零,就得考虑零基数组的问题了...

create table test(text name);
foreach(x in listOf('a', 'b', 'c', 'd')) insert into test values(x);
select * from test limit 3;
select * from test limit 1;
select * from test limit 1 offset 1;
select * from test limit 1 offset 0; -- no returning records

(没用到啥关系代数知识,一方面也是关系代数那点操作符不够,虽然可以自己造新含义...)
唉,看来我还是了解的不够仔细。
#geekapk 我也不是不想继续 github.com/duangsuse/GeekApk(肯定要重写的), 只是现在真的没有时间啊,哪怕写了后端,服务也部署了(虽然都很幼稚,我该去学学 J2EE AS 架构、JPA、JTA、JAX-RS 什么的)
没有 Android 客户端依然是白搭,肯定需要至少十天时间我才敢动键盘。
永久封存 | Yuuta 台 | 😷 #Pray4Wuhan
为什么我认为 工欲善其事,必先利其器 是不完全正确的 工欲善其事,必先利其器 这句话大家耳熟能详,尤其是在各大社交软件(如某乎)的教程上,总有 【大神】 上来就给你塞上这句话,说先做好准备工作 balabalabala。我从一个业余开发者的 situation 出发,分享一下自身感受,以及为什么说 工欲善其事,必先利其器 是不完全正确的,而且会耽误时间。 比如,我最近在研究 Android 源代码的学习方案,如何开始学习 Android 源码,知乎一些大神给出了方案。某个回答的第一段就是讲某源码阅读软件比某…
我觉得,就为 #GeekApk#GeekSpec 这个例子来说,是正确的,至少我不用去做一些完全体力的工作了... 虽然 GeekApk 还有部分 JavaEE / Spring 的模型接口/子类实现什么的必须手写,逻辑也必须用 Kotlin,但自动化无必要的、模板化的部分重要性不言而喻。

后面同样基于 GeekSpec 的 Spectrum 自动化 HTTP API 客户端程序,更是肯定了这么做的价值 — 写出接口定义本来的样子,最大可能去压榨它潜藏的用途

#UNIX 哲学里也提到一句:程序员的时间比计算机的时间宝贵,所以如果可能,就要写会写程序的程序,让它替代程序员工作。

优先使用工具而不是拙劣的帮助来减轻编程任务的负担。工欲善其事,必先利其器。
duangsuse::Echo
可惜没有绘制成图表 plot 好看一些 🤔 r.size #=> 187 一共统计了 187 条消息。 r.sort_by { |it| it['published'] }.first['published'] => 2019-03-24 11:22:00 +0800 第一条消息是 2019-03-24 11:22 发送的 r.sort_by { |it| it['published'] }.last['published'] => 2019-04-05 20:06:00 +0800 最后一条消息是…
😃 那么,简而言之,我觉得有价值的信息:

def get_link(h); "https://tttttt.me/dsuse/#{h['debug']['no'] + 9511 + 20}"; end

+ 一共统计了 187 条消息。

2019-03-24 11:22 - 2019-04-05 20:06,一共两个星期的时间里,本频道 @dsuse

+ 有 #Telegram Hashtag 的消息,一共有 42 条,约有 20% 的消息被打上了标签
+ 含链接的消息,一共有 37 条,约有 19% 的消息被打上了标签
+ 链接和 Tag 都有的消息有 17 条,占总消息的 9%

map { |h| [h['body'].size, h] }.sort_by { |it| it.first }.reverse
map { |h| [h['body'].size, h] }.sort_by { |it| it.first }.reverse.first[1]['links'].size

+ 187 条消息里,最长的消息是这条,它有 4475 个字 — 连链接都有 25 条! 🤪
+ 187 条消息里,折行最多的消息是这条,它有 4232 个字和 7 条链接。

sum { |it| it['body'].size } / size
+ duangsuse 的平均字数:359 字 / 消息

sum { |it| it['body'].lines.size } / size
+ duangsuse 的平均行数:11 行 / 消息

find_all { |it| it['header_type'] == 'REPLY' }.size
+ 过去的 187 条消息里,有 70 条都是回复,占总量 37%

find_all { |it| it['header_type'] == 'FORWARDED' }.size
+ 过去的 187 条消息里,有 45 是转发自其他频道或个人的,占总量 24%
当然,这 70 条都是回复本频道消息的。

a.uniq.map { |u| [u, a.count(u)] }.sort_by { |it| it.last }.reverse.to_h.each { |e| puts "#{e.first}: #{e.last}" }
+ 转发者和条数表如下:

IT 那点事 (YuutaW 鱼塔): 10
羽毛的小白板: 10
duangsuse Throws: 6
Rachel 碎碎念 (IFTTT): 5
Rachel 的消息发布站点 (Rachel Miracle.) via @like: 3
YSC 的频道: 2
duangsuse ¯\_(ツ)_/¯ |学渣 | 我爱学习 | ∈ [E²PROM, 范畴论]: 2
Doge: 2
YuutaW 鱼塔: 2
Rachel 碎碎念 (湘江一桥): 2
DogeSpeed广播: 1

😄 @haneko_daily 被转发的次数最多,继续努力!

sort_by { |it| it['hashtags'].size }.reverse
+ 具有最多标签的消息是这条,它有足足 8 条标签!

sort_by { |it| it['links'].size }.reverse.first
+ 具有最多链接的消息是这条,它有 25 条链接!同时也是字数最多的消息!

find_all { |it| it['header_type'] == 'A_PHOTO' }.size
过去 187 条消息里,一共有 29 条广播是单纯的一个照片 🖼
find_all { |it| it['header_type'] == 'A_ALBUM' }.size
过去 187 条消息里,一共有 5 条广播是照片集 📸
find_all { |it| it['header_type'] == 'IS_STICKER' }.size
可爱 🐱 的 duangsuse 在过去 187 条消息里使用了 28 个 sticker 抒发自己的感情,使用的表情这么多:
find_all { |it| it['header_type'] == 'IS_STICKER' }.collect { |it| it['ext'] }.yield_self { |r| r.uniq.map { |u| [u, r.count(u)] }.sort_by { |it| it.last }.reverse.to_h.each { |e| puts "#{e.first}: #{e.last}" } }

😔: 7
😳: 4
😲: 3
😡: 2
😑: 2
🙄: 2
😋: 2
😀: 2
😥: 2
🍹: 1
😐: 1

find_all { |it| it['header_type'] == 'HAS_FILE' }.size
duangsuse 在过去 187 条消息里发了 8 个文件,它们是:
find_all { |it| it['header_type'] == 'HAS_FILE' }.collect { |it| it['ext'] }
["axml.rb", "AndroidManifest.xml", "AndroidManifest.xml", "TextSort.kt", "RandomPicture.kt", "Vibrator.svg", "Vibrator.png", "Vibrator.svg"]

最火的
hashtags 组合:

collect { |it| it['hashtags'] }.yield_self { |r| r.uniq.map { |u| [u, r.count(u)] }.sort_by { |it| it.last }.reverse.to_h.each { |e| puts "#{e.first}: #{e.last}" } }

结果太长,在这里查看

所有 Hashtags:
hs = s.flatten.find_all { |it| it.is_a? Array }.flatten.map { |s| s.tr(" ", "") }
"#" + hs.uniq.join(' #')

#Android #zhihu #KDE #Low #Haha #life #tech #tencent #WeChat #weibo #share #tools #dev #Markups #Telegram #Hack #aop #Huawei #通知 #Freedom #sysadmin #GitHub #travis #CI #Sysadmin #Linux #Coolapk #Web #frontend #HTML #China #school #Microsoft #Life #VisualStudio #-} #OOP #web #geekapk #doge #CS #fix #CSharp #School #blog #recommended #bin #backend #Kotlin #Java #Share #svg #blogPOst #PL #JVM #Moha #code #ALgotithm #DuangsuseSB #GeekApk #SQL #Learn #wiki #Mozilla #ES6 #JavaScript #MoHa #Paper #haha #dotnet #bad #OOP_Delegates #Parallelism #dotNet #Csharp #Windows #performance #Channel #weekly #linux #Ruby #Project

以及他们的消息覆盖个数:
hs.yield_self { |r| r.uniq.map { |u| [u, r.count(u)] }.sort_by { |it| it.last }.reverse.to_h.each { |e| puts "#{e.first}: #{e.last}" } }

太长,这里看

== 非线性查询(当然和算法上那个没有关系啦,就是复杂一点的查询)

// 收集所有单 / 双数索引

ar = []; ar2 = []

i = 0 // 0 2 4 6
while i < self.size; ar << self[i]; i += 2; end
i = 1 // 1 3 5 7
while i < self.size; ar << self[i]; i += 2; end


aa = ar.zip(ar2)

我们将比较相邻两消息之间的关系。

aa.zip(aa.map { |ms| ms.last['published'] - ms.first['published'] }).sort_by { |p| p.last }.reverse

间隔最长的两条消息是这条这条,间隔 44880 秒(12 小时)

b.map { |h| [h.last, h.first.first['body'].size ] }.map { |a| a.last / a.first }.select { |it| not it.nan? and not it.infinite? }.sort.reverse

平均打字速度:7 字 / 秒 🤔

受到解析度(只到分钟)和浮点运算准确度的影响,有很多消息都是在间隔一分钟内发完的,统计结果可能不正确。

好啦,还有什么别的信息,请大家自己来发掘呗( 😝 比如说,我熬夜发过多少消息。
https://github.com/duangsuse/GeekApk/blob/master/geekapk_v1b_api.geekspec #GeekApk

GeekApk 的 GeekSpec 规范即将准备制定 v0.2 新版本,新的规范使用了宏预处理和 Markdown,将支持使用 SPEC 语言进行控制器编程(所以可以将能自动生成的逻辑尽可能自动生成)

🤔
#GeekApk 最后我吐槽一下,然后去写 DJson 吧(浪费了太多时间,DJson 还要写一 TextInputStream 代理呢... 虽然不需要 parser combinator

欸话说刚才看的时候又见到了汉语机器学习 + 歌声合成的实例... 即使在 B 站...
这年头啥都逃不过浮点计算... 😕
NVIDA 的高性能计算库 OpenSeq2Seq: toolkit for distributed and mixed precision training of sequence-to-sequence models
可以用于语音识别和合成、自然语言建模处理等流行操作...

这年头不想当码农难啊,要不然就得学习『使用』一些自己看不懂的东西,做『用户』... 😐


> 我主要想看看谁会继续领导
> 否则就是瞎写嘛

< 没有生产力,活不下去,哪里有闲心政治,就像一群没有自理能力的人无法组成社会一样


这是前几个星期我在凉了的 GeekApk user 讨论组看到的一小段消息

🤔 duangsuse 想关于这些『创业』系信息技术『从业者』发表一些自己的看法。

🗒 此广播不应在任何程度、任何侧面上被理解为对『创业』的不敬、对群不对人,请勿对号入座。

——
GeekApk 嘛... 一些人可能以为是我自己开始想搞出这个坑来叫一群仇酷安(当然,也可以说,是“恨铁不成钢”,可惜我们并不拥有酷安,呵呵)的人一起填或者要组队破坏酷服务的(GeekApk 组曾经是有一次被拿来组织了一次 DoS,目标是酷安的静态页面,并且导致了主要酷服务(这里分为 coolapk.com, dl.coolapk.com, api.coolapk.com, 主服务是说 coolapk.com 主站)宕机半小时,当然,也有可能是酷安本身土豆服务器过于辣鸡导致的,我不是此活动的策划者,甚至不是 GeekApk 的『管理者』,也不能算是『创建者』,对酷安的『失去初心』亦无仇视心态)

其实真的不是,我开始比较 naive(正如当初我以为,why Rust? It's fast!),就是想自己弄一个,本来的『项目』是 Dropage,虽然只有一个『蓝皮书』(现在可以说是『烂』了,呵呵)

后来呢,就不得不提到 @iVanilla (现在 Deleted 了... 或许是主动删号的吧,或许... 😶) 弄出了 GeekApk 项目(我自己不想咸得没事去组织一群人弄这种事情,虽然他说是自己早有想法,但是我在某小群里提到自己的打算后再找我私聊讨论并且建立 GeekApk 的,虽然我开始天真无邪 Too young too simple, 但是也不至于捅出这个篓子,因为我打算自己弄,弄完了... 呃... 我觉得照那个样子啥都弄不完),不得不承认他是很好的进行了一些『商业』上的帮助,并且讨论了一些『商业』上的东西... 可惜后来 GeekApk 是这样,那么我这条广播,是想告诉你们为啥它『咕咕』了,为啥会是这样而不是我们都认为的皆大欢喜 good ending — 大家齐心协力弄出了类似酷安的东西,然后欢天喜地地入驻进去,开始的人全成了 GeekApk 里最 dalao 的权限,然后本来『屈居』在酷安的人也都过来了,本来只知酷安的人后来也注册了 GeekApk 帐号,GeekApk 一周年,大家都高喊 GeekApk 万岁万岁万万岁... 还要成立什么米国美国公司,拉赞助... 😶

嗯,drakeet 曾经直白地批判过 GeekApk,除了他无视本组都是一群运维菜鸡而且我仍在学习之外(恕我直言,而且也未必有人维护着多大的集群,体验过什么分布式架构和高性能计算技术)『空壳』我还是很认同的,当然不要以为我也顺带着『仇视』他,我对技术比对人更感兴趣,看问题一向对事不对人。

https://github.com/GeekApk 到现在真正的错误,上面『幼稚和空壳』已经能很好地概括出来了

有些人说 GeekApk 错在用爱发电,在我看来真正致命的却是另一个缺口:用爱发电,其实也未必不可,在自己的业余时间(可能足够长)里做想做的事情,在自己的经济能力范围内要求必要的服务,本来就是人生的一大乐事,可是那个 GeekApk 却是要你用不断咕咕叫🐦的空头支票去给『酷安变质』的信仰充值,这就不行了。

信仰自然还是要有的,可是有一天没有依附的希望终将消散,光靠信仰光环,画饼充饥,能扛过一天,扛得过一年么?

所谓的项目,没有拥有基本技术能力的参与者,没有能做实事的人,就好比一台没有电源的机器,连动力都没有,你说它该怎么工作?靠推吗?你说没有人有能力写代码的『网络技术公司』靠什么去做项目、做产品、做平台、占领『市场』?靠『xxxx 天内出 OO』的承诺吗?

崇才科技。大家都认为是吹的,可是,没有那些抄来、改来的『产品』,想来媒体要炒作,光靠某泽的学历怎么这么高,故事怎么这么大佬,也无物可炒啊?00 后开公司,前浪死在沙滩上啊,哇好厉害,可是有啥东西做出来呢?
没有?那有啥好说的?
可是他们这群脚本小子,『自己动手』(“丰衣足食”)『做』出来了『崇才』课表、『崇才』萌狼输入法,加上『无薪资』『QQ 群』等『企业』 flag,就像是真正的 SOHO(Small Office Home Office) 公司了,何况还有名分的,不是么?

GeekApk 还要降一档次,因为名分上的东西都没有,我们也没人『自己动手』去把酷安复制一下(这种程度能力的人都没有,好吧,的确有一个高性能计算的大佬被我『赶跑』了... 其实那时候 GeekApk 连个设计本本都没有,不像 R 还有个第一版明确定义),没有一个拿来骗人的『酷极安』『产品』,也没一个 50w 资本的注册公司和大手子转发评论,最后当然是烟消云散啥都没留下。(呵呵

GeekApk 需要的是什么?是白皮书、贷款、基金、股票、融资、股票期权、资金链、生态圈?是项目?是员工、运维、CTO、CIO、CEO、COO?是 “用 Trello”、“用 Rails”、“用 Laravel”、”用 Go“、“用 Vue”、“用 OO”?是 “不能『抄』酷安”“即使身死绝不自我审查”?它们都出现过,都消失了,说到底,『产品』的核心还是靠着软件工程实战的程序逻辑,其他的,『一步到位』、测试、文档、打包、可读性、可扩展性、可维护性、健壮性,编程技巧,都是次要,『库』的核心还是抽象、架构和算法,『应用程序』的核心还是业务逻辑,产品的核心还是你要提供的东西本身,其他的,在没有一个存在的展开基础的时候,都是一纸空谈。

著名计算机科学家沃思(NiklausWirth)提出一个公式:
  算法 + 数据结构 = 程序
其中算法是程序的灵魂。

是灵魂啊!你到底想干什么?你知道吗?

在你还没学会走好路之前,不要被眼前斑驳陆离的世界迷惑,拒绝政治、拒绝形式主义,就是给自己一个更广阔的天空。
— duangsuse, Sun Apr 21, 2019
#sysadmin 说起来之前 #GeekApk 的 VPS 也是 Archlinux 装的...
GAPP项目.txt
2.2 KB
#GeekApk Prototype Project 组成,其中很大一部分(比方说,Literate Kotlin)我都已经打过不少实现稿了(就拿上面那个来说,我都考虑过怎么解析 .kt 文件跨模块引用和拿到其他模块的 html 地址了,也考虑过如何使用 TokenizerRangeMap 进行高亮和加引用/id、多个<code> 如何『视作一起』解析如何『分开来』高亮引用处理操作,staging-intro 主要的内容和布局也想好了)