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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
7. WiFi (/ˈwaɪfaɪ/, 念『歪wai1』『负爱fu4ai4』🤣) 是啥 WiFi 无线抱̶枕̶保真技术啊,但是这些东西,知识复杂性梯度太大了,没啥好讲的啊! 说点概念吧: — 它是一个无线电双工信息传输技术 — 98 年的技术,开始有专利,并且在 WLAN 技术里,一直无可替代,20 年了 可惜啊可惜无可替代(跑路) — 它的标准 AP 射频设备,IEEE 802.11 Wifi 目前有三个版本, WiFi4 — 802.11n — 72–600 Mbit/s Wi‑Fi5 — 802.11ac…
8. 是先有鸡还是先有蛋?

等等,别急,看完下面这行代码你就知道了!

"
🐔🥚
".match(/(.)/ug).sort() //=> Array [ "
🐔
", "
🥚
" ]


是先有鸡!

...等等,真的是先有鸡?

'🐔'.codePointAt() //=> 128020(U+1F414)
'🥚'.codePointAt() //=>129370(U+1F95A)

我们知道,Unicode 码表在扩展的时候,是不会考虑到什么先后顺序的!

比如它会颠倒因果顺序,这就很灵性了。

["👫", "👪"].sort() //=> Array [ "👪", "👫" ]

显然是先有 👱🏼‍♂️🍹👩🏼‍🦳 才有 👪 (装作很确定一样,嗯嗯)


好吧,那么进入正题:

先有蛋。

如果你说的蛋没有限定是鸡蛋的话 — 看起来就是这样的啊

最早的恐龙蛋,可以追溯到一亿多年前的白垩纪,而的驯化历史就晚太多了,4000 年前。
目前回家自学半年时间,使用PHP+MySQL初步搭建了一个简易新闻网站

我当时就喷了,自学半年才这个三脚猫水
平,也不知道这位同学工程到了个什么程度呢,是测试套件写了几万行呢还是自己设计了什么不得了的框架和去繁复的方案呢、还是写出了个不得了的 Web 应用呢,还是使用了最新的框架、最新的技术、最新的点子呢,比如,OAuth、RESTFul、灰盒测试、特性测试?还是说有部分是用 C++ 写的呢?还是说你在算法上达到了多么高的造诣?形式化验证程序逻辑?自己写了所有平台的客户端?我现在真的很佩服轮子哥的忍耐能力。要是我一上去就喷... 我这种没素质的人。

这种应用层的东西,我觉得即使是入门,PHP,即使对于高中生来讲,三个月时间足矣。而这位大学生,勉强搭建这种简易新闻(没错,它的身份验证可以瞎做、访问控制可以少做、而信息保密性几乎不需要考虑,其他信息安全侧面交给框架和运维吧,打包部署不是我的事情,是框架的事情,监控管理有运维工具呢)网站都花了半年左右的时间,我不知道这位是学到了什么程度。

我自学有两年了(实际上很长一段时间以来,都是『业余时间』,总的来说四舍五入也就一年而已),今年三月,这是第三年,我觉得好的学习者只应该学习,他们不应该去强调某种『学习方法』『学习技巧』『捷径』让自己分心,他们不应该这么功利地去学习,这是短视的。

本苏当年在酷安的时候,利用 AIDE 的交互式教程,虽然我连子类型是啥都不知道,也实现了一些简单的 Android 应用(虽然很多连个列表视图都没有,第一个我只花了三四天的时间过了一遍教程,然后就写出了一个使用 android.util.Base64 的前端应用),一个大学生,写 Web 时代的『后端/全栈』应用,就难到需要半年时间完成?


真正能达到对计算机科学,交叉了那么多知识系统、那么多学科,把那么多领域都融会贯通程度的人,都很难想象他们平时会去追求什么『技巧』什么『捷径』

除了死干,还是死干,除了死磕死背还是死背,坚持那么多个月、那么多年,把十几本、几十本书翻来覆去看不知多少遍,把各种优质工程不断拿来剖析重写,不断写博文、看博文、看论文、写论文,技术都是一天一天积累来的,不费力气想靠着一点肤浅的理解吃饭,吃一阵子可以,能这么滴水不入地在这个领域干一辈子?那是中国计算机工程的悲哀。

技术就是积累来的,每个人的智商总是差异不大,那就看谁更能积累深刻了,一天天的努力,最后能积累起来,一天比一天多会一个知识点、一周比一周多了解一个问题、一个月多涉足一个领域,最后可以达到融会贯通。

拥有奶酪,就拥有幸福;
如果你不改变,就会被淘汰;
越早放弃旧的奶酪,你就会发现新的奶酪;
随着奶酪的变化而变化,并享受变化!

有捷径为什么你能走别人不能走,你比别人多条腿、多张嘴?


『教官,能不能给我们传授一下,您一招必胜的绝技呀。』

凭什么有这种绝技就只能你会别人不会。成绩都是练出来的,就看谁能在逼近极限的同时犯更少的错误,你过的每一个弯,都没有机会再来一次,你犯的每一个错,都会断送整场比赛,甚至你的一生。

竞技体育,成绩是练出来的,冠军是撞出来的。作为一个拉力车手,冲出赛道没有任何缓冲区域,旁边可能是墙是树,是水库,是悬崖。就看谁能在逼近极限的同时,犯更少的错误。你过得每一个弯都没有机会再来一次!你犯的每一个错,都会断送整场比赛。你所爱的事业和别的运动不一样,需要你的专业和冷静。

巴音布鲁克,1462道弯,109公里。
耍小聪明,赢得了100米,赢不了100公里。
你问我绝招,绝招只有两个字,奉献!
就是把你的全部,奉献给你所热爱的一切。
我每天在脑海里开20遍,5年,3万6千遍,
我能记住每一个弯道。

所要的就是这种精神 — 奉献

奉献到不知道自己在奉献,当奉献成为常态的时候,你才能成为一个真正的优秀的软件工程者,而不是仅仅一个『称职』的软件工程者。

== UPDATE: 上面的言过了,这位同学的追求和我的不一样,所以上面的,全当我胡说算了。

这位同学也就是想好好生活,对于这方面,老师、同学、家人想必说的也不少了,我也没什么经验,不能帮到任何一点。
所以呢,只要能看清自己在技术上处在哪种层次,我根本不会『看不起』这些人,因为他们只是在做自己喜欢做的事而已(我也一样),我完全可以无视他们的『职位』而只把他们当成自然人看待。emmmm 🌝
上面的文字只能代表我自己对以后几十年经验的老程的期待,因为热爱生活的人肯定学的更慢一些,这是非常正常的。

虽然我确实比较笨,但无端被人议论起智商问题还是有点恼火,我就回家自己搞搞技术,打算以此谋生而已,招谁惹谁了 ……
羽毛的小白板
极端 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

(没用到啥关系代数知识,一方面也是关系代数那点操作符不够,虽然可以自己造新含义...)
唉,看来我还是了解的不够仔细。
其实我也相当努力了... 可是,其实有些东西就是要花时间... 而且我现在还没有机会沾染计算机图形学和人工智能
duangsuse::Echo
😔 Sticker
所以 GeekApk v1b trivial 的不得了的权限验证和所谓高难度的分页,都是智障级别的.... 除了被不良工程的 GeekSpec、Spectrum,我不知道它还有什么可取之处... 只要我现在完成这个临时的版本,真该啥时候重写的。
This media is not supported in your browser
VIEW IN TELEGRAM
#DuangsuseSB 煞笔警告一次
duangsuse::Echo
#DuangsuseSB 煞笔警告一次
好吧,好吧,duangsuse 来恢复一下心情,顺便写今天最后一个代码:默写重写 @YuutaW 的 RandomPicture

完全默写,包括 Gradle 构建文件(除了 Vertx 的依赖关系 Coordinate 在外)
并且,不得使用 IDEA 等具有自动补齐功能的 IDE

== 首先,我们来玩个简单的文件排序游戏,因为 duangsuse 不是学算法的(我以后会学)所以不考虑算法层的东西,就快速排序吧(因为它不需要我花时间去记,皮一下哦)(反正怎么说我,交换、插入、选择排序里,我也只会快排、冒泡、简单选择,虽然 OI 基础里还有简单插入、希尔排序、堆排序)。

肯定要用 Kotlin 最好,Haskell?那玩意 IO 模块的 API 我还不是老熟,现在弄了又要花掉十几分钟时间。

首先,我们要这么定义我们的『顺序』(基于 Int 优先级):
优先级,0 为最高优先级,往后依次递减,排序时使用 greaterThan ([a|b],若 a greaterThan b,则交换顺序) 来比较

针对每个字符,使用求和函数归并出优先级:
[A-Z] 范围内,递减优先级(0..23)
[a-z] 范围内,递减优先级,比 [A-Z] 小(23..49)
[0-9] 范围内,比 [a-z] 小(49..59)
任意其他字符,不影响优先级(0)

首先我们定义快速排序函数:

fun <E> quickSort(compare: Comparator<E>)
= fun (items: List<E>, lhsStart: Int = 0, rhsEnd: Int = items.lastIndex) {
// recursion base: like [1] / [2]
if (items.size < 2) return items;

// select swap pivot
val pivot = items.size / 2
// recursion
val lhsSorted = quickSort(compare)(items[lhsStart..pivot], pivot, );
val rhsSorted = quickSort(compare)(items[pivot..rhsEnd], pivot, );

// exchange mybe?
if (compare(lhsSorted.last(), rhsSorted.first()) > 0) {
// lhs is greaterThan rhs, swap then
return rhsSorted + lhsSorted
} else { return lhsSorted + rhsSorted }
}

以上这个函数写了我差不多半个小时,但是没有成功,我始终忘记了应该怎么模拟调用栈来设计算法... 🤔
所以我索性直接抄了某本算法书上的算法,我说过我是本本主义者。

fun <E> List<E>.quickSort(cmp: Comparator<E>): List<E> {
if (this.size < 2) return listOf()
val pivot = this[this.size / 2]
val less = this.filter { cmp.compare(pivot, it) > 0 }
val more = this.filter { cmp.compare(pivot, it) < 0 }
return more.quickSort(cmp) + pivot + less.quickSort(cmp)
}

import java.text.Collator
val col = Collator.getInstance()
const val TEXT = "hello HELLO 810 114514 1919810 z ab cd dc"
TEXT.split(' ').quickSort(col)

[z, HELLO, dc, cd, ab, 1919810]


我开始居然忘记递归调用 quickSort 了... 最近思路有点崩溃,看不到数据的流动了。
然后居然又忘记了,基线条件,列表的大小必须得大于等于 2 才有顺序一说啊!
亏我还想画图分析来着... 回头发现自己连顺序是啥都忘记了
没有思路了... 大概是老了吧

我得恶补一下算法了... 我居然不知道,左边的必须全是比 pivot 小的元素、右边的全得是比 pivot 大的元素,才能交换啊!唉
可怜的、不是天才的 duangsuse,长得又不好看,emmmmm....

然后是 [A-Z] [a-z] [0-9] 的排序

class StringComparator: Comparator<String> {
override fun compare(r: String, l: String): Int = toLevel(r).compareTo(toLevel(l))
override fun equals(o: Any?) = o is StringComparator // Stateless comparator

companion object Helper {
fun toLevel(str: String) = str.fold(0, ::appendLevel)
private fun appendLevel(acc: Int, ch: Char) = acc + getCharLevel(ch)
fun getCharLevel(ch: Char): Int = when (ch) {
in 'A'..'Z' -> ch - 'A'
in 'a'..'z' -> ch - 'a' + 26
in '0'..'9' -> ch - '0' + ('a'-'0'+2)
else -> 0
}
}
}
}

且慢,那么,假若我们希望开头的字符优先级更高呢?
这就是我们用 fold 而不是 sum 的原因啊!

修改一下:

fun toLevel(str: String) = str.fold((0, str.size), ::appendLevel)
private fun appendLevel(acc: Int, chnk: (Char, Int)) = (acc + chnk.second * getCharLevel(chnk.first), chnk.second - 1)

:: 从第一个字符开始以字符串长度数,每个字符都递减,然后把当前字符的长度,乘当前字符的优先级

那么是测试时间了呢。
好了,我玩够了。


和画出 mindmap,给大家讲出『Vibrator 到 System Service』所有的知识点。

快快写完睡觉吧。
结果
TextSort.kt
2 KB
This media is not supported in your browser
VIEW IN TELEGRAM
https://github.com/duangsuse/RandomPicture 我必须得感谢自己,因为我使我自己发现了无计划死拖死缠的坏处和自己能力、记忆的有限... #life #tech #dev