一些简单的 Erlang 的用法(RabbitMQ)

众所周知,RabbitMQ 底层的开发语言是 Erlang,所以通过一些简单的 Erlang 操作能获得一些 RabbitMQ 的底层信息。

通过新的 Node 节点来进行连接和调用

通过命令erl -sname test ,我们先新建了一个节点。

new-erlang-node

接下来就是通过命令 net_adm:names(). 来查看当前机器上的 Erlang 节点。

exist-erlang-nodes

然后通过命令 net_adm:ping('rabbit@Asia'). 来连接上 RabbitMQ 的节点。

connect-to-erlang-node

接下来就可以通过命令 rpc:call(<node_name>, <command>, <function_name>, <parameters>) 的形式来执行命令在连接上的节点上。

run-command-on-node

通过 CLI 直接连接到 RabbitMQ 的节点

通过传入 remsh 参数来启动 Erlang 程序。

Read more feature in hexo

When I am using the hexo as my blog system, I found one big problem that really frustrate me. In the home page of my blog website, articles are displayed at full content and that makes the page size so big and the loading time extraordinary long.

《函数式编程入门:使用 Elixir》笔记 2

一些奇特语法点

1
2
3
4
5
[1, 2] ++ [3]
# => [1, 2, 3]

"Hello" <> ", World!"
# => "Hello, World!"

假值包括 false 和 nil,而真值是除了假值以外的所有值。

1
2
3
4
5
6
7
8
true and false
# => false

true && "Hello, World!"
# => "Hello, World!"

1 || "Hello, World!"
# => 1

&& 运算符是另外一个版本的 and,不同之处在于它既可用于布尔值,也可以用于普通值。当第一个表达式为真值时,它返回第二个表达式的值,否则返回第一个。 || 运算符是另外一个版本的 or,它返回第一个真值,否则返回第二个表达式的值。

《函数式编程入门:使用 Elixir》笔记 1

基本思想

函数式编程是一种编程范式。编程范式包括构建软件的规则和设计原则,侧重于使用纯函数构建软件,这些函数的描述方式是要怎么样,而不是使改如何做!使用像 Elixir 这样的函数式语言,可以更好地利用多核 CPU,编写更简洁的代码。在函数式语言中使用函数范式,可以编写出更和谐的程序。前提是要理解其核心概念:不可变性函数声明式代码

不可变数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
list = [1, 2, 3]
# => [1, 2, 3]

List.delete_at(list, 1)
# => [1, 3]

list ++ [4]
# => [1, 2, 3, 4]

list
# => [1, 2, 3]

你可能会想每次都创建新值会降低效率,其实并非如此,Elixir 具有灵巧的数据结构来避免这个问题。

Something about code review

Recently, I was reading some articles which are about the code review. As a software developer, we all know the importance of the code review. But eventually, we will all ignore or put less attention on this step. When I was surfing the Internet, I found Google wrote some pages to explain how they do the code review and which kind of things that we as a reviewer should be aware of.

一些 SQL Server 的小技巧

记得备份!备份!备份!

以下我会记录一些我在实际工作中遇到的或者看到别人记录下的关于 SQL Server 的用法和小技巧。文章会不定期的更新。

临时表结构的创建

1
2
-- 可以用于构建临时表的表结构
select top 0 a, b, c into #d from e

临时表的一些优化方式

临时表可以添加索引或者直接增加主键或复合主键来提升性能。

判断表是否为空

1
2
-- 可以用来判断表里还有没有数据
select 1 from a

大批量数据的生产环境更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
-- 建立表
select top(0) sod.SalesOrderID,
              sod.SalesOrderDetailID,
              sod.ProductID,
              sod.UnitPrice
Into #SalesOrderNeedUpdate
From Sales.SalesOrderDetail as sod;

alter table #SalesOrderNeedUpdate add constraint PK_#SalesOrderNeedUpdate PRIMARY KEY (SalesOrderDetailID, SalesOrderID)

set identity_insert #SalesOrderNeedUpdate on

-- 初始化表数据
insert into #SalesOrderNeedUpdate(SalesOrderID, SalesOrderDetailID, ProductID, UnitPrice)
select sod.SalesOrderID,
       sod.SalesOrderDetailID,
       sod.ProductID,
       0
from Sales.SalesOrderDetail as sod;

-- 更新数据
update #SalesOrderNeedUpdate
set UnitPrice = p.ListPrice
from #SalesOrderNeedUpdate as sonu
join Production.Product as p on p.ProductID = sonu.ProductID

-- 创建分页数据临时表
select top 0 sod.SalesOrderID,
             sod.SalesOrderDetailID,
             sod.UnitPrice
into #SalesOrderPagedData
from Sales.SalesOrderDetail as sod

-- set identity_insert #SalesOrderPagedData on

while exists(select 1 from #SalesOrderNeedUpdate)
begin
    -- 插入分页数据表
    insert into #SalesOrderPagedData(SalesOrderID, SalesOrderDetailID, UnitPrice)
    select top 3000 sonu.SalesOrderID,
                    sonu.SalesOrderDetailID,
                    sonu.UnitPrice
    from #SalesOrderNeedUpdate as sonu

    -- 更新实际表
    update sod
    set sod.UnitPrice = sopd.UnitPrice
    from Sales.SalesOrderDetail as sod
    join #SalesOrderPagedData as sopd
    on sod.SalesOrderDetailID = sopd.SalesOrderDetailID and
       sod.SalesOrderID = sopd.SalesOrderID

    -- 在总的更新数据表中删除已更新的数据
    delete sonu
    from #SalesOrderNeedUpdate as sonu
    join #SalesOrderPagedData as sopd
    on sopd.SalesOrderDetailID = sonu.SalesOrderDetailID and
       sopd.SalesOrderID = sonu.SalesOrderID
end

清空表数据

当需要清空整表数据时,推荐使用 TRUNCATE 语句,因为 DELETE 语句会为每条删除的语句建立 log,所以直接用 TRUNCATE 会更快。对于 I/O 有好处,对于磁盘空间也有好处。

Using Docker (Compose) to host SQL Server AdventureWorks DB

Recently, I am learning the SQL Server performance tunning and the book I am using is using the AdventureWorks database as the sample database. And I don’t want to install the SQL Server Engine in my Surface, not even the Express version. So I am thinking about using the Docker to host my database. After some investigations and tries, I figured it out.

《SQL Server 性能调优实战》笔记 1

T-SQL 语句编写的一些简单方针

  1. 编写语句前,一定要了解业务需求。
  2. 确定过滤字段能否使用索引,是否合理。重复率是一个指标,可以通过查询统计信息获得。
  3. 不要对有索引的字段使用任何计算,包括函数。
  4. 小表操作优先,用小表驱动大表。执行计划里尽量是 NESTED LOOP。
  5. 只返回必要的字段。
  6. 保持 SQL 语句简单。
    • 只简单的存在 2~4 个表的关联。
    • 不要有复杂的过滤条件,只有 2~3 个条件判断。
    • 越复杂的语句在业务量大的系统中,越会有“变异”的可能性。适度考虑用固定执行计划
    • 如果要 order by 的话,尽量使用有索引的字段进行。
    • 不要遗漏 join 关键字,不然的话容易发生笛卡尔积。

SELECT 语句

  1. 只查询需要的字段。
  2. 限定查询的结果集的大小。
  3. 高效的使用和建立索引来提高性能。

ORDER BY/DISTINCT/GROUP BY

从索引的角度分析

1
2
3
4
5
6
7
8
9
USE AdventureWorks2019
GO

SELECT
sod.OrderQty,
sod.ProductID
FROM Sales.SalesOrderDetail AS sod
WHERE sod.ProductId = 870
ORDER BY sod.OrderQty DESC

默认情况下的执行计划和 I/O 情况如下所示:

Surface Go2 M3 LTE 版本使用感受

为了能在地铁上看看文档并且同时处理一些简单的事物,我购买了目前唯一一款全新的能支持 4G LTE 的 Surface 设备。

Surface Go2

Surface Go2

购买

以下是一些可供选择的购买配置

Purchase Option

我选择的是最高配的版本,因为我想顺带能连接家里的两台 4K 显示器。

多显示器

默认情况下,通过 Surface Go2 自带的一个 Type-C 接口,只能连接一台 4K 显示器 (60Hz 频率)。需要通过扩展坞才能实现多台显示器的连接。通过实际体验和理论参数配对,排除了一下几款。

最终,我打算购买微软官方的新版 Surface Dock。以下是一些微软官方的支持参数链接。

扩展坞的要求和参数

第二块显示屏的扩展要求

性能体验

以下是我的 Surface 的任务管理器的截图。总体来说能满足大部分的使用场景。

Task Manager

我按照主力机的软件安装列表,挑选了一些常用的编程软件进行安装和使用。综合来说,如果是大型的 IDE 的话,比如 Visual Studio,JetBrains 全家桶的话,启动会有些慢,但是一旦启动完,编译和浏览代码的体验还是可以接受的。当然不能和搭载酷睿处理器的电脑进行比较,不过日常轻度使用还是没有任何问题的。这篇文章就是我用 Visual Studio Code 在 Surface Go2 上编辑的。

移除 Git 里面的 Submodule

最近在整理我的博客项目中,用到了 hexo 的 next 主题,因为主题的原作者仓库的地址发生了变化,所以我也相应的 fork 了新的仓库,从而需要更新已有的博客项目中的 module 引用。下面我把步骤列出,以备后用 :)

移除已有的 module

移除 .gitmodules 文件夹

1
2
cd <project-root-path>
rm .gitmodules

Stage 刚才的修改

1
2
cd <project-root-path>
git add .gitmodules

修改 .git/config 文件的内容

删除所有和你想删除的 module 的相关行

[submodule "vendor"]
url = git://github.com/SharryXu/hexo-theme-next.git

通过 git 命令来移除 submodule

1
git rm --cached path/to/your/submodule

物理移除在 .git 的 submodule 文件夹下的 module 文件夹

1
rm -rf .git/modules/submodule_name

提交修改 (先前 Stage 的修改)

1
git commit -m "<comment>"

物理移除 submodule 的文件夹

1
rm -rf path/to/your/submodule

注意:在这里的命令都是 UNIX 系统下的,如果是使用 Windows 系统, PowerShell 的命令或参数可能有所不同。