Damus与Nostr去中心化网络

Damus是什么

这几天Damus可以说是火遍全网——又一个来挑战Twitter的社交应用,不过与Twitter不同的是——Damus是一个去中心化的社交应用,所有消息采用了端到端加密。当然也因此在上架第二天就因违反中国相关法律法规下架了。

在Damus的官网上是这样介绍的:

  1. 完全由用户控制:基于开放的网络协议,没有那个平台可以禁止或者审查,用户可以完全控制自己的数据和言论。
  2. 加密:端到端加密的私人消息。
  3. 无需注册:创建账号无需手机号、Email或者姓名。
  4. 无需服务器:消息通过去中心化的中继进行分发.
  5. 可编程:轻松集成机器人,帮助生活或者业务自动化。
  6. 挣钱:可以给朋友的帖子打赏或者或者收集中本聪币。

Damus App可以说和Twitter是十分相似了,不过这个版本看起来制作还是显得有些粗糙。另外功能方面也不是很完善,比如发帖之后不能删除、点赞或者转推之后不可撤销、图片需要转成链接才能发布等等。

在Twitter上一眼望去都是大量的神秘代码——都是各自的公钥,在Damus上搜索这个公钥,你就可以Follow这个人。…

新冠——躲不过的终究还是来了

家人一个接一个先后感染了,我想着怎么还没轮到我,这不前天开始喉咙有点痒,昨天就发烧了。早上六点多从36.8开始,到八点多37.6,到下午3点就到了38.8,不到四点干到了39.1。不过虽然体温高,但精神倒是挺好的,食欲很不错,特别想吃辣的和甜的,于是点了外卖鸭翅尖、卤藕以及水果茶。但是这阶段阳的人太多了,外卖一个多小时才到,都到了晚饭的时间。一直到吃完外卖都没有吃药,但是吃完外卖之后觉得有点累了,于是躺下。躺下之后再也不想起来了,虽然我也不困,但就是想躺着……

这样一直躺到大概七点半,决定还是吃一颗对乙酰氨基酚,虽然高温让免疫系统杀死了病毒,但是我也得为我的脑细胞考虑下。半小时后体温降到了38.2,三小时后降到了37.6,但是太精神了,睡不着……

也不知道啥时候睡着的,三点多醒了一次,补点水,接着睡。早上不知道几点,迷迷糊糊的感觉全身都湿透了,但实在是太困了,就又睡了,这样迷迷糊糊的睡到早上六点多,量了下体温36.8,除了头还有点晕、喉咙略有点痒以外,几乎没啥其他不适了。…

IE终于要寿终正寝了

IE要寿终正寝的事说了好久好久了,这次似乎来真的了。官方发布消息说将在2023年2月14日永久禁用IE。真是选了个好日子。但是IE的图标仍然会在开始菜单和任务栏上保留,直到2023年6月的Windows强制更新,还是留有不少余地的。但是话又说回来,那些用windows的大企业多半也不会更新。

The retired, out-of-support Internet Explorer 11 desktop application is scheduled to be permanently disabled through a Microsoft Edge update on certain versions of Windows 10 on February 14, 2023. 

IE11 visual references, such as the IE11 icons on the Start Menu and taskbar, will be removed by the June

json.Unmarshal不区分大小写的坑

这个坑隐藏得很深,绝大多数情况下都不会碰到。在转换JSON的过程中,Unmarshal会按字段名来转换,碰到同名但大小写不一样的字段会当做同一字段处理。在官方文档中亦有说明(加粗部分):

To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don’t have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).

精确匹配最好,但是也接受大小写不敏感的匹配。只能说“包容性”太好了,但我认为这并不是一个好的设计。…

Tags:

用ChatGPT写了段无法通过编译的Go代码

这几天ChatGPT突然之间火得一塌糊涂。这个AI能够写小说、剧本、散文,回答各种问题,当然它肯定也能写代码,还能扮演Linux虚拟机来执行各种命令、编译代码。由于它过于强大,有人用它来回答stackoverflow上的各种问题,导致官方采取临时措施,把这个AI给禁止了。不得不说,它回答这些问题比google要好用多了。

我也折腾了一个账号,上去试了试。作为程序员,我让ChatGPT用Go写了段快速排序的代码,总体看起来还是很不错的:

func quickSort(arr []int) []int {
  // base case: if the length of the array is 0 or 1, it is already sorted
  if len(arr) < 2 {
    return arr
  }

  // choose the pivot element as the middle element of the array
  pivot := arr[len(arr)

Go指南练习11-Web爬虫

这个是A Tour of Go这个教程里面的最后一个练习,如下:

在这个练习中,我们将会使用 Go 的并发特性来并行化一个 Web 爬虫。

修改 Crawl 函数来并行地抓取 URL,并且保证不重复。

提示:你可以用一个 map 来缓存已经获取的 URL,但是要注意 map 本身并不是并发安全的!

原题代码模板如下:

package main

import (
	"fmt"
)

type Fetcher interface {
	// Fetch 返回 URL 的 body 内容,并且将在这个页面上找到的 URL 放到一个 slice 中。
	Fetch(url string) (body string, urls []string, err error)
}

// Crawl 使用 fetcher 从某个 URL 开始递归的爬取页面,直到达到最大深度。
func Crawl(url string, depth int, fetcher Fetcher) {
	// TODO: 并行的抓取 URL。
Tags:

Go指南练习10-等价二叉查找树

这个是A Tour of Go这个教程里面的第十个练习,原题如下:

不同二叉树的叶节点上可以保存相同的值序列。例如,以下两个二叉树都保存了序列 `1,1,2,3,5,8,13`。

在大多数语言中,检查两个二叉树是否保存了相同序列的函数都相当复杂。 我们将使用 Go 的并发和信道来编写一个简单的解法。

本例使用了 tree 包,它定义了类型:

type Tree struct {
    Left  *Tree
    Value int
    Right *Tree
}

1. 实现 Walk 函数。

2. 测试 Walk 函数。

函数 tree.New(k) 用于构造一个随机结构的已排序二叉查找树,它保存了值 k2k3k, …, 10k

创建一个新的信道 ch 并且对其进行步进:

go Walk(tree.New(1),
Tags:

Go指南练习9-图像

这个是A Tour of Go这个教程里面的第九个练习,原题如下:

还记得之前编写的图片生成器 吗?我们再来编写另外一个,不过这次它将会返回一个 image.Image 的实现而非一个数据切片。

定义你自己的 Image 类型,实现必要的方法并调用 pic.ShowImage

Bounds 应当返回一个 image.Rectangle ,例如 image.Rect(0, 0, w, h)

ColorModel 应当返回 color.RGBAModel

At 应当返回一个颜色。上一个图片生成器的值 v 对应于此次的 color.RGBA{v, v, 255, 255}

原题模板代码如下:

package main

import "golang.org/x/tour/pic"
Tags:

Go指南练习8-rot13Reader

这个是A Tour of Go这个教程里面的第八个练习,原题如下:

有种常见的模式是一个 io.Reader 包装另一个 io.Reader,然后通过某种方式修改其数据流。

例如,gzip.NewReader 函数接受一个 io.Reader(已压缩的数据流)并返回一个同样实现了 io.Reader 的 *gzip.Reader(解压后的数据流)。

编写一个实现了 io.Reader 并从另一个 io.Reader 中读取数据的 rot13Reader,通过应用 rot13 代换密码对数据流进行修改。

rot13Reader 类型已经提供。实现 Read 方法以满足 io.Reader

原题模板代码如下:

package
Tags:

Go指南练习7-Reader

这个是A Tour of Go这个教程里面的第七个练习,原题如下:

实现一个 Reader 类型,它产生一个 ASCII 字符 'A' 的无限流。

原题代码模板如下:

package main

import (
	"golang.org/x/tour/reader"
)

type MyReader struct{}

// TODO: 给 MyReader 添加一个 Read([]byte) (int, error) 方法

func main() {
	reader.Validate(MyReader{})
}

这题其实就是要实现一个Read接口:

func (T) Read(b []byte) (n int, err error)

然后在这个接口里面一直返回b的长度,给b注入相应长度的A的ASCII码就好:

package main

import (
	"golang.org/x/tour/reader"
)

type MyReader
Tags: