duangsuse::Echo
致命: 每次工程都会花很多时间,每次时间都不够
其实是思路不清晰.... 熟练度不够
首先我的方式就不对,Ruby 里面没有
考虑一下 《深入理解 Java 虚拟机》 里的一个例子,使用了二进制处理、字节码处理、类加载器技术
包含下面五个类
—
1. public final class CodeRunner
2. class HotSwapClassLoader extends ClassLoader
3. static class ByteUtils
4. class ClassModifier
5. public static final HackSystem
它要加载一个类文件的字节数组,修改替换其中常量池里的 UTF String 内容,涉及读取/存储截断指定字节长度 int32、读取字符串、序列化字符串等操作,可是却不清楚到底该怎么写?
... 需要多加练习。
首先我的方式就不对,Ruby 里面没有
inline def,这种『递归下降』是错误的好的程序会反映出它所处理数据的结构想想看是真理啊,为什么这种简单的数据结构,会需要递归呢?
考虑一下 《深入理解 Java 虚拟机》 里的一个例子,使用了二进制处理、字节码处理、类加载器技术
包含下面五个类
—
1. public final class CodeRunner
2. class HotSwapClassLoader extends ClassLoader
3. static class ByteUtils
4. class ClassModifier
5. public static final HackSystem
它要加载一个类文件的字节数组,修改替换其中常量池里的 UTF String 内容,涉及读取/存储截断指定字节长度 int32、读取字符串、序列化字符串等操作,可是却不清楚到底该怎么写?
... 需要多加练习。
duangsuse::Echo
解析器(其实就是扫描器)处理这种文法: 以行("\n")为单位进行逐行处理,因为 Telegram 客户端使用这种方式输出 — 状态 DEFAULT: 如果匹配 /^(.+), \[(\d{2})\.(\d{2})\.(\d{2}) (\d{2}):(\d{2})\]$/ 说明是一个新消息 进入状态 NEW_MESSAGE 否则,扫描此行,进入状态 SCAN_PUSH_LINE 状态 NEW_MESSAGE 假若此行以 "[" 开头 匹配 /^\[In reply to (.+)\]$/…
我们看看真正应该有几个状态:
首先是进入文件的状态:就是
如果匹配,则记录下当前 Message 的创建时间和频道,进入状态
到上个流程结束,应该已经创建了一个消息的『基础信息』
进入状态
匹配消息文本连接、内联文本链接、文本链接、Hashtags
为了调试方便,还必须保存当前行、当前位置、当前消息编号信息
总之,扫描器要保存这些状态:
首先是进入文件的状态:就是
EXPECT_MESSAGE
这时,如果不匹配 REGEX_NEW 则直接忽略该行如果匹配,则记录下当前 Message 的创建时间和频道,进入状态
SCAN_MESSAGE_HEADER
直到行不以 "[" 开头,检查特殊匹配,记录下当前消息类型和特殊内容到上个流程结束,应该已经创建了一个消息的『基础信息』
进入状态
SCAN_MESSAGE_BODY
直到行以 "]" 结束,检查新消息匹配,否则:匹配消息文本连接、内联文本链接、文本链接、Hashtags
为了调试方便,还必须保存当前行、当前位置、当前消息编号信息
总之,扫描器要保存这些状态:
var feeder伪代码:
var state, line, offset, message_no
var tg_current_message
var tg_name, tg_date // new message
var tg_type, tg_ext_ref, tg_body_type
var tg_body
<EXPECT_MESSAGE> {
until ((ln = feeder.next_line).match?(REGEX_NEW)) scan_warn "Ignore line #{ln}"
// 或者说 dropWhile(readline.not_match?(REGEX_NEW)) { |ln| scan_warn "Expecting new message , ignoring line #{ln}" }
name, d0,d1,d2, hh, mm = _ln.match(Message::REGEX_NEW).captures
tg_name = name; tg_date = Time.new(d2, d1, d0, hh, mm, 0)
begin SCAN_MESSAGE_HEADER
}
<SCAN_MESSAGE_HEADER> {
takeWhile(readline.start_with("[")) {
// check special matches, set tg_type, tg_ext_ref, tg_body_type
}
begin SCAN_MESSAGE_BODY
}
<SCAN_MESSAGE_BODY> {
takeUntil(readline.end_with("]")) {
// check label links, inline links, plain links, hashtags
// and read body text
// return created message
}
begin EXPECT_MESSAGE
}
duangsuse::Echo
我们看看真正应该有几个状态: 首先是进入文件的状态:就是 EXPECT_MESSAGE 这时,如果不匹配 REGEX_NEW 则直接忽略该行 如果匹配,则记录下当前 Message 的创建时间和频道,进入状态 SCAN_MESSAGE_HEADER 直到行不以 "[" 开头,检查特殊匹配,记录下当前消息类型和特殊内容 到上个流程结束,应该已经创建了一个消息的『基础信息』 进入状态 SCAN_MESSAGE_BODY 直到行以 "]" 结束,检查新消息匹配,否则: 匹配消息文本连接、内联文本链接、文本链接、Hashtags…
那么,完成这程序需要的一些信息: #Kotlin #tools #project
— Regex 正则表达式匹配 group
新消息的 Regex
要保存的状态
— Regex 正则表达式匹配 group
新消息的 Regex
/^(.+), \[(\d{2})\.(\d{2})\.(\d{2}) (\d{2}):(\d{2})\]$/
对应数据:data class MessageHead(val channel: DisplayName, val date: Date)
新消息,reply to/^\[In reply to (.+)\]$/数据:
data class RepliedMessageHead(val replies: DisplayName): MessageHead
新消息,forwarded/^\[Forwarded from (.+)\]$/数据:
data class ForwardedMessageHead(val origin: DisplayName): MessageHead
data class Message<T>(val messageType: MessageType, val messageExtRef: T, val messageBodyType: MessageBodyType, val messageBody: MessageBody, val links: MessageLinks, val hashTags: MessageHashTags)消息体,file
typealias FileMessage = Message<String>
typealias StickerMessage = Message<Character>
typealias NothingMessage = Message<Nothing>
/^\[ File : (.*) \]$/消息体,sticker
/^\[ (.) Sticker \]$/消息体,photo
/^\[ Photo \]$/消息体,album
/^\[ Album \]$/文本消息体,label links
/\((\w+)://(\S*)\)/文本消息体,plain links
/^(http|https):(\S+)/文本消息体,inline links
/(?![\(\)]).((http|https):(\S+))/文本消息体,hashtags
/(^|\s)#(?!#)((\S(?<![\(\)]))+)/—
要保存的状态
val feed: InputStream扫描算法:
var state: ScannerState
var line: Int, offset: Int, messageNo: Int, localLine: Int
var tgCurrentMessage
var tgName, tgDate
var tgType, tgExtRef, tgBodyType, tgBody
fun nextMessage(): Message<*> {
while (!feed.eof) {
try {
when (state) {
EXPECT_MESSAGE -> scanMessage()
SCAN_HEADER -> scanHeader()
SCAN_BODY -> scanBody()
}
} catch (r: MessageResult) { return r.result }
}
}
inline fun scanMessage() {
feeder.lineDropUntil(REGEX_NEW_MESSAGE::matches) { scanWarn("Ignoring line $it") }
// set tgName and tgDate
begin(SCAN_HEADER)
}
inline fun scanHeader() {
feeder.lineTakeWhile("["::startWith) {
// check special matches, set tgType, tgExtRef, tgBodyType
}
begin(SCAN_BODY)
}
inline fun scanBody() {
feeder.lineTakeUntil({it.endWith("]") && it.match(REGEX_NEW_MESSAGE)}) {
// check label links, inline links, plain links, hashtags
// and read body text
}
throw MessageResult(tgCurrentMessage)
}count.rb
4.4 KB
#Ruby 版的最后没有完成(
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (YuutaW 鱼塔)
为什么我认为 工欲善其事,必先利其器 是不完全正确的
工欲善其事,必先利其器 这句话大家耳熟能详,尤其是在各大社交软件(如某乎)的教程上,总有 【大神】 上来就给你塞上这句话,说先做好准备工作 balabalabala。我从一个业余开发者的 situation 出发,分享一下自身感受,以及为什么说 工欲善其事,必先利其器 是不完全正确的,而且会耽误时间。
比如,我最近在研究 Android 源代码的学习方案,如何开始学习 Android 源码,知乎一些大神给出了方案。某个回答的第一段就是讲某源码阅读软件比某 IDE 高到哪里去了 balabala,然后我查了一下这个被推荐的软件,价格 200+ USD / user。在这里,我又想到了另一个 situation。为了 P 图,不惜花钱去买某砖块公司的 XXShop 软体,时间和金钱都 “浪费” 在了这些被推荐的软体上。
这些软体之所以会被大神们推荐,肯定由于它们的确好用,大神也都是有经验的过来人,指导新手(写教程)的时候也一定不希望其他人由于软体不好用而走自己走过的弯路。这些我们都能理解,但是真的很必要在自己还没有着手学习核心内容的时候花大价钱,或者费劲地去 “利其器” 吗?
我这里不是讽刺那些付费软体,这不是本文的重点,因为付费只是 “利其器” 的一个门槛。我还回到学习 AOSP 这件事情上来说。在学习 AOSP 之前,真的要去花时间来准备学习的工具吗?这就像一个人,为了好好读书而花了几天时间来挑选中意的阅读器一样。
“利其器” 必然有用,但是如果把太多的金钱和时间都浪费在这些准备工作上,那么就是一种浪费。为何不先拿起记事本(极端地说),买本书,把这些准备的时间用在真正的学习上呢?等学好了,再准备,也不迟。
#观点
工欲善其事,必先利其器 这句话大家耳熟能详,尤其是在各大社交软件(如某乎)的教程上,总有 【大神】 上来就给你塞上这句话,说先做好准备工作 balabalabala。我从一个业余开发者的 situation 出发,分享一下自身感受,以及为什么说 工欲善其事,必先利其器 是不完全正确的,而且会耽误时间。
比如,我最近在研究 Android 源代码的学习方案,如何开始学习 Android 源码,知乎一些大神给出了方案。某个回答的第一段就是讲某源码阅读软件比某 IDE 高到哪里去了 balabala,然后我查了一下这个被推荐的软件,价格 200+ USD / user。在这里,我又想到了另一个 situation。为了 P 图,不惜花钱去买某砖块公司的 XXShop 软体,时间和金钱都 “浪费” 在了这些被推荐的软体上。
这些软体之所以会被大神们推荐,肯定由于它们的确好用,大神也都是有经验的过来人,指导新手(写教程)的时候也一定不希望其他人由于软体不好用而走自己走过的弯路。这些我们都能理解,但是真的很必要在自己还没有着手学习核心内容的时候花大价钱,或者费劲地去 “利其器” 吗?
我这里不是讽刺那些付费软体,这不是本文的重点,因为付费只是 “利其器” 的一个门槛。我还回到学习 AOSP 这件事情上来说。在学习 AOSP 之前,真的要去花时间来准备学习的工具吗?这就像一个人,为了好好读书而花了几天时间来挑选中意的阅读器一样。
“利其器” 必然有用,但是如果把太多的金钱和时间都浪费在这些准备工作上,那么就是一种浪费。为何不先拿起记事本(极端地说),买本书,把这些准备的时间用在真正的学习上呢?等学好了,再准备,也不迟。
#观点
永久封存 | Yuuta 台 | 😷 #Pray4Wuhan
为什么我认为 工欲善其事,必先利其器 是不完全正确的 工欲善其事,必先利其器 这句话大家耳熟能详,尤其是在各大社交软件(如某乎)的教程上,总有 【大神】 上来就给你塞上这句话,说先做好准备工作 balabalabala。我从一个业余开发者的 situation 出发,分享一下自身感受,以及为什么说 工欲善其事,必先利其器 是不完全正确的,而且会耽误时间。 比如,我最近在研究 Android 源代码的学习方案,如何开始学习 Android 源码,知乎一些大神给出了方案。某个回答的第一段就是讲某源码阅读软件比某…
我觉得,就为 #GeekApk 造 #GeekSpec 这个例子来说,是正确的,至少我不用去做一些完全体力的工作了... 虽然 GeekApk 还有部分 JavaEE / Spring 的模型接口/子类实现什么的必须手写,逻辑也必须用 Kotlin,但自动化无必要的、模板化的部分重要性不言而喻。
后面同样基于 GeekSpec 的 Spectrum 自动化 HTTP API 客户端程序,更是肯定了这么做的价值 — 写出接口定义本来的样子,最大可能去压榨它潜藏的用途
#UNIX 哲学里也提到一句:程序员的时间比计算机的时间宝贵,所以如果可能,就要写会写程序的程序,让它替代程序员工作。
优先使用工具而不是拙劣的帮助来减轻编程任务的负担。工欲善其事,必先利其器。
后面同样基于 GeekSpec 的 Spectrum 自动化 HTTP API 客户端程序,更是肯定了这么做的价值 — 写出接口定义本来的样子,最大可能去压榨它潜藏的用途
#UNIX 哲学里也提到一句:程序员的时间比计算机的时间宝贵,所以如果可能,就要写会写程序的程序,让它替代程序员工作。
优先使用工具而不是拙劣的帮助来减轻编程任务的负担。工欲善其事,必先利其器。
Telegram
duangsuse::Echo
🤔 GeekSpec 对 GeekApk Spring 的工程有多大的辅助作用呢?自 Spec 文件写完之后,自动生成解决了 300 多行模板代码的编写任务,从写完 7:34 到完成任务合并主分支 8:08 只花费了半个小时左右,可谓是一瞬生成了(
永久封存 | Yuuta 台 | 😷 #Pray4Wuhan
为什么我认为 工欲善其事,必先利其器 是不完全正确的 工欲善其事,必先利其器 这句话大家耳熟能详,尤其是在各大社交软件(如某乎)的教程上,总有 【大神】 上来就给你塞上这句话,说先做好准备工作 balabalabala。我从一个业余开发者的 situation 出发,分享一下自身感受,以及为什么说 工欲善其事,必先利其器 是不完全正确的,而且会耽误时间。 比如,我最近在研究 Android 源代码的学习方案,如何开始学习 Android 源码,知乎一些大神给出了方案。某个回答的第一段就是讲某源码阅读软件比某…
#statement #IDEA #IDE QNMD,IDEA, CLion 不好?IDE 不能拿来阅读源码?笑话!JB 给你们做那么具有扩展性的 IDE 就泡汤了还被这一群软件工程娱乐界大佬在嫌弃
请问这些工具第一论的大佬,请问你拿 IDEA 调试过程序么?会不会连 IDEA 里默认 keybinding 怎么暂停目标程序、怎么 toggle breakpoint 都不知道?Ctrl - N, Ctrl - F, Ctrl - Q, Ctrl - Shift - I, Ctrl - B, Ctrl - Alt - B 这些做什么的都不知道?你到底了不了解 IDE?用没有用过 IDEA 的重构功能?还是和某些把 Kotlin CSharp C++ Rust 写成 Basic 的工程师一样,也把 IDEA 用成了功能不给你推荐你就不知道的『自动补全文本编辑器』?你说 IDEA 这种历经工程实践的 IDE 不能用来『阅读源码』,是怪 IDE、怪外部工具不好使还是怪人视野太窄?
有些人就是能把 Kotlin 写成 Haskell,再把 Haskell 写成 Agda,普通人只能把 Kotlin 写成 Java 11,差点的 Java 7 加点语法糖(比如 val/var、data class、type inference),但再看另外一些人还真会把 CSharp 给写成 Basic 的,好好的 OOP 被一群类都看不见的人折腾成妥妥的过程式,别说泛型多态了抽象封装都不会,结果自己菜成那可怜样反过来还骂 CSharp 连带 CLR 『性能低』,也不知道是 CSharp 性能低呢还是你能力低呢?
你说不用专有『大公司』的工具,不用 Sketch 这种工具不好画示意图啊,但是你看得见 Graphviz 项目和那么多用 dot 画的图示么?知道多少计算机科学界论文在用 TeX 排版么?无视那么多东西自觉得不能用什么的,反过来其实是自己看得太少。
请问这些工具第一论的大佬,请问你拿 IDEA 调试过程序么?会不会连 IDEA 里默认 keybinding 怎么暂停目标程序、怎么 toggle breakpoint 都不知道?Ctrl - N, Ctrl - F, Ctrl - Q, Ctrl - Shift - I, Ctrl - B, Ctrl - Alt - B 这些做什么的都不知道?你到底了不了解 IDE?用没有用过 IDEA 的重构功能?还是和某些把 Kotlin CSharp C++ Rust 写成 Basic 的工程师一样,也把 IDEA 用成了功能不给你推荐你就不知道的『自动补全文本编辑器』?你说 IDEA 这种历经工程实践的 IDE 不能用来『阅读源码』,是怪 IDE、怪外部工具不好使还是怪人视野太窄?
有些人就是能把 Kotlin 写成 Haskell,再把 Haskell 写成 Agda,普通人只能把 Kotlin 写成 Java 11,差点的 Java 7 加点语法糖(比如 val/var、data class、type inference),但再看另外一些人还真会把 CSharp 给写成 Basic 的,好好的 OOP 被一群类都看不见的人折腾成妥妥的过程式,别说泛型多态了抽象封装都不会,结果自己菜成那可怜样反过来还骂 CSharp 连带 CLR 『性能低』,也不知道是 CSharp 性能低呢还是你能力低呢?
你说不用专有『大公司』的工具,不用 Sketch 这种工具不好画示意图啊,但是你看得见 Graphviz 项目和那么多用 dot 画的图示么?知道多少计算机科学界论文在用 TeX 排版么?无视那么多东西自觉得不能用什么的,反过来其实是自己看得太少。
把自己限制于一种语言的程序员会经常错过其他地方提供的重要机会,这样的程序员绝对不会被他们的老板或客户看成是专业领域中的专家。
— Oliver Sturm
所以今后好好看看啥叫真正的『程序设计』,就是不论你要解决什么问题,哪怕是给数控机床、PLC、树莓派、串口机去编程还是解决超算集群的编程问题,并行计算、实时计算、机器学习、信号处理、高精度科学计算,你都能看到你工作目标工作平台的全貌,解决方案都会出现在你的脑子里,并且能被快速高效地实现出来,而不是看到一点就自以为完美无可匹敌了。Cnblogs
你觉得 .NET 性能低,可能只是因为你的能力低 - Conmajia - 博客园
by Conmajia ⚠️ 由于安全设置,本文互动查询功能已失效 本文赞助者: ◎梦想起航 ◎ tzhang Tim 李敏 倾听 metoer 破除现代迷信,人人有责。.NET的源码点这里 Fork 奇了个怪 .NET作为开发平台来说,不可否认是优雅的、高效的。可是有些人就是看不到它极高的开发效率,极
duangsuse::Echo
#statement #IDEA #IDE QNMD,IDEA, CLion 不好?IDE 不能拿来阅读源码?笑话!JB 给你们做那么具有扩展性的 IDE 就泡汤了还被这一群软件工程娱乐界大佬在嫌弃 请问这些工具第一论的大佬,请问你拿 IDEA 调试过程序么?会不会连 IDEA 里默认 keybinding 怎么暂停目标程序、怎么 toggle breakpoint 都不知道?Ctrl - N, Ctrl - F, Ctrl - Q, Ctrl - Shift - I, Ctrl - B, Ctrl -…
This media is not supported in your browser
VIEW IN TELEGRAM
#Math 再去看一下更新喽?(高中数学爱好者的说?可是我因为原来基础的原因不是特别喜欢数学
Forwarded from Math notes | 数学笔记 (Ying Kanyang)
笔记将于今日更新