duangsuse::Echo
721 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/bytemaster/fc_malloc #lowlevel #backend 才想起来 CAS 是 compare-and-swap 非阻塞并行同步 Atomic 操作的意思
The key to developing fast multi-threaded allocators is eliminating lock-contention and false sharing. Even simple atomic operations and spin-locks can destroy the performance of an allocation system. The real challenge is that the heap is a multi-producer, multi-consumer resource where all threads need to read and write the common memory pool.

With fc_malloc I borrowed design principles from the LMAX disruptor and assigned a dedicated thread for moving free blocks from all of the other threads to the shared pool. This makes all threads 'single producers' of free blocks and therefore it is possible to have a lock-free, wait-free per-thread free list. This also makes a single producer of 'free blocks' which means that blocks can be aquired with a single-producer, multiple consumer pattern.

When there is a need for more memory and existing free-lists are not sufficent, each thread maps its own range from the OS in 4 MB chunks. Allocating from this 'cache miss' is not much slower than allocating stack space and requires no contention. Requests for larger than 4MB are allocated direclty from the OS via mmap.
This media is not supported in your browser
VIEW IN TELEGRAM
马上就从 F29 升 F31 了,代码都没写,还有很多东西该学。
https://coolshell.cn/articles/3585.html
SOAP专家: 不知道,使用GET的行为 undefined.

程序员: 哼哼。那么,要是我把我的服务移到别的 endpoint上?我是否可以得到一个301错误?

SOAP专家: 不会的,SOAP不会返回HTTP的错误码。


嗯?HTTP 动词又使用 POST,不是 GET,好像你把信封放那,别人不是有时间了看一下回你,还是立刻就回复一样
就算 GET 有 body 和请求长度上限制算吧,可既然用了 POST,Status Code 不用又是什么意义?
如果只是把 HTTP 当成管道来用,为什么不抽象出一个底层的 SOAP-HTTPTUN 协议?

SOAP专家: RPC!对象序列化!你从哪得到的SOAP就是一堆RPC的这种印象?! SOAP是关于基于文档的消息传递啊,我的朋友。

我的天啊,现在还有人觉得序列化是很重要的东西?难道这不像小白觉得 JavaScript、Lua 和 Ruby 有本质上的区别一样可笑吗?序列化和数据本身无关,和表达格式有关!难道二进制读写器这类东西需要额外再写,不是很差劲的主意吗?

基于文档和 KV 有啥关系和不同???所谓的文档是什么?redis 的 geolocation, sorted set, bitmap, lru 算不算?


SOAP专家: 忘了我所说的吧。现在,让我们谈谈消息传递吧。其消息格式遵守XML Schema,我们把之称为新型的文件格式。

程序员: XML Schema?

SOAP专家: 哦,这是很不错的东西,未来的头等技术,你应该看一下。

程序员: (阅读 Schema 规格说明书). 上帝保佑我们!就算是亚历山大帝也搞不定它啊。

SOAP专家: 不必太担心。会有专门的工作为你来创建XML Schema。真的,这只不过就是工具上的事。


……当一个东西的复杂性需要工具来解决,那些复杂性就本不应该存在。
就像一些人谈编程,他们根本不知道自己写了半天 Java、C,自己写的是什么,更不可能知道 C 的前身是 BCPL、第一个广泛使用的高级语言 Fortran 是 John Backus 于 1957 设计的,更不可能知道自己在用的基础编程方法是『表述式』,结构化编程,是对过程的结构化描述,那时编程是用既有的数据、程序逻辑和语言提供的结构,组织自己的程序,事件、线程、异步,这些通通不特殊。

SOAP专家: 哦,我没有说过吗?WSDL. Web Services Description Language. 它让你指定你的数据类型,参数,操作名,传输绑定,以及endpoint URI,这样,所有的客户程序员就可以访问你的服务了。你应该看看。

其实我设计过一种『WSDL』,它的名字叫 GeekSpec,虽然那时我还很幼稚,我肯定我的设计思想是简单的。
getUserList(name_filter:string) -> array:user = /users
POST@createUser(name:string) = /users

程序员: (阅读WSDL 规格说明书)。我相信那个写下这个文章的人已经被枪杀了。其内部说明都不一致。而且,其用的是HTTP GET绑定,你不是和我说过, GET 是 undefined吗.

SOAP专家: 不必担心那个,没人会用那玩意。


没人会用的设计,会引发非常严重的问题。

总之,工具会帮你生成WSDL,而且在WDSL里会有Schema的。

WSDL 居然是一种『语言』?它是工具生成的?

SOAP专家: 就像是原来那样,只不过,你整个消息被 包装起来成一个元素,其和操作有一样的名字。现在操作名和消息成了一体了。

这就显示出它的不成熟,早产儿。


程序员: 让我总结一下,SOAP的定义是不变的,SOAP可以是任何东西,但就是简单,它不再意味着对象访问,就算是所有的工具都那样做。

SOAP专家: 基本上是对的,但是我们走得比你要远一些。我们不赞成SOAP缩写的含义。

程序员: 真的!那么SOAP是什么的缩写?

SOAP专家: 什么也不是,就是SOAP.
duangsuse::Echo
所以我们在能够区分 case 制造 Element Tree 之前,还需要一个 Map<string, [PlaygroundDefaults, PlaygroundFnGlobalId, PostprocessFn]> 其中 PostProcessFn 可以帮助一些与 #Kotlin Playground 对元素树的结构要求区别很大的 playground 完成兼容,比如修改 hidden text area 的 class 什么的。 #project type PlaygroundDefaults…
什么叫做『设计』呢?举个例子吧。就是上面这种情况,为什么我不用之前想的扩展配置结构:

Map<string, [PlaygroundDefaults, PlaygroundFnGlobalId, PostprocessFn]>

而换用更『不规范』的

Map<string, [ElementConfig, Operation<Element>]> 呢?

我们来看看它们是怎么被使用的,我们有一个钩子函数 function configureLiterateKotlin()。它会在为整个页面添加 show code button 之前对 LiterateKt Script 进行配置。

function configureLiterateKotlin() {

// 『更规范的方法』 [PlaygroundDefaults=Object, PlaygroundGlobalId=String, Postprocess=ElementConfig]

literateKtConfig.language["kotlin"] = [
{/**/},
"KotlinPlayground",
() => {},
];

首先我们就不该写 Postprocess——为什么?难道不应该和前面的 assignDOMAttribute 合并吗?能放在一起的为什么不放一起?能更加可配置的为什么还要用一个全局函数的名字,并且强求那个函数只有一个 (e_code:Element) 参数?
而且我们用了 RequireJS,模块化了 JavaScript 代码,这已经是很『出尘脱俗』的做法了,为什么在这种情况下不允许外部脚本复用 'dom' 这个 JavaScript module?为了兼容老一点的编程风格?

// 正常方法 [ElementConfig, Operation<Element>]

const { withAttribute } = require('dom');
literateKtConfig.language["kotlin"] = [withAttribute({/**/}), e => schedule("KotlinPlayground", e)];

}

type Operation<T> = Consumer<T>
这是我的编程风格,避免任何含糊和“自动类型转换”。
Gradle 实在是太过分了!
Steam 太令人振奋了!
艹,Qt MXE 交叉编译环境!
怎么可以这样!!!
[DuangSUSE@duangsuse]~% find . -print -perm a+x
这也太难用了吧! tldr!还有 bitflags,7 是 rwx,从 x 到 w 居然是 1 2 4!
怎么是这样!叫 '-' 有错吗?为什么都不让读???
for ln in $<.each_line do
next unless ln.start_with?('mv')
_mv, src, dst = ln.split
puts("mv #{dst} #{src}")
end
def bulkRename(re_src, pat_dst, fmt_dst)
re_dst = Regexp.new(pat_dst)
selected = Dir.glob(re_src)
for name in selected
newnam = name.gsub(re_dst, fmt_dst)
puts("mv #{name} #{newnam}")
File.rename(name, newnam)
end
end

case ARGV.size # Just br size is OK
when 0 then warn("Usage: #{$0} [select] re_dst fmt_dst")
when 1 then puts(Dir.glob($*[0]))
when 2 then bulkRename('*', $*[0], $*[1])
when 3 then bulkRename($*[0], $*[1], $*[2])
end
好久以前的 #Ruby
『再见了』
感动。
duangsuse::Echo
for ln in $<.each_line do next unless ln.start_with?('mv') _mv, src, dst = ln.split puts("mv #{dst} #{src}") end def bulkRename(re_src, pat_dst, fmt_dst) re_dst = Regexp.new(pat_dst) selected = Dir.glob(re_src) for name in selected newnam =…
for ln in $<.lines do
if ln.start_with?("mv"); next; end
_mv, src, dst = ln.split
puts("mv #{dst} ${src}")
end


def bulkRename(pat_glob, pat_src, fmt_dst)
names = Dir.glob(pat_glob)
for name in names do
newName = file.gsub(pat_src, fmt_dst)
puts("mv ${name} {newName}")
end
end

case ARGV.size
when 0 then warn("Usage #{$0} [select] pat_src [fmt_dst]")
when 1 then puts(Dir.glob(ARGV[0]))
when 2 then bulkRename("*", ARGV[0], ARGV[1])
when 3 then bulkRename(ARGV[0], ARGV[1], ARGV[2])
end
🌚?? 要重下???