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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
我之前还以为是黑科技虚拟机层面提供服务支持呢... 说起来我想的和实际的差别可能就是缓存而已,然而其实动态字节码生成已经是一个足够好的方法了。 #Java #JVM
#China #embedded http://www.zhaoxin.com/

🤔 其实国产的『芯片』也不是少数(比如龙芯 MIPS 和 Allwinner),实际对市场使用上有帮助的是少... 要知道和编译器一样,好的 CPU 和辣鸡的 CPU,无论性能、功耗、热功耗、处理特性上都有很大区别

说起来,至于处理器特性,比如 VMx、矩阵运算(SIMD)AVX, SSE、PCI、APIC、Hardware floating points、64 (lm, Long mode, x64 mode)、Hyper threading、某些算法的机器层面支持(比如 aes, sha, rng"random number generator")什么的

说起来我这样的辣鸡对于 CPU 最看的就是逻辑解释器(内核)数目和超线程(对 Intel 芯片来说)数目了
至于处理器平常实现时的多级流水线、数据代码缓存、哈佛架构、实际解释器实现、一个 sadd 指令需要几个时钟周期、支持哪种类型的内存、存储总线类型、使用哪种内存协议什么的我作为一个门外汉也不关心。

我只多看一眼“处理器频率”,好像能做到 2.0GHz, 28nm,很厉害了(超出我对国产芯片的想像...)。

对于智能手机和个人 PC 机来说,可能有些东西国产的高集成电路产品还无法满足吧... 中国的“芯片”的确要赶的还不少,然后我本人就不懂那些电子的东西( 🙈

话说,BLUG, 北京 Linux User Group,应该有几个是学校里有芯片科目的大佬..
想学这种高度集成电路解释器的... RISC-V 是一个开源的 ISA (指令集架构)
duangsuse::Echo
#China #embedded http://www.zhaoxin.com/ 🤔 其实国产的『芯片』也不是少数(比如龙芯 MIPS 和 Allwinner),实际对市场使用上有帮助的是少... 要知道和编译器一样,好的 CPU 和辣鸡的 CPU,无论性能、功耗、热功耗、处理特性上都有很大区别 说起来,至于处理器特性,比如 VMx、矩阵运算(SIMD)AVX, SSE、PCI、APIC、Hardware floating points、64 (lm, Long mode, x64 mode)、Hyper…
被很多人称为芯片的这一类东西,和编译原理、native 编译器工程、操作系统内核、高性能计算、系统编程从来都脱不开关系,尤其是编译器原理,CPU 就是使用集成电路实现的机器代码解释器,但是需要很多的麻烦...
永久封存 | Yuuta 台 | 😷 #Pray4Wuhan
https://blog.yuuta.moe/2019/05/19/create-wtg/
使用了新 Windows (大概自 Windows 7)的一些小工具

DIskPart
用于生成 VHD 虚拟硬盘
  create vdisk file=filename parent=parentVdisk

parent
指定的母盘将作为子盘的原型,之后在子盘上的操作将在母盘的基础上差分压缩(比如子盘只象征对于母盘的 文件新增、删除 修改集合)

DISM (Disk Image utilities)
用于写入镜像到 U 盘
  Dism /Get-ImageInfo /imagefile:C:\install.wim
Dism /Apply-Image /imagefile:C:\install.wim /index:<windowsIndex> /applydir:<VHDPart>
BCDBoot
用于向 U 盘写入 NTBoot 引导加载程序和配置默认启动为 V:
  bcdboot D:\Windows /s X: /f UEFI /l en-us
PowerCfg
  powercfg -h off
禁止系统进行休眠
===
ImDisk
用于生成虚拟内存盘
Forwarded from dnaugsuz
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (Yuuta | a.k.a. 鱼塔 🐟)
#sysadmin 说起来之前 #GeekApk 的 VPS 也是 Archlinux 装的...
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (加藤日向的大傻瓜加藤乃爱 | 折腾编译中 | 最喜欢妹妹了)
达成成就:在GCE上安装Arch神教
Forwarded from dnaugsuz
说到 Spam 自动分类,除开自然语言处理模式识别这种重量级算法,最好用的就是 Naive Bayes Classifier 了,不过这是一种机器学习算法,我自己也只是会 KNN 机器学习推荐系统而已...
https://zh.wikipedia.org/wiki/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%86%E7%B1%BB%E5%99%A8#%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB

反正说到机器学习和人工智能,没有一个是简单的,唉... 😢 #machl
Forwarded from dnaugsuz
数学不好的人碰到尤其是信号处理和机器学习、搞基一点的算法之类就会哭哭的 😭
还是 kNN 好啊,找算法实现大概不是一个困难的事情,难在自己实现这种算法
Forwarded from dnaugsuz
这里有个写的很好的人工神经网络入门《前馈全连接神经网络和函数逼近、时间序列预测、手写数字识别》
dnaugsuz
说到 Spam 自动分类,除开自然语言处理模式识别这种重量级算法,最好用的就是 Naive Bayes Classifier 了,不过这是一种机器学习算法,我自己也只是会 KNN 机器学习推荐系统而已... https://zh.wikipedia.org/wiki/%E6%9C%B4%E7%B4%A0%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%88%86%E7%B1%BB%E5%99%A8#%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB 反正说到机器学习和人…
不过,其实完全可以用自然语言处理分词算法再用字典树的说(因为用 HashSet 算法还是太慢了,即使是常量时间判断 has 也不行)

比如说,这个怎么就这么变态的字典里有一个磁:

duangsuse 于 2019 年悼念1989.6.4天anmen事件中死去被屠杀的学生

🌚 怎么就这么反华呢?

分词:

duangsuse(v) 于(p) 2019年(t) 悼念(v) 1989.6.4(m) 天(q) anmen(nx) 事件(n) 中(f) 死去(v) 被(p) 屠杀(v) 的(u) 学生(n)

如果分词后使用集合查询,复杂度是 O(n) * O(1) where n: 输入磁条数,比较慢
如果分词直接上字典树,虽然时间复杂度差一点,而且还是要对每个词条检查,但是性能可能会强一些(因为 hashCode 的 32 位空间很小的,这样 HashSet 判定复杂度会上升很多)
要是我们不仅仅要有设计图纸了,恐怕还得专门弄一个程序辅助建红石方块... 类似:不是有个 MCHDL 吗?
Forwarded from 开发者日报
在我的世界打造一台计算机有多难?复旦大神花了一年

【在《我的世界》里从零打造一台计算机有多难?复旦本科生大神花费了一年心血】一块小小的CPU里有多少个晶体管?几十亿个。单枪匹马造出一个CPU乃至完整的电脑需要多长时间?有位大牛在《我的世界》游戏里用实际行动回答了这个问题:可能要花费一年多。「分享自新浪科技
硬碰硬的东西,强调不如做到。
duangsuse::Echo
硬碰硬的东西,强调不如做到。
甚是,这些成天写利用一些高层抽象和用户直接交流应用程序的『高性能计算』大佬们,真应该问问他们会不会写链表和并行快速排序,知不知道啥叫 Reordering,啥叫 SIMD,啥叫并行算法

某些人连递归和尾递归优化都不知道怎么做,却靠着抄代码和自以为是而没有深究的『高端优化技巧』自以为有多么强大的能力,这是误会了,不应该是这样的。
说起来现在讲一个二进制的事情 #bin

首先说 #Java

Java 8 里有这些类型比较奇特:

byte short int long float double
char boolean

java.lang.Object
java.lang.Throwable
java.lang.Cloneable
java.lang.Compareable
java.lang.Number
java.lang.Enum
java.lang.Annotation

java.lang.CharSequence
java.lang.String
java.lang.Void

java.lang.Deprecated

java.lang.Iterable
java.util.Collection
java.util.RandomAccess
java.util.Iterator
java.util.Map
java.util.List
java.util.Set

别的都不看,我们看 primitive numbers
我们今天不谈 Java 1.5 引入的 Autoboxing, Autounboxing, etc,单单看 C-like 语言里这些数值类型的最大值和最小值

所谓的一个 number 呢,一般都是可以进行各种操作的对象,操作包含:加减乘除取余位运算什么的

不要看 java.lang.Number 的 abstract class 定义,没用(只有 coercion,转型的方法),因为 Java 是使用 primitive 方法实现 +-*/^ 等 operator 的

在 Java 里,这些操作都是使用 <i|l|f|d> <cmp|add|sub|mul|div|rem|neg|shl|shr|ushr|or|and|xor|2Type> 字节码指令实现的,byte 和 short 不直接受到支持

比如,你算 println(ary[row*ary.width+column]) 这里 aryint[]

将生成如下字节码,假设 ary 被放在本地表的第一位... 好吧,我应该标注这个是 static 方法(要不然第一位是隐式参数 this),为了保证准确性这代码的确是 javac 编译出来的,我只是截取并注释

import static java.lang.System.out;

class Main {
void printIndex(int[] ary, int width, int row, int column) { out.println(ary[row*width+column]$
}


getstatic Ljava/lang/System.out:Ljava/io/PrintStream;
aload_1 ; int[] ary
iload_3 ; row in (*) operation
iload_2 ; width
imul ; row * width
iload 4 ; column
iadd ; (row * width) + column
iaload ; subscript ary with x
invokevirtual Ljava/io/PrintStream.println:(I)V;
return

生成代码?看起来很复杂?其实面向 JVM 的编译器写起来很简单,考虑一下类型的问题和静态本地表长度,最大栈深度,然后后序遍历抽象语法树输出字节码指令流就可以了

那么这次讲什么?只是讲他们的长度。

打开 Hex editor 应该经常能看到一些东西『有符号』『无符号』『整型数』
就是一种整数 {Z} 啦 (signed)
对于 unsigned,就是 {N}

不过计算机不是数学,精度有限制,是靠二进制来存储的,二进制是一种状态序列(组合),每一位都有两种状态:0 或者 1。

0b00 : case 0
0b01 : case 1
0b10 : case 2
0b11 : case 3

二位的二进制可以存储四种状态:这很好,这意味着我们可以有 0-3 之间的整数
至于具体的『整型数据操作实现』比如比较(大、小、同一)、相加相减,都是由机器层面实现的,我们不需要操心。

如果我们要存储符号,可以留一个位的状态来存储『它是不是一个负数』这个状态

0b01: +1
0b11: -1

很多人说不是直接通过一个符号位来的,是通过补码,但其实补码就是符号位... 只不过是加上了按位取反而已, 一种编码细节
有符号数字的操作也可以让机器来实现(不然也没必要使用二进制了)

要取一个数字的 lowbit(没有符号位的部分)可以使用如下位运算(Ruby):

def lowbit(x); return (-x) & x; end
lowbit(1) == lowbit(-1)

C 里面可以写成宏定义或者 inline procedure, 因为我这里 inline 会出现链接符号找不到的愚蠢问题,所以干脆使用宏定义

#define lowbit(x) ((x) & (-(x)))

当然这和按位取反(inverse by bit)是不一样的

====

十六进制

16 进制是表示二进制的一种简单记法,它一般被用于表示二进制数值。

计算机科学里的数值和数学里的数的区别,主要是计算机科学的『机器数值』是有最大值最小值范围限制的(二进制 n 位,因为现代常用电子计算机基于二进制),而数学只是一种抽象定义,它没有位数的限制

== 对数函数

这里不是数学教程,所以只有使用没有定义。

-- 以 n 为底关于 n 的对数
log(n) x = k
where k: n^k == x

-- n 的 k 次幂
n ^ 0 = 1
n ^ k = n {* n} repeats for k-1 times

使用诸如:

满二叉树(对于非叶子节点,每一层都有两个子节点)第 n 层的节点个数: 2 ^ (n - 1) — 排除第一层根节点不符合二元增长律的
有 n 个节点的满二叉树的层数: log2 (n - 1) +1 — 排除第一个不符合增长率的节点,算出第二层和下面的,再加上第一个节点
duangsuse::Echo
说起来现在讲一个二进制的事情 #bin 首先说 #Java Java 8 里有这些类型比较奇特: byte short int long float double char boolean java.lang.Object java.lang.Throwable java.lang.Cloneable java.lang.Compareable java.lang.Number java.lang.Enum java.lang.Annotation java.lang.CharSequence …
== 十六进制和二进制

log2(16) = 4

我们这里算的是『序列』case 数目,不过我们知道,

2^4 = 16,也就是说,一位 2 case,重复 4 次就可以表示一位 16 case 的情况(或者说,4 位二进制有 16 个 case)

log2(10) 不是整数,所以无法直接将 10 进制和二进制对应,不过 log2(8) 也是整数 3,所以 3 位二进制可以对应一位 8 进制

下面 0x 后面跟随十六进制、0b 后面跟随二进制

所谓 16 个 case 是,四位二进制,按照 <> 里的位为 1 的情况,可以这么与 16 进制对应:

0b <+8> <+4> <+2> <+1>

{} 里的东西可以重复无数遍或者不出现,[] 里的东西是一些字符的区间,用于表示 {} 里重复的字符都在此区间里

0x {[0-9A-Z]}

0-9 A-F 一共是 16 个数字,10 通过 A 表示,11 通过 B 表示,...

因为一般都是这么表示的(简单的二进制加减法)

0xFF : 0b1111_1111
0xFE: 0b1111_1110

0xFE 换算为二进制,直接对每一位写对应的二进制

hexDigitToBinary(0xA) = 0b1010 — +8 +2 = 10
hexDigitToBinary(0xD) = 0b1101 — +8 +4 +1 = 13
hexDigitToBinary(0xE) = 0b1110
hexDigitToBinary(0xF) = 0b1111 — 15

换算回来等同(这本身就是一个双向映射关系)。

== 字节序(ByteOrder)

字节序是一个底层硬件实现的细节,一般分为大端字节序和小端字节序,二者可以互相转化,它是一种二进制数值表示的规格
一旦一个数值类型长过一字节(比如 Java int,4 字节)就会出现字节序的问题

enum ByteOrd { LittleEndian = 0xfffe; BigEndian = 0xfeff }

我们所认为的『大位』(比如 13 里的十位)会被小端放在前面的字节里(所以它是从结束的字节起始一个数值),被大端放在后面的字节里

一般 x86 等 CISC 机器都会使用小端字序、ARM 等 RISC 机器会使用大端字序,大端字序也被称为网络序(因为在计算机网络上传递整型一般使用大端),小端也被称为本地序