Go漏洞管理

本文翻译自《Go Vulnerability Management》。

点此回到《Go安全》

概述

Go可以帮助开发人员检测、评估和解决有可能被攻击者利用的代码Bug或弱点。在幕后,Go团队运行一个管道来策划有关漏洞的报告,这些报告存储在Go漏洞数据库中。可以阅读和分析各种库和工具的这些报告,以了解特定用户项目可能受到的影响。此功能已集成到Go软件包发现站点和新的CLI工具govulcheck中。

该项目正在推进中,正在积极开发中。我们欢迎你的反馈,帮助我们改进!

注意:要报告Go项目中的漏洞,请参阅Go安全策略

架构

Go中的漏洞管理由以下高级部分组成:

资源

Go漏洞数据库

Go漏洞数据库包含来自许多现有来源的信息,此外还有Go包的维护人员直接向Go安全团队的报告。数据库中的每个条目都会被审查,以确保漏洞的描述、包和符号的信息以及版本的详细信息是准确的。

有关go漏洞数据库的更多信息,请参阅go.dev/security/vuln/database,在浏览器中查看数据库中的漏洞信息,请参阅pkg.go.dev/vuln

我们鼓励包的维护人员在自己的项目中提供有关漏洞的信息,并向我们发送如何减少该漏洞造成的影响的建议

Go漏洞检测

Go的漏洞检测旨在为Go用户提供一种低噪声、可靠的方式来了解可能影响其项目的已知漏洞。漏洞检测集成到Go的工具和服务中,包括一个新的命令行工具govulcheckGo包发现网站主流的编辑器,例如带有Go扩展的VS Code。

要开始使用govulcheck,请在项目中运行以下命令语句:

$ go install golang.org/x/vuln/cmd/govulncheck@latest
$ govulncheck ./...

要在编辑器中启用漏洞检测,请参阅编辑器集成漏洞检测插件页面中的说明。

Go CNA

Go安全团队是一个CVE编号机构(CVE Numbering Authority)。有关更多信息,请参阅go.dev/security/vuln/cna

反馈

我们希望你在以下方面做出贡献并帮助我们改进:

FAQ

如何报告Go项目中的漏洞?

通过电子邮件向[email protected]报告Go项目中的所有安全漏洞。有关我们流程的更多信息,请阅读Go的安全政策

如何将公共漏洞添加到Go漏洞数据库?

要将公共漏洞添加到Go漏洞数据库,请填写此表单

如果漏洞已经公开披露,或者存在于你维护的包中(并且你已准备好披露),则该漏洞被视为公开漏洞。该表单仅适用于不由Go团队维护的可导入的Go包中的公共漏洞(Go标准库、Go工具链和golang.org模块之外的任何包)。

该表单也可用于申请新的CVE ID。点击此处了解更多关于Go CVE编号机构的信息。

如何提议对漏洞进行编辑?

提议编辑Go漏洞数据库中的现有报告,请填写此处的表单

我如何报告问题或提供有关govulcheck的反馈?

Go问题跟踪器上提交你的问题或反馈。

我在另一个数据库中发现了此漏洞,为什么它不在Go漏洞数据库中?

由于各种原因,报告可能会被排除在Go漏洞数据库之外,包括相关漏洞不存在于Go包中,存在于可安装命令而非可导入包中,或者该漏洞被数据库中已存在的另一个漏洞所包含。你可以在此处了解更多关于Go Security团队排除报告的原因。如果你认为某个报告被错误地排除在vuln.gov之外,请告诉我们

为什么Go漏洞数据库不使用严重级别标签?

大多数漏洞报告格式使用严重性标签,如“LOW”、“MEDIUM”和“CRITICAL”,以指示不同漏洞造成的影响程度,并帮助开发人员确定安全问题的优先处理级别。然而,由于几个原因,Go避免使用此类标签。

漏洞的影响很少是普遍的,这意味着严重性指标往往具有欺骗性。例如,如果解析器用于解析用户提供的输入,并且可以被DoS攻击利用,那么解析器中的漏洞可能是一个严重的问题,但如果解析器只是用于分析本地配置文件,即使将严重性称为“低”也可能言过其实。

严重程度也必然是主观的。即使对于CVE程序也是如此,该程序假定了一个公式来分解漏洞的相关方面,如攻击向量、复杂性和可利用性。然而,所有这些都需要主观评价。

我们认为,对漏洞的良好描述比严重性指标更有用。一个好的描述可以分解什么是问题,如何触发问题,以及用户在确定对自己软件的影响时应该考虑什么。

如果你想与我们分享你对此主题的想法,请随时提交一个议题

使用IDE扫描Go依赖项的漏洞

本文翻译自《Vulnerability Scanning in IDE》。

点此回到《Go安全》

Go语言服务器集成的编辑器,例如装有Go扩展的VS Code,可以检测依赖项中的漏洞。

检测依赖关系中的漏洞有两种模式。两者都由Go漏洞数据库支持,并相互补充。

  • 基于导入的分析:在这种模式下,编辑器通过扫描工作区中导入的一组包来报告漏洞,并在go.mod文件中显示诊断结果。这很快,但如果你的代码导入了有漏洞的包,但并没有实际调用具有该漏洞的函数,则可能会误报。此模式可以通过“vulncheck”: “Imports”设置启用。
  • Govulncheck分析:这是基于gopls中嵌入的govulnchick命令行工具。这提供了一种低噪声、可靠的方法来确认代码是否真的调用了易受攻击的函数。由于此分析的计算成本可能很高,因此必须与基于导入的分析中的诊断报告相关的“Run govuncheck to verify”代码操作或使用go.mod文件上的“codelens.Run_govulcheck”代码操作手动触发。

切换Vulncheck (vulncheck.mp4)

这些功能在gopls v0.11.0或更新版本中可用。请在https://go.dev/s/vsc-vulncheck-feedback上分享你的反馈。

编辑器相关指导

VS Code

Go扩展提供了与gopls的集成。需要以下设置才能启用漏洞扫描功能:

"go.diagnostic.vulncheck": "Imports", // 默认启用基于导入的Govulncheck分析
"gopls": {
  "ui.codelenses": {
    "run_govulncheck": true  // 在go.mod文件里,鼠标移到依赖项上时显示"Run govulncheck"菜单选项
  }
}

Go Toggle Vulcheck”命令可用于打开和关闭当前工作空间的基于导入的分析。

Vim/NeoVim

使用coc.nvim插件时,以下设置将启用基于导入的分析。

{
    "codeLens.enable": true,
    "languageserver": {
        "go": {
            "command": "gopls",
            ...
            "initializationOptions": {
                "vulncheck": "Imports",
            }
        }
    }
}

注意事项和警告

  • 该扩展不扫描私有包,也不发送任何有关私有模块的信息。所有分析都是通过从Go漏洞数据库中提取已知有漏洞风险的模块的列表,然后在本地计算交集来完成的。
  • 基于导入的分析使用工作区(workspace)模块中的包列表,如果使用了go.work文件或replace/exclude指令,则该列表可能与你在go.mod文件中看到的不同。
  • 在修改代码或更新Go漏洞数据库后,govulcheck分析结果可能会变得过时。要手动使分析结果失效,请使用go.mod文件顶部显示的“Reset go.mod diagnostics”选项。否则,结果将在一小时后自动失效。
  • 这些功能目前不会报告标准库或工具链中的漏洞。我们仍在调查用户体验,了解在哪里显示这些发现比较合适,以及如何帮助用户处理这些问题。

_seq_no和_primary_term这两个字段在Elasticsearch里的作用是什么?

它们用来实现基于乐观锁的版本控制。

Elasticsearch跟踪上次操作的序列号(sequence number)和主项(primary term),以更改它存储的每个文档。通过GET API响应信息中的_seq_no和_primary_term字段返回序列号和主项。

_primary_term

在故障转移期间,每当不同的分片成为主分片时,primary term的值就会增加。这有助于解决重新联机的旧的主分片上发生的更改,与新的主分片上发生的更改的冲突问题,一般新的主分片会获胜。

这里我们要先理解Elasticsearch的高性能和高可用机制:一个索引的数据可以存储到多个分片上,以均衡负载,提升读写性能;而每个分片(主分片)又可以有多个副本(副分片),在主分片脱机后Elasticsearch可以快速把其中一个副分片推举为新的主分片,保障Elasticsearch集群的高可用性。

副分片的primary term只是主分片更改次数的计数器。

这些primary term是递增的,并且在主分片升级时会发生变化。它们作为集群状态的一部分被持久化,因此代表了集群所在的主分片的一种“版本号”或“年代(generation)”。

为了确保文档的旧版本不会覆盖新版本,对文档执行的每个操作都由对应更改的主分片分配一个序列号。

假设你的索引由5个主分片组成(在Elasticsearch 7之前是默认的)。索引(新增文档)和更新的请求是针对主分片执行的。如果你有多个主分片,Elasticsearch能够将传入请求(例如,巨大的批量插入文档的请求)并行化/分发到多个分片,以提高性能。

因此,_primary_term字段提供了关于执行或协调更改主分片(本例中为#1、#2、#3、#4或#5)的信息。

_seq_no

序列号在Elasticsearch 6.0.0中引入。

一旦我们对primary term进行了保护,我们就添加了一个简单的计数器,并开始向每个操作发出该计数器的序列号。因此,这些序列号使我们能够理解发生在主分片上的对索引的操作。

_version字段存储了一个序列号,用于统计文档更新的次数。_seq_no字段也是一个序列号,用于统计索引上发生的操作次数。因此,如果你创建第二个文档,你将看到该文档的_seq_no和第一个文档的_seq_no有所不同。

实例

创建多个文档:

POST test/_doc/_bulk
{"index": {}}
{"test": 1}
{"index": {}}
{"test": 2}
{"index": {}}
{"test": 3}

返回响应信息:

{
  "took" : 166,
  "errors" : false,
  "items" : [
    {
      "index" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "d2zbSW4BJvP7VWZfYMwQ",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "eGzbSW4BJvP7VWZfYMwQ",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 1,
        "_primary_term" : 1,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "eWzbSW4BJvP7VWZfYMwQ",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 2,
        "_primary_term" : 1,
        "status" : 201
      }
    }
  ]
}

正如你所看到的:

  • 对于所有文档,版本号_version为1;
  • 对于文档1,_seq_no为0(第一次索引操作);
  • 对于文档2,_seq_no为1(第二次索引操作);
  • 对于文档3,_seq_no为2(第三次索引操作)。

教程:使用VS Code Go插件查找和修复可能有安全风险的依赖项

本文翻译自《Tutorial: Find and fix vulnerable dependencies with VS Code Go》。

点此回到《Go安全》

目录

先决条件

如何使用VS Code Go扫描漏洞

其他资源

你可以使用Visual Studio Code编辑器的Go插件直接在编辑器中扫描代码中的漏洞。

注意:有关以下图像中包含的漏洞修复相关的教程,请参阅govulcheck教程

先决条件

  • Go 1.18或更高版本。Govulncheck旨在与Go 1.18及以后的版本配合使用。有关安装说明,请参阅安装Go。我们建议你使用最新版本的Go来学习本教程。
  • VS Code编辑器,更新到最新版本。请在此处下载。你也可以使用Vim(有关详细信息,请参阅此处),但本教程的重点是VS Code Go插件。
  • VS Code Go插件,可以在这里下载。
  • VS Code编辑器特定设置更改。你需要根据这些规范修改VS Code的设置,然后才能复制下文的代码示例,运行后得到相应的结果。

如何使用VS Code Go扫描漏洞

第一步,运行“Go: Toggle Vulncheck”

Toggle Vulcheck命令显示在你的模块中列出的所有依赖项的漏洞分析。要使用此命令,请打开IDE中的命令面板(在Linux/Windows上的快捷键为Ctrl+Shift+P,在Mac OS上的快捷键为Cmd+Shift+P),然后运行“Go:Thoggle Vulcheck”。在Go.mod文件中,你将看到代码中可能会被直接和间接攻击的依赖项的诊断。

注意:要在自己的编辑器上重现本教程,请将下面的代码复制到main.go文件中。

// 这个程序从命令行获取一个或多个“语言标签(language tag)”参数,然后解析它们
package main

import (
  "fmt"
  "os"

  "golang.org/x/text/language"
)

func main() {
  for _, arg := range os.Args[1:] {
    tag, err := language.Parse(arg)
    if err != nil {
      fmt.Printf("%s: error: %v\n", arg, err)
    } else if tag == language.Und {
      fmt.Printf("%s: undefined\n", arg)
    } else {
      fmt.Printf("%s: tag %s\n", arg, tag)
    }
  }
}

然后,确保程序的go.mod文件的内容如下所示:

module module1

go 1.18

require golang.org/x/text v0.3.5

运行go mod tidy命令以确保你的go.sum文件已更新。

第二步,运行govulcheck。

使用代码操作(code action)运行govulcheck可以让你专注于代码中实际调用的依赖项。VS Code中的代码操作由灯泡图标标记;将鼠标悬停在相关依赖项上以查看有关该漏洞的信息,然后选择“快速修复(Quick Fix)”以显示选项菜单。再选择“运行govulcheck进行验证(run govulncheck to verify)”。这将在你的终端中返回相关的govulceck输出。

第三步,将鼠标悬停在go.mod文件中列出的依赖项上。

将鼠标悬停在go.mod文件中的依赖项上,也可以找到关于此依赖项的govulcheck输出。为了快速查看依赖项相关信息,这种方式甚至比使用代码操作更高效。

第四步,把你的依赖项升级到修复后的版本。

代码操作还可以用于快速升级到修复漏洞后的依赖项的版本。通过在代码操作的下拉菜单中选择“升级”选项来完成此操作。

其他资源

  • 有关IDE中漏洞扫描的详细信息,请参阅此页。特别是“注意和警告”小节讨论了漏洞扫描可能比上例中更复杂的特殊情况。
  • Go漏洞数据库包含来自许多现有源代码的信息,此外还有Go包维护人员向Go安全团队的直接报告。
  • 请参阅Go漏洞管理页面,该页面提供了Go用于检测、报告和管理漏洞的体系结构的高级视图。

字符集,编码、显码和存码,ANSI,GB2312,GBK,Unicode,UTF-8名词解释

ANSI是美国国家标准协会,系统预设的标准文字储存格式。

简体中文编码GB2312,实际上它是ANSI的一个代码页936

一种代码页就是一种字符集。

例如代码页936(Codepage 936)是Microsoft的简体中文字符集标准,是东亚语文的四种双字节字符集(DBCS)之一。其最初版本和GB 2312一模一样,但在Windows 95时扩展成GBK。现时中国大陆强制要求所有软件皆要支持GB 18030(Microsoft称之为代码页54936)。

根据微软资料,GBK(汉字内码扩展规范)是对GB2312-80的扩展,也就是CP936字码表(Code Page 936)的扩展(之前CP936和GB 2312-80一模一样),最早实现于Windows 95简体中文版。虽然GBK收录GB 13000.1-93的全部字符,但GBK也是一种编码方式并向下兼容GB2312;而GB 13000.1-93等同于Unicode 1.1是一种字符集,它的几种编码方式如UTF8、UTF16LE等,与GBK完全不兼容。

UTF-8是一种通用的字符集编码格式,这是为传输而设计的编码,2进制,以8位为一个单元对Unicode进行编码。

在UTF-8里,英文字符的编码仍然跟ASCII编码一样,因此原先的函数库可以继续使用。而中文的编码范围在0080-07FF之间,因此是2个字节表示(但这两个字节和GB编码的两个字节是不同的),用专门的Unicode处理程序可以对UTF-8编码进行处理。”

GBK、GB2312是ANSI字符集的扩展字符集,UTF-8是Unicode字符集的一种编码方案,在编码层面,它们对ASCII字符的编码是一样的,但是对中文字符的编码就不一样了、不兼容了!

Unicode狭义来说只是一个字符集,而UTF-8是其一种编码规则(编码方式),Unicode有多种编码方式,还有ucs-2(utf-16)等。

字符集在计算机系统里的实现技术,分为存码技术和显码技术,编码规则属于存码技术,字体属于显码技术。一个字符可以有多种编码方式,例如GBK、UTF-8等,编码方式告诉计算机如何用二进制编码(此处“编码”是动词)和存储一个字符;一个字符也可以有多种显示方式,例如使用不同的字体,将在屏幕上显示不同的字形。一种字体就是一种显码。

参考

https://blog.csdn.net/l1028386804/article/details/46583279

https://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A2%BC%E9%A0%81936

https://zh.wikipedia.org/wiki/%E6%B1%89%E5%AD%97%E5%86%85%E7%A0%81%E6%89%A9%E5%B1%95%E8%A7%84%E8%8C%83

电报Telegram隐藏手机号的方法

电报Telegram使用手机号注册成功后,默认不隐藏你的手机号,你的手机号会被Telegram上面的其他人看到,很不安全。

如何在Telegram里隐藏手机号,网上教程有很多,搜索一下。

最后记得重启Telegram,隐藏手机号的设置才会生效!

Go数据结构

本文翻译自《Go Data Structures》。

2009/11/24

在向新程序员解释Go程序时,我发现解释Go值在内存中的样子通常有助于建立正确的直觉,了解哪些操作是昂贵的,哪些不昂贵。这篇文章是关于Go的基本类型、结构体、数组和切片的。

基本类型

让我们从一些简单的例子开始:

变量i的类型为int,在内存中表示为一个32位的字(word)。(所有这些图片都显示了32位内存布局;在当前的实现中,只有指针在64位机器上变长了——int仍然是32位——尽管可以选择使用64位的int64类型。)

由于显式转换,变量j的类型为int32。即使ij有相同的内存布局,它们也有不同的类型:赋值i=j会引起一个类型错误,必须使用显式转换:i=int(j)

变量f的类型为float,当前实现将其表示为32位浮点值。它具有与int32相同的内存占用空间,但内部布局不同。

结构体及其指针

现在情况开始变得有趣。变量bytes的类型为[5]byte,是一个由5个字节组成的数组。它的内存表示就是这5个字节,一个接一个,就像一个C数组。类似地,primes是一个由4个int组成的数组。

Go与C一样,但与Java不一样,它可以让程序员控制什么是指针,什么不是指针。例如,此类型定义:

type Point struct { X, Y int }

定义了一个名为Point的简单结构体类型,表现在内存中就是两个相邻的int字段。

复合字面量语法Point{10, 20}表示已初始化的一个Point实例。获取Point{10, 20}的地址&Point{10, 20}表示指向Point{10, 20}的指针。前者是内存中的两个字(word);后者是指向内存中这两个字的指针。

结构体中的字段在内存中并排排列。

type Rect1 struct { Min, Max Point }
type Rect2 struct { Min, Max *Point }

Rect1是一个具有两个Point字段的结构体,在内存中由一行中的两个Point字段(四个int)表示。Rect2是一个具有两个*Point字段的结构体。

使用过C语言的程序员可能不会对Point字段和*Point字段之间的区别感到惊讶,而只使用过Java或Python(或…)的程序员可能会感到惊讶。通过让程序员控制基本的内存布局,Go提供了控制给定数据结构集合的总大小、分配的元素的数量和内存访问模式的能力,所有这些对于构建性能良好的系统都很重要。

字符串

有了这些预备知识,我们可以继续研究更有趣的数据类型。

(灰色箭头表示字符串实现中存在但在程序中不直接可见的指针。)

一个字符串string在内存中表示为一个2字结构体,里面包含一个指向字符串数据(是一个字节数组)的指针和一个长度字段。由于字符串是不可变类型,因此多个字符串共享同一底层存储是安全的,因此对s进行切片会产生一个新的2字结构体,该结构体具有不同的指针和长度字段,但仍然引用相同的底层字节序列。这意味着可以在不重新分配或复制的情况下进行切片,从而使字符串切片与显式地使用下标索引一样高效。

(顺便说一句,Java和其他语言中有一个众所周知的难题,当你对一个字符串进行切片以保存一小段时,对原始字符串的引用会将整个原始字符串保留在内存中,即使只需要少量的字符串。Go也有这个难题。我们尝试过但拒绝了另一种选择,那就是让字符串切片变得如此昂贵——一次再分配和一个新副本——大多数程序都应该避开它。)

切片(slice)

切片是对某个数组的部分引用。在内存中,它是一个3字结构体,包含指向第一个数组元素的指针、切片的长度和容量。长度是x[i]等索引操作的上限,而容量是x[i:j]等切片操作的上限。

与对字符串进行切片一样,对数组进行切片不会产生新副本:它只会创建一个包含不同指针、长度和容量的新结构体。在本例中,一开始创建切片[]int{2,3,5,7,11}在底层会创建一个包含五个值的新数组,然后设置切片x的字段来描述该数组。但切片表达式x[1:3]没有分配更多的数据:它只是创建一个新的切片头结构体,以引用相同的底层数组。在本例中,它的长度为2,即y[0]y[1]是唯一有效的索引,但容量为4,即y[0:4]是有效的切片表达式。(有关长度和容量以及切片使用方式的详细信息,请参阅Effective Go。)

因为切片是多字结构体,而不是指针,所以切片操作不需要分配内存,甚至不需要为切片头分配内存,因为切片头通常可以保存在栈上。这种切片的使用成本与在C语言中显式传递指针和长度对一样低。Go最初将切片表示为指向上述结构体的指针,但这样做意味着每个切片操作都会分配一个新的内存对象。即使使用快速的内存分配器,也会给垃圾收集器带来很多不必要的工作。不使用指针和分配内存使得切片足够便宜。

new和make

Go有两个数据结构创建函数:newmake。它们的区别在早期是一个常见的混淆点,但似乎很快就变得很自然了。基本区别是new(T)返回一个*T,Go程序可以隐式地解引用该指针(下图中的黑色指针),而make(T,args)返回普通的T,而不是指针。通常,T内部有一些隐式指针(下图中的灰色指针)。new返回一个指向值全是0的一块内存区域的指针(如下图所示),而make返回一个复杂的结构体。

有一种方法可以将这两者统一起来,但这将是对C和C++传统的重大突破:定义make(*T)返回一个指向新分配的T的指针,这样当前的new(Point)就可以被改写为make(*Point)。我们尝试了几天,但认为这与人们对分配函数的期望太不一样了。

更多……

这已经有点长了。接口(interface)、映射(map)和通道(channel)将不得不等待将来的发布。

你应该写坚持写博客,即使没有一个读者

本文翻译自《You should blog even if you have no readers》,作者是开源的分布式实时大数据处理框架Apache Storm的作者。

Spencer Fry的《为什么企业家应该写作》是一篇很棒的文章。我想进一步补充一点,写作的好处是如此非凡,即使你没有读者(无论你是否是企业家),你也应该写博客。

我有50多份未完成的草稿。其中一些只是我和自己争论时写下的一些想法。它们中的大多数永远不会出版,但我从所有这些写作中获得了价值。

写作使你成为更好的读者

博客改变了我阅读别人文章的方式。

在努力寻找正确的方式来构建和展示我的帖子的过程中,我更加适应什么是好的论点,什么是坏的论点。我也变得更善于发现别人推理中的漏洞。

同时,在阅读时,我不太可能陷入以微弱的反驳证据而诋毁帖子的陷阱。在大多数帖子中,都可能有基于特殊案例的反驳。网络评论者喜欢指出这些。然而,这些特殊的案例错过了帖子的主旨。通过理解帖子论点背后的隐含背景,我从阅读中获得了更多的价值。

我也更了解优秀作家的风格。我在脑海中注意优秀作家表达自己想法的方式。我一直很喜欢Paul Graham的写作,但现在我真的很欣赏他组织自己的帖子的方式。他有一种很棒的能力,可以把你吸引到他的世界里,并向你展示他眼中的世界。通过阅读Bradford Cross的博客,我学到了很多关于优秀写作的知识;他的帖子有一个清晰的弧线,很好地利用简短的段落来保持帖子的流畅性。

写作使你更加聪明

写作可以揭示你思维中的漏洞。当你的想法被写下来并回头看时,它们的说服力要比它们在你脑海中时低得多。写作迫使你通过思考和反驳来使你的想法更成熟。

写作可以帮助你以连贯的方式组织你的思想。当这些话题出现时,你就能侃侃而谈。我记不清有多少次我和其他人进行了更深层次的对话,因为我已经让自己的想法变得成熟。

把其他任何东西都视为附带收益

写作给你的其他一切东西——个人品牌、人际网络、工作机会——都只是附带的好处。这些好处有时候非常大,但它们不是你应该写作的主要原因。

你应该写作,因为写作会让你成为一个更好的人。

为什么企业家应该写作

本文翻译自《Why entrepreneurs should write》。

Spencer Fry

2010/07/14

人们问我为什么要花时间写文章。我从制定和分享我的想法中得到了什么价值?我没有引入广告,所以不会在月底领到广告薪水——那为什么要这样做呢?我认为,作为企业家,把你的想法用语言表达出来可以帮助你思考自己的想法,帮助推销自己和产品,并带来良好的人际关系机会。但首先反驳一下大家对简讯(newsletter)的看法……

简讯

正如GigaOM的Mathew Ingram在一篇题为《是时候停止写博客并开始写电子邮件简讯?》的文章中所写的那样,一群人——主要是纽约市的企业家社区——已经从写博客转向写简讯。Jason Calacanis是2008年第一个这样做的人,他说这是一种解决他收到的辱骂言论的方式。通过简讯,人们可以直接向他发表评论,而不是向所有阅读他的帖子的人发表评论。问题解决了。

直到最近,Sam Lessin关闭了他的博客,推出了Letter.ly,作为一项简讯服务,你可以对自己的内容收费,尽管价格不高。“所以,是的,旧的又变成了新的,”Sam写道。

但我不使用简讯!

信息是用来消费的。它应该是免费的。它旨在让尽可能多的人接触到,分享和讨论。一堵围绕信息内容的墙——无论是付费的还是其他的——注定要倒塌。你只需要看看Jason Calacanis,当他真的想发出自己的声音时,他会在博客上重新发布他的简讯。

这个简讯“运动”,如果你真的可以这么称呼它的话——只有少数人真正在做——我猜订阅的人更少,它已经成为了一个过渡阶段。我非常尊重Sam、Michael、David、Andrew和其他转而撰写简讯的人——他们都是我的朋友——但如果看到他们在这件事上坚持己见,我会感到惊讶。如果他们真的重视写作的意义,那么他们将再次公开分享自己的内容。

博客已死?不全是

我认为博客在某种程度上已经死了。我不认为我的个人网站spencerfry.com是一个博客。这是一本散文集。传统意义上的博客——你对X、Y和Z的想法的片段——已经被推特、脸书和汤博乐所取代。几乎任何大小的段落都可以压缩到140个字符。

如果人们要坐下来阅读你要说的话,那么你必须认真写出一些值得阅读的内容。这年头信息爆炸,如果你想让别人阅读你的文章,那么你必须选择一个有趣的话题,深思熟虑地阐述你的想法,并支持你的论点。所有这些都需要不止140个字符,如果做得好,确实值得一读。

思考想法

大多数时候,当我坐下来写一篇文章时,我的脑海里都没有一个清晰的画面,我要说什么。只要我有一个我想谈论的话题和立场,总有回旋的余地让我形成自己的想法。把所有的东西都写下来有助于我完成思考的过程,并让我对某个话题做出有力的决定。如果它是书面的形式,那么当我点击“提交”时,我必须100%支持它。

通常先思考我将要写什么内容。然后以一个标题(尽管这通常会改变)、各个章节的标题以及每个标题下的一些潦草的想法开始。接下来,我开始写一些简介(在每个标题下面),最后把每一章节下面的段落都整理出来。

当我写完一篇文章时,我已经彻底地审视了这个话题的各个角度,做了研究,找到了一些外部证据,并在谷歌搜索栏上搜索了关于这个话题的相关材料。这个过程有助于巩固我的思考,像这样系统地充实你的想法的过程本就对你有所帮助。

教会你的读者

写下你的想法不仅有助于你形成自己的想法,而且教育读者也是一件非常值得做的事情。《通过教育促进真实生活》一书中指出,“你可以回馈支持你的社区,同时获得一些不错的宣传曝光率。”

俗话说,分享就是关爱。通过你的产品和你的名字,你的文章能得到进一步讨论的评论,你会收到读者的电子邮件,以及你遇到的那些读过你的文章的读者。我每次都很快乐。

网络(在线)

我在2010年4月写的一篇题为《如何建立网络》的文章给出了一些关于如何成功地在线下建立网络的基本技巧,但对于一个想要为自己和产品扬名立万的企业家来说,在线网络同样重要。

写一篇深思熟虑的文章意味着你有140个字之外的话要说,赢得你的尊重,并让你接触到有趣的人。我写作的许多粉丝都成了Carbonmade的粉丝。我们甚至被推荐为合作伙伴,成为了朋友。

推特、脸书、汤博乐等等都值得你花时间,但我发现没有什么比深思熟虑的散文集更能吸引大批粉丝了。如果你想从人群中脱颖而出,你首先必须在地面上划出一条线,表明你在什么问题上的什么立场。

Ubuntu22安装PHP8.2的方法

首先更新系统:

sudo apt update && sudo apt upgrade -y

Ondrej sury PPA仓库是目前维护PHP最新版本的仓库,我们添加这个仓库:

sudo add-apt-repository ppa:ondrej/php

再次更新系统以使添加的Ondrej sury PPA仓库生效:

sudo apt update && sudo apt upgrade -y

安装php8.2:

sudo apt install php8.2 -y

安装完成后,检查php的版本:

php --version

使用sudo apt-get install php8.2-PACKAGE_NAME命令安装php常用扩展,把PACKAGE_NAME替换为具体的扩展名:

sudo apt-get install -y php8.2-cli php8.2-common php8.2-fpm php8.2-mysql php8.2-zip php8.2-gd php8.2-mbstring php8.2-curl php8.2-xml php8.2-bcmath

查看已经安装了哪些php扩展:

php -m

参考

https://techvblogs.com/blog/install-php-8-2-ubuntu-22-04