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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
那么就到这里了,这的确是一种不错的方法,可惜花的时间也是比较长... https://github.com/duangsuse/GeekSpec-GeekApkv1.0b/blob/master/geekapk-1.0beta-zh_CN/models/comment.api-inline.md#entity-relation-comment Entity Relation comment Belonging to User by author on delete set -1…
没人打星... 考虑到这个只是 draft 的原因就算了,但我真的写了几个小时的... 那我就设置 vote 吧,既然怕污染自己的 GitHub star 列表就在这里打星... 别吐槽『毛都没有』什么的,看在 GeekSpec 0.1 的确有两个工具(虽然没和 Gradle、Maven 什么的集成)的份上好歹打颗星...
https://github.com/duangsuse/GeekSpec-GeekApkv1.0b 吼不吼啊? 🐸
anonymous poll

吼,概念不错 – 1
👍👍👍👍👍👍👍 50%

上面的不吼兼而有之 – 1
👍👍👍👍👍👍👍 50%

不吼,格式有点太冗长了
▫️ 0%

不吼,严重怀疑是否真的能如你说的那样利用 Markdown 文档生成代码
▫️ 0%

不吼,严重怀疑预处理器是否能实现
▫️ 0%

不吼,严重怀疑 Markdown 解析器是否能实现
▫️ 0%

不吼,还没有写出 API 规范格式呢
▫️ 0%

懒得看了
▫️ 0%

👥 2 people voted so far.
#Android #dev ... 怎么又扯到 drakeet 又是这种撕逼...
Forwarded from AlPlank [Courtyard]
我是简体用户…无语。
Forwarded from duangsuse Throws
恕我直言(情商为零)我觉得,所谓不擅长回复的『技术人员』不适合叫做技术人员,真正的技术人员从来不害怕在任何时刻任何场地任何谈起任何领域的技术,他们会在生活中看到程序题,在不知道别人的抽象、模型时根据目标问题领域自己弄出自己的模型猜测,把一切符号背下来,一切 pattern 也都熟练于心、为自己的编程写工具、实现自己使用的程序设计语言,从高级控制结构看到指令流,学习 IDE 快捷键、重构,彻底理解测试、打包、部署和构建系统,至少不会做出有安全漏洞的设计,不断尝试攻破新的效率顶峰,从布局到 SIMD 到 TCP/IP 至网络层硬件内核驱动甚至密码学、机器学习、线性代数、数控、函数式编程,都不该害怕,这样才配叫做真正的技术人员。

如果你连 RSA 算法怎么手算都不知道,你怎么可能拿汇编去写一个 RSA 加解密实现?甚至可能带单指令多数据优化的
如果你连拼音有几个声母几个韵母、韵母是什么、声调是什么都不知道,怎么可能开发出语音合成软件?
如果你没有能力查找『不是你领域知识』的资料,没有看论文的能力,(假设你不学编译原理)编译器你怎么会写?解释器、Visitor Pattern、Annotation processor、2D 物理引擎这些哪里写得出来?
如果你连数学矩阵都不会,DIP (数字图形处理)算法对你来说就是天书,如果你连 sin cos 函数都联想不到直角三角型的图像,无法动动脑子就得出调用参数,五角星你都画不出来
如果你连关系代数、记录、外键都不清楚,那 SQL 和 Pg 的扩展对你来说只是抄
如果你连基础算法、暴力查找、IO 都搞不懂,那别指望应用编程了

🤔

编程应该是在脑子里,在生活中,你看到一个打水器、一部电梯都会想到要用什么控制平台,要怎么编程,而不是跟着已有的代码和 StackOverflow 走,有一句特别扎心的话:

离开了网络、GitHub,StackOverflow,现在还有多少程序员能编程?

我觉得最好的程序员,肯定都是在睡觉时都能想到人工神经网络学习回归运作的。

我们学校也有不少会各种奇葩技能的同学,比如魔方、折纸、飞扑克牌,我都不会(甚至篮球都不会打)... 不过我觉得,对现在的『程序员』『软件工程师』要求还是太小了... 居然只会会一种事情...

这就是我对技术人员的看法,在我看来,我的最终目标就是成为这种技术人员,在这之前,都不能拒绝学习
AlPlank [Courtyard]
我是简体用户…无语。
性格变化大... 不会就是我害的吧... 🤔 23333
哦... 那也好,至少我又能看他的技术了... 不过我这次绝不评论 🤔... 不过其实也很无聊的(除非我想写些 Android 应用,但 WinForm、Qt 的一些子系统,比如 resouces 抽象我都不是特别熟,Java 的稍微好一点),如果我做完了自己的安排就去看,待会发链接。
Forwarded from LetITFly News (LetITFly 让技术飞) via @like
https://t.me/drakeets/1605
我认为 Drakeet 的频道没增长多少粉丝的原因有一条是:国内来 Telegram 的 Android 开发者(相对于爱好者(用户)而言)还是太少了。

虽然频道主不喜欢基于微信的公众号/小程序等平台,但频道主能理解并尊重 Drakeet 将后续的技术文章放到知识星球的决定。

经过和 Drakeet 短暂私聊,我了解到:
Drakeet 是喜欢 Telegram 这款软件的,他也会继续上 Telegram 接受纯纯写作的反馈等。

频道主在此建议在座的各位一起维护良好的交流氛围,不要让更多的人心寒。
duangsuse::Echo
哦... 那也好,至少我又能看他的技术了... 不过我这次绝不评论 🤔... 不过其实也很无聊的(除非我想写些 Android 应用,但 WinForm、Qt 的一些子系统,比如 resouces 抽象我都不是特别熟,Java 的稍微好一点),如果我做完了自己的安排就去看,待会发链接。
另外,本频道虽然是『技术频道』但『干货』(这里指,大家平时会用的东西,比如 MultiType 的使用... 好吧,或者说别的,Android 控件应该怎么写怎么支持 from XML 什么的)比较少(而谈程序设计语言理论的有一些,我最近想讲二维文法),所以大家懒得看吧。(有些干货,比如软件逆向工程,则是因为大家太菜(恕我直言,很多人的确是这样的),没人看得懂反汇编而已...)

👆 上面一句被喷『菜』的回复之前容我卖个小,对比一下年龄,我 17,高二在读,每周接触电脑的时间不超过 8 小时... 我用 Fedora + KDE,平时最喜欢 Java/Kotlin/Groovy/JavaScript/Ruby/Python,偶尔有可能写下 C/C++/Lua/Crystal/Rust/CSharp/Haskell/Scheme 再偶尔 Assembly/TypeScript/Shell/Perl/AWK/SED/PHP/VisualBasic/Octave/Dart/Go/Julia?/Scala?/Clojure?,非泛向编程的 Makefile/CMake/QMake/HTML/YAML/JSON/Regex/PEG.js/Ohm.js/ANTLR/Flex/Bison,托一位 PL/FP/PLT 大佬的福我还会一点 Agda,可是懒得看『类似』的 Coq 和 Idris、FStar,可是不会 rewrite 归纳证明... 不过 OO 软件架构、Future、Fiber(非对称 Coroutine, Sequence, Generator)、容器类、类型参数化、组件化、依赖注入、函数式编程、消息队列使用、多线程、进程抽象、响应式布局抽象还是会的

隔壁羽毛(一个 MSCLR C# 开发者)的频道都(为啥要说都)比本频道阅读率高,因为大概还是刷的慢一点。
本频道... 呵呵。 🤪

啥时候我搞得懂 Haskell Monad 的理论... 使用我是会的
#lib #Android #tencent https://github.com/Tencent/matrix#matrix_cn

APM 居然还有这个概念,叫 Application Performance Manage, 就是应用运行时状态的管理,比如 Error trace 什么的(这就显示出异常系统的好了)
https://996.icu/#/zh_CN

“996”工作制,即每天早 9 点到岗,一直工作到晚上 9 点,每周工作 6 天。

“996”工作制的周工作时间为最低 12x6=72 小时。

中国大陆工时规管现况(标准工时): 一天工作时间为 8 小时,平均每周工时不超过 40 小时;加班上限为一天 3 小时及一个月 36 小时,逾时工作薪金不低于平日工资的 150%。而一周最高工时则为 48 小时。平均每月计薪天数为 21.75 天。


== 🤔 高二学生们又是如何呢? #School #China

+ 最幸福的时候,每天早上 7:00 到岗,这是指放假的那天,一般都是从早六到晚十
+ 一直工作到晚上 10:00 到 10:30
+ 每周工作 7 天,周六放假一晚上,周日不休息

学生日工作时间
= 早自习时间 + 早课时间 + 下午课时间 + 晚课时间 - 休息半天占去的课程时间
= 40 + (40 × 5) + (40 × 4) + (40 × 3 + 50 × 1)
= 570 = 9 (hours/day) (1)

学生周工作时间
= (1) * 7 - 一个下午的学习时间
= 570 - 160
= 53(hours/week) (2)

“高中”工作制的周工作时间为最低 (2) 小时。
https://altair-viz.github.io/gallery/multiline_tooltip.html #Python 当然 Qt 也有 data visualization
C++ 虽然不如『数据处理语言』Python,但扩展可以很厉害(Python 也不过就是把一些 lib 实现的东西加了语法糖而已,C++ 照样很容易写),C++ 也同时支持了宏处理和模板、constexpr 编译期计算,不算是垃圾语言了。
LetITFly News
https://t.me/drakeets/1605 我认为 Drakeet 的频道没增长多少粉丝的原因有一条是:国内来 Telegram 的 Android 开发者(相对于爱好者(用户)而言)还是太少了。 虽然频道主不喜欢基于微信的公众号/小程序等平台,但频道主能理解并尊重 Drakeet 将后续的技术文章放到知识星球的决定。 经过和 Drakeet 短暂私聊,我了解到: Drakeet 是喜欢 Telegram 这款软件的,他也会继续上 Telegram 接受纯纯写作的反馈等。 频道主在此建议在…
知识星球... 我不知道向不向平台外开放(真正符合 WWW 的概念)

不过我在百度找到了 drakeet 之前的个人博客,现在没被删,当然你们不用通知他去删掉了,如果删了比较可惜,我可懒得再搞事,而且有些东西删了,以后我要重写记起来困难

OutOfMemeory 博客 http://ju.outofmemory.cn/feed/2166/ 这个内容比较多,都是 Android 开发的内容

CSDN 博客 https://blog.csdn.net/drakeet 这个没内容,基本是转载,drakeet 只写了几篇,我居然发现他还学过 C 语言会二进制换算,感动,真想改天我也写一篇分析...

简书 https://www.jianshu.com/users/5c4e75544fc3/timeline (主要是点赞)

https://www.v2ex.com/member/drakeet 基本不上了

🤔 感情不是不会,是学了没用上啊!唉... 怎么都学些不用的东西
duangsuse::Echo
知识星球... 我不知道向不向平台外开放(真正符合 WWW 的概念) 不过我在百度找到了 drakeet 之前的个人博客,现在没被删,当然你们不用通知他去删掉了,如果删了比较可惜,我可懒得再搞事,而且有些东西删了,以后我要重写记起来困难 OutOfMemeory 博客 http://ju.outofmemory.cn/feed/2166/ 这个内容比较多,都是 Android 开发的内容 CSDN 博客 https://blog.csdn.net/drakeet 这个没内容,基本是转载,drakeet…
#bin 然后为了证明我不比 drakeet 差,只是缺少拿来实践的时间, 我分析一下这篇文章《5分钟学会十进制转换成二进制的快速口算方法 & Java输出二进制的代码》,然后就睡觉。

当然,至于 Android 那一套,比如异步、Timer、MessageDriven、Android XML、Android Widgets、Resources、Android Gradle Build 集成、库打包、封装、Android Layouts、Views、Paint、Android Layout Animations、组件化、接口、持久化、SQLite、HTTP、Reactive、Activities 和之间的信息传递、Android IPC、MVP、Databinding、List model view、多线程等套路,还有平常的编程技巧,诸如 Annotation 什么的,都是次要,反正你们记得我被 drakeet 喷了而且看他那个反应很不爽就是了。我就是这性子。而我就自负地觉得我能比他会得多。 😝
虽然我不能在 5 分钟内看完这篇文章也不能在一分钟内为 CPython 和红姐加持的 Python 加上多行 lambda,但我有的是时间学。

大一寒假的时候我在学校里学C语言的补码时候学会了一种十进制换成二进制的方法,不知道学计算机的是不是也是这么算的,感觉比高中数学课教的那除2取余的方法快多了,而且容易掌握和不需要笔算。。。

首先我要吐槽一下,要知道计算机怎么算,为啥不看 libc source?不过一般都是取余的... 取余我不知道机器层面怎么实现的,据说是靠逻辑位移动?

首先作者举例
toHex(35) =
0x10 * 35 / 16 +
35 % 16 * 0x1
= 0x23 (这个是我靠着对 Nat 的理解强行猜的,当然我用别人教的方法也不差)

toHex(100)
= 16 * 6 + 4
= 0x64

toHex(1024)
= 16 * 64
= (需要进位64 = 16*4) 0x400

哦,我知道了,原来他是先算出 base=16 进位的数目,然后手动进位...

看出规律了吗?因为16进制的每一位可以对应4位的二进制数,... 我这么说可能十分不清楚,但也懒得去想更好的表达方法了,如果有人看不懂再说

嗯,这个本频道之前也提到过,至少我教过你们手动编码 base64,想来也不可能不告诉过你们 0x 是 0b 的简记法,因为 2^8 = 4*4 = 16, 或者说 log2(16) = 4

下面说的有点复杂

四位二进制数分别是8 4 2 1,比如说,16进制的3,就是2+1,就是0011,16进制的5,就是4+1,就是0101,意思就是说每一位16进制数都可以表示为8,4,2,1这四个数字的加和,若使用到,则该位为1不使用为0。我这么说可能十分不清楚,但也懒得去想更好的表达方法了,如果有人看不懂再说

我给个 table,就是说单纯四位二进制(之中一位为 1,其他都 0)

0b0001 = 2^0 = 1
0b0010 = 2^1 = 2
0b0100 = 2^2 = 4
0b1000 = 2^3 = 8

为啥要 (-1) 是因为我们算的是进位,看不懂算了(其实不是的,是我弄错 factorial 的定义了,后来改正了)(我也不清楚,爱因斯坦说过,如果你不能把道理给小孩子解释明白,那你自己也不懂,这是说我自己)。

比如说,16进制的3,就是2+1,就是0011,16进制的5,就是4+1,就是0101,意思就是说每一位16进制数都可以表示为8,4,2,1这四个数字的加和,若使用到,则该位为1不使用为0

0x3 = 0x2 + 1 = table[2] (0b0010) + table[1] (0b0001) (这是 16 到 2 快速换算法,类似乘法口诀,你尝试把数 n 与表中最近的整位相减,然后把余数这么做...)
0x5 = 0x4 + 1 = table[4] (0b0100) + table[1] (0b0001)

0bXXXX pat
0b0 <+8> <+4> <+2> <+1>
按这个 pattern 算,最大和为 15,就是 0xF

至于上面的 0x 0b 什么的,就是 C 风格的 16, 2 rhs literate 支持,我也不知是.... 前面第一位 0 是为了要有一个占位的

那么按照这个规律,你现在可以来尝试算一下十进制的307等于多少

就是 toBin(toHex(307)),我算算

307(10)
= 0x1 * 307 %16 +
let _10_0 0x10 * 307 / 16 +
然后我们发现 _10_0 大于 16,可以进位... 该死,我应该递归的,为啥要循环呢?(滑稽)

那么递归用 Haskell 很好写,我们来看看流程,反正我们是在编程:

+ 输入一个数 n,我们要一个 String,和当前进位的数值,它的字符串表示
+ 字符串表示 0x0 - 0xf,分别对应 0-15
+ 那么就有了一个递归程序,可是,算法是:

所谓自然数计数法,就是 0xFFF = (16^2 * 1) + (16 * 1) + 15
好吧,还不直觉,是 11 = 10 +1, 100 = 10^2*1 + 10^1*0 + 10^0*0
言而总之,就是把一个数化为数位相加的形式,这个过程中,如果我们用类似 C 的结构化方法,就是:

arg n
base = 16
var outs
ret n
for d = map (factorial base) (1..)
var r = n % d — rest
n = tailrec(n / (n-r)
)
outs « toHexDigit(n) « toHexDigit(r)
— 一个是进位的,就需要递归,一个是剩下本位的

那么我们来验证算法的正确性(一定程度上,你们都知道我在熬夜并且是算法垃圾)

n = 100

for, d = 16^1 = 16
r = 4
n = 6
outs = "0x64"
🤔 那就暂时认这个,虽然我知道它不对... 管他呢

307
= (算个位) 递归 (307-16^1) + 3 (16 余数,要进位的数)
= (16^1) 递归 (259-16^2) + 3*0x10 |(16^0) +3
= (16^2) |+3*0x10 |+3*0x1

🤔 ... 看来没写出来呢。我还是手算算了

307
先算 307 mod 16 = 3 (个位)
算进位 (307 - 307 mod 16) / 16 = 19
19 大于 16,再次进位到 0x100 "1",16^1 位为 19 - 16 "3"

综合,得到 0x100*1+0x10*3+0x1*3 = 133(16) = 307(10)
然后再算 toBinary(0x133)

考虑一下 4 位最大达到 8 + 4 + 2 + 1 = 15,完全不够,所以 drakeet 之前教的速算... 不得不说对这个没用
那么就继续往下推,下一个 "8 4 2 1" 是 reverse . take 10 $ (2^) <$> [0..]
128,64,32,16

那好喽,就这么算呗,我自己曾经也造过这表
...
0x133
= 128 + 5
= 1000 0000
| 0101
= 1000 0101

完成了!

最后,再检验一下,我们可以反过来算一遍,比如随便拿一个二进制数,0101 1111 1110 这个数换成十进制是多少呢?你肯定不会再拿笔来算各位成于2的n次方的加和吧

0101 1111 1110 = 0x500 + 0xF0 + 0xE = 0x5FE
然后再去做就可以了,『并行化』乘除法计算

那么就是这样,不过我觉得就是个口算优化...

最后 drakeet 写了个 Java 的输出 int32 binary digit,每 4 位一个空格的程序,其实也可以用 C 写一个(其实嘛位运算很入门的,还不如他上面教的算法有趣...),我写

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
if (argc != 2) return -1;
int32_t n = atoi(argv[1]);
fprintf(stderr, "Got %i\n", n);

char digit;

// output binary
for (short int processing_bit = 0; processing_bit < 32; processing_bit++) {
digit = 0b1 & (n >> processing_bit); // little endian reverse

if (processing_bit %4 == 0 && processing_bit != 0) printf(" ");
printf("%d", digit);
}

printf("\n");
}
#C
[DuangSUSE@duangsuse]~% ./digit 256
Got 256
0000 0000 1000 0000 0000 0000 0000 0000
[DuangSUSE@duangsuse]~% ./digit 1
Got 1
1000 0000 0000 0000 0000 0000 0000 0000
duangsuse::Echo
#bin 然后为了证明我不比 drakeet 差,只是缺少拿来实践的时间, 我分析一下这篇文章《5分钟学会十进制转换成二进制的快速口算方法 & Java输出二进制的代码》,然后就睡觉。 当然,至于 Android 那一套,比如异步、Timer、MessageDriven、Android XML、Android Widgets、Resources、Android Gradle Build 集成、库打包、封装、Android Layouts、Views、Paint、Android Layout Animat…
啊今天早上想了一会,发现我还是错了,首先我要改一下输出二进制位的,虽然我知道真的是输出弄反了...(昨天就知道,因为我完全有能力在脑中把循环过程和位移动『可视化』要不然我也没法编程了)

// for atoi
#include <stdlib.h>
// for std io
// 就不用 C++ iostream 了
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

/*inline*/ bool get_i32_bitflag(int32_t x, int8_t bitoffset) {
const int32_t bitselector = 0x01000000; // little endian
return x << bitoffset & bitselector;
}

void print_bits(int32_t x, int8_t count) {
for (int i = 0; i < count; i++) {
if (i %4 ==0 && i !=0) printf(" ");

if (get_i32_bitflag(x, i)) printf("1");
else printf("0");
}
printf("\n");
}

int main(int argc, const char *argv[]) {
if (argc < 2) return -1;

int32_t n = (int32_t) atoi(argv[1]);
print_bits(n, 32);
return 0;
}

啊真垃圾居然改了我半天,虽然开始第一个程序也可以接受... 简单的位运算而已,还没用 lowbit 呢,我开始怀疑人生了

我准备用 Haskell 定义一下 fromBaseN, toBaseN 两个函数,使用两种方法

fromBaseN 没啥好说的,就是一位一位加而已

fromBaseN(16)(0xFF)
= digit('F') * 16^0 + digit('F') * 16^1
= 15*16 +15
= 255

toBaseN 有两种方法,我彻底想通了怎么递归

第一种方法是取余判定,一次输出两位的数字(本位的,进位的,判断是否还要再进位,然后剩下的 (* base) 递归)



第二种方法比较慢,就是判定是否大于等于 base(可以进位),算出本位的(如果可以进位,本位自然是 0xF),然后减法递归

简而言之,就是(为了方便暂时只支持 16 进制)

toBaseN' n x d
| x >= (n^d) = "F" : toBaseN' n (x - n^d) (succ d) — carry
| digitChar(x) : "h"
: []

如果要进位,则输出一个当前的最高位(F)然后递归下去
如果不用进位,则输出当前位然后加一个 "h"

当然还有一种方法,就是 drakeet 这篇文章教的,就是先算不能进位的余数,然后再去算进多少位,然后再去算进多少位... 好吧,这是笔算法

toHex(1024)
= 16 * 64
= (16^2) * 64
= 16*16 * 64
= (需要进位 64 = 16*4) 0x400

我都懒得实现了...

最后就是十六进制转换速算的问题,drakeet 教了大家 10->16 和快速 16->2, 2->16 什么的,当然其实原因就是『16 进制是 2 进制的简单形式』了(我从某本书看的,本频道之前也说过)

大概就是 2^4 = 16... 但是 log2(10) 不是整数不能直接对应,如果这么换算了可以节省手算时间了,至于电子机器怎么算和笔算无关


==
做完了我会开始写(GeekSpec 暂时放一下,我想写点代码)DJson (支持各种流哦,JSE 封装的,包括 Http 的)和 NaiveCat,当然我还是想先写个 Binary Stream Editor 的,,, 支持 byteorder 就可以了,因为 BinaryStreamIO 的状态的确有点多...

大概我会尝试把假期拖到明天中午,这样我就有一天半的时间(足足比别人多放一天半!别人周日早就去上学了,我可以拖到周一中午)

... 计划一直来都是『入不敷出』一样... 宿命吧,啥时候大学(迫真,专科,但是我不虚,因为我可以自学 self-teaching) #China #School #life 🤔🏫
duangsuse::Echo
#bin 然后为了证明我不比 drakeet 差,只是缺少拿来实践的时间, 我分析一下这篇文章《5分钟学会十进制转换成二进制的快速口算方法 & Java输出二进制的代码》,然后就睡觉。 当然,至于 Android 那一套,比如异步、Timer、MessageDriven、Android XML、Android Widgets、Resources、Android Gradle Build 集成、库打包、封装、Android Layouts、Views、Paint、Android Layout Animat…
对了,其实 #Android 应用和(我没写过,不过别人写过)iOS 应用其实都和 #Qt 应用很像的,如果想学会开发多平台的 #GUI 应用程序,不妨学好 Qt(
一些基础比如 Canvas (Qt 里是 QPainter 和 QGraphicsScene,Android 里也有 PorterDuff Compositor 和 View Canvas)不就会了么( 🖥
duangsuse::Echo
#bin 然后为了证明我不比 drakeet 差,只是缺少拿来实践的时间, 我分析一下这篇文章《5分钟学会十进制转换成二进制的快速口算方法 & Java输出二进制的代码》,然后就睡觉。 当然,至于 Android 那一套,比如异步、Timer、MessageDriven、Android XML、Android Widgets、Resources、Android Gradle Build 集成、库打包、封装、Android Layouts、Views、Paint、Android Layout Animat…
其中有一部分弄错了,我还以为 base16 只能表示 base2,base2 不能表示 base16,所以 16 -> 2 不能快速笔算,其实不是这样的(当然是可以这么算的,因为 16 = 4 * 2 * 2 呢,要不然不该是等号)

0x133
= toBinary(0x1) * 0b1000_0000
+ toBinary(0x3) * 0b1000
+ toBinary(0x3) * 0b1
= 0b0001_0000_0000
| 0b0000_0011_0000
| 0b0000_0000_0001
= 0b0001_0011_0001

如果还有错误的,请赐教 #fix 🐱
duangsuse::Echo
#bin 然后为了证明我不比 drakeet 差,只是缺少拿来实践的时间, 我分析一下这篇文章《5分钟学会十进制转换成二进制的快速口算方法 & Java输出二进制的代码》,然后就睡觉。 当然,至于 Android 那一套,比如异步、Timer、MessageDriven、Android XML、Android Widgets、Resources、Android Gradle Build 集成、库打包、封装、Android Layouts、Views、Paint、Android Layout Animat…
最后一句(我懒得再看 drakeet 的博客和文章什么的了,怕又引起撕逼,虽然我对技术还是很客气的... 而且现在我不虚,除了要和我谈 Monad 和范畴论图论线性代数什么的):
我才知道 drakeet 使用的排序算法是从大学的时候改的... 而且他还学过 Objc 和 iOS 开发...

https://blog.csdn.net/drakeet/article/details/12948029 👈 here, 《还是用csdn吧》

那么我这周最后谈一下这个博文最后提的问题,太久流于一个话题对我来说也不好。

我发现,其实酷安开发者们大学生也不少。by_syk 应该也是大学生吧

NSNumber *temp = [[NSNumber alloc] init];

//「从小到大」排序
for (NSInteger i = 0; i < aHundredArray.count - 1; i++) {
for (NSInteger j = i+1; j > aHundredArray.count; j++) {

if (aHundredArray[j] < aHundredArray[j-1]) {
temp = aHundredArray[j-1];
aHundredArray[j-1] = aHundredArray[j];
aHundredArray[j] = temp;
}
}
}
---------------------
作者:drakeet

我们用伪代码描述一下,反正我们不再乎是 Objc、Swift 还是 C++ 是吧?因为交换排序本来就应该是任何正常编程语言都能写的,Haskell 靠 forM_, (!!) 都能写(或许吧)

var ary[n]
predicate x y = not $ x `lessThan` y

for i in ary.indicesWithoutLast |>
local suc_i = i +1 — next item index
if (ary[i] `predicate` ary[suc_i]) swap(ary, i, suc_i)

怎么样,好看吧?这是个『不能使用』的交换排序算法,交换比较谓词函数为 (not · lessThan),换句话说,我们认为列表应该是 [a(<b), b (<c), c] 才对,否则就交换索引致使它成那样。

那么不对在哪里?假设我们有一个列表

[1, 3, 4] 排序结果显然是正确的,因为它不需要消除任何逆序对
[4, 1, 3] 在 i = 0 的时候,我们消除了一个逆序对 [4, 1][1, 4],然后 i = 1 结束循环时 [4, 3] 也被消除,得到有序列表

那么这个算法(我写的,不是原算法...)其实就是简单交换排序... 是没问题的(迫真,其实有问题... 比如 [4, 1, 3, 2] 就不能排序,因为它不足以把 2 交换到顶部,至于数据模式,就是 [d, a, b, c], a > b, a > c, d > a, 算法输出只能是 [a, b, c, d]... 好吧我输了,我这么抽象的时候找不出不能排序的... 但我觉得不对,肯定有无法交换到『前面』的模式的)

那么问题来了,到底为啥一半有序一半无序?因为我开始看错了...

for (NSInteger i = 0; i < aHundredArray.count - 1; i++)
for (NSInteger j = i+1; j > aHundredArray.count; j++)

什么魔性循环... 比如对于输入 [4, 3, 2, 1], for
count = 4
i = 0
j = 1 — j 不可能 greaterThan count,因为所有 i 循环中的 j (aka. succ i) 在 range bound (0:(count-1)-1+1) 内,(count - 1) 不可能 greaterThan countj++ 为死代码, 第二个循环不存在,, 看来我上面的是对的
swap([4,3,2,1], 0, 1)
i = 1
j = 2
swap([3,4,2,1], 1, 2)
i = 3
j = 4
swap([3,2,4,1], 3, 4)
(endfor)
result = [3, 2, 1, 4]

这就是所谓的『排了一半』,我们注意到 3 和 2 是逆序的,因为我们在交换 &2 和 &1 的时候没有考虑到前面有个 3 打破了期望的偏序关系(只知 3 > 2 不知 3 > 1,何况知道手也短无事可做)。

然后你们看到了,后来 drakeet 也在 LayoutFormatter 里觉悟了原来交换步长只有 1 啊!逆序对只是个 pair,更大的逆序是无法靠交换相邻项消除的,所以用了一个 for (i = 0; i < j - 1; i++), 完美