Aliyun 支持IPv6

启用 IPv6 的主要有四步:

  • 注册并创建 IPv6 通道
  • 配置 ECS 使其支持 IPv6
  • 配置 Nginx 使其监听 IPv6 端口
  • 配置 DNS 使其支持 IPv6 解析

第一步:注册并创建 IPv6 通道

注册 https://www.tunnelbroker.net/ (需要邮箱验证)
点击 Create Regular Tunnel
在IPv4 Endpoint (Your side)处填上 ECS 的 IPv4 地址
在Available Tunnel Servers中选择Hong Kong, HK(如果你面向海外用户,可以选择更接近目标用户的地区)
点击Create Tunnel后,通道就创建完成了

第二步:配置 ECS 使其支持 IPv6

编辑/etc/sysctl.conf,将以下三项的配置改成0

  net.ipv6.conf.all.disable_ipv6 = 0
  net.ipv6.conf.default.disable_ipv6 = 0
  net.ipv6.conf.lo.disable_ipv6 = 0

在/etc/network/interfaces底部加上以下内容(注:下面大写的处,需要替换成你在 HE 得到的Server IPv6 Address,但不包括最后的::1/64,如:

2001:470:100:100
  auto he-ipv6
  iface he-ipv6 inet6 v4tunnel
  address <IPV6>::2
  netmask 64
  remote <HE 的 Server IPv4 Address>
  local <阿里云的 IPv4 地址(内网IP)>
  endpoint any
  ttl 255
  gateway <IPv6>::1
  up ip -6 route add 2000::/3 via ::<HE 的 Server IPv4 Address> dev he-ipv6
  up ip -6 addr add <IPv6>::1:1/128 dev he-ipv6
  up ip -6 addr add <IPv6>::2:1/128 dev he-ipv6
  down ip -6 route flush dev he-ipv6

重启服务器
执行ifup he-ipv6确认 IPv6 已启用

第三步:配置 Nginx 使其监听 IPv6 端口

server {
  listen 80; // 监听 IPv4 的 80 端口
  listen [::]:80; // 监听 IPv6 的 80 端口
}

server {
  listen 443 ssl http2; // 监听 IPv4 的 443 端口
  listen [::]:443 ssl http2; // 监听 IPv6 的 443 端口
}

第四步:配置 DNS 使其支持 IPv6 解析

这步最简单,只需给相应的域名加上AAAA解析,值填 HE 里的Client IPv6 Address,去掉最后的/64即可,如

2001:470:100:100::2

Unity Android 编译依赖 Gradle 的版本

Unity项目导出Android编译经常遇到的问题就是Gradle版本不匹配的问题。默认情况下Android Studio会自作聪明地取最新版本的Gradle。
Gradle Build Error: Gradle version 2.10 is required. Current version is 4.0.1

2017.1 和 2017.2 使用
Android plugin version 2.1.0
Gradle version 2.14

2017.4 和 2018.1 使用
Android plugin version 2.3.0
Gradle version 4.0.1

2018.2 使用
Android plugin version 3.0.1
Gradle version 4.2.1

2018.3 使用
Android plugin version 3.2
Gradle version 4.6

C# for 和 foreach 性能测试

for与foreach从性能上来讲几乎是一样的,主要区别在栈内存的使用上。foreach会涉及迭代器,而迭代器会使用栈内存。从某种程度来说,foreach其实是一种语法糖,甚至连微软也推荐在循环中操作集合涉及到添加或移除项时只使用for,否则可能会产生不可预知的副作用。

测试方式是for 和 foreach 分别遍历一个数组一百万次。

测试1:遍历数组时,每个元素只访问一次

测试2:遍历数组时,每个元素访问多次

测试环境

1. macOS
2. Mono Runtime

Program.cs

using System;
using System.Diagnostics;

class Program {
    static void Main() {
        Console.WriteLine ("Runing Csharp Loop Performace Test.");
        const int loop_count = 1000 * 1000 * 100;
        int[] array = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
        // 测试 for 性能
        var watch_1 = Stopwatch.StartNew();
        for (int i = 0; i < loop_count; i++) {
            TestCase.case_for(array);
        }
        watch_1.Stop();
        // 测试 foreach 性能
        var watch_2 = Stopwatch.StartNew();
        for (int i = 0; i < loop_count; i++) {
            TestCase.case_foreach(array);
        }
        watch_2.Stop();

        Console.WriteLine ("case for: " +
                           ((double)(watch_1.Elapsed.TotalMilliseconds * 1000000) / loop_count).ToString("0.0 ns"));
        Console.WriteLine ("case foreach: " +
                           ((double)(watch_2.Elapsed.TotalMilliseconds * 1000000) / loop_count).ToString("0.0 ns"));
    }
}

测试1[for 测试]

class TestCase {
    public static int case_for(int[] array) {
        int result = 0;
        for (int i = 0; i < array.Length; i++) {
            result += array[i];
        }
        return result;
    }
}

测试1 [foreach 测试]

class TestCase {
    public static int case_foreach(int[] array) {
        int result = 0;
        foreach (int value in array) {
            result += value;
        }
        return result;
    }
}

测试1耗时

Runing Csharp Loop Performace Test.
case for: 12.1 ns
case foreach: 12.6 ns

测试2 [for 测试]

class TestCase {
    public static int case_foreach(int[] array) {
        int result = 0;
        foreach (int value in array) {
            result += value;
            result += value;
            result += value;
        }
        return result;
    }
}

测试2 耗时

uning Csharp Loop Performace Test.
case for: 20.5 ns
case foreach: 15.4 ns

结论

for的性能是要比foreach要高出一些,但测试1和测试2对比。 需要频繁去访问集合中的元素

result += array[i];

反而会比用foreach还要慢,因为foreach已经把元素取出后无需再次访问集合,元素已经在栈内存中。

所以在使用循环时,也需要考虑实际场景。如果循环内只会访问一次元素,则用for,如果访问多次元素则用foreach,但从易用性以及风格统一的考虑推荐使用foreach,除非有特殊需求再考虑使用for循环。

Git子模块的使用

github在大半年前就允许个人付费用户创建无限个数的私有git仓库,对于个人开发者来说这是一个很好福利。 不过每个仓库是有大小限制的,最大不超过1G。但是一个完整的项目,带上文档和资源很轻松就超过1G。 超过后就必须再付费,每50G/5美元为单位进行再付费。所以为了节省成本,可以把项目拆分到不同的子模块中, 在不同仓库进行分存就可以不超过github的限制。

子模块其实也是一个完整的git仓库,如果单独去维护子模块则跟普通git仓库的操作一致。 但是从父项目的角度来维护,则有一些不同之处。以下是子模块的基本用法和常见的问题。

创建子模块

git submodule add git://github.com/Someone/SomeRepo.git

创建完成后,会生成.gitmodules文件

cat .gitmodule
[submodule "SomeRepo"]
      path = SomeRepo
      url = git://github.com/Someone/SomeRepo.git

更新子模块

git submodule update

本质上,子模块和父项目是不同的仓库。这里有个坑。 git pull并不会更新子模块,此时执行git status发现子模块有更新,则需要执行 git submodule update. 所以正确的更新方式是

git pull
git submodule update

修改子模块

默认情况下,进入子模块HEAD是处理游离状态(detached HEAD), 所以如果要更新子模块,就先要checkout到master

cd submodule_folder
git checkout master
do some mod
git add files
git commit -m 'Mod submodule'
git push

如果开始一开始忘记checkout到master并且有进行commit, 则可以采用如下办法

mod submodule files and commited
git log #查看commit hash id 假定id是12345
git checkout master
git cherry-pick 12345
git push

删除子模块

最简单的方法就是编辑.gitmodule文件把相关信息删除,然后再从文件系统把子模块相关目录删除。

- [submodule "SomeRepo"]
-       path = SomeRepo
-       url = git://github.com/Someone/SomeRepo.git

在Linux下重置Windows密码

前置条件

OS环境为Ubuntu

软件依赖

apt-get update && apt-get install -y ntfs-3g chntpw

操作步骤

1. 假设windows分区为sda2

$> mkdir -p /mnt/win && mount /dev/sda2 /mnt/win

2. 进入config目录

$> cd /mnt/win/Windows/System32/config

3. 查看SAM信息

$> chntpw -l SAM
chntpw version 0.99.6 080526 (sixtyfour), (c) Petter N Hagen
Hive <SAM> name (from header): <\SystemRoot\System32\Config\SAM>
ROOT KEY at offset: 0x001020 * Subkey indexing type is: 666c <lf>
Page at 0x8000 is not 'hbin', assuming file contains garbage at end
File size 262144 [40000] bytes, containing 7 pages (+ 1 headerpage)
Used for data: 299/26944 blocks/bytes, unused: 19/1504 blocks/bytes.

* SAM policy limits:
Failed logins before lockout is: 0
Minimum password length        : 0
Password history count         : 0
| RID -|---------- Username ------------| Admin? |- Lock? --|
| 01f4 | Administrator                  | ADMIN  | dis/lock |
| 01f5 | Guest                          |        | dis/lock |

4. 解锁Administrator

$> chntpw -u Administrator SAM
chntpw version 0.99.6 080526 (sixtyfour), (c) Petter N Hagen
Hive <SAM> name (from header): <\SystemRoot\System32\Config\SAM>
ROOT KEY at offset: 0x001020 * Subkey indexing type is: 666c <lf>
Page at 0x8000 is not 'hbin', assuming file contains garbage at end
File size 262144 [40000] bytes, containing 7 pages (+ 1 headerpage)
Used for data: 299/26944 blocks/bytes, unused: 19/1504 blocks/bytes.

* SAM policy limits:
Failed logins before lockout is: 0
Minimum password length        : 0
Password history count         : 0
| RID -|---------- Username ------------| Admin? |- Lock? --|
| 01f4 | Administrator                  | ADMIN  | dis/lock |
| 01f5 | Guest                          |        | dis/lock |

---------------------> SYSKEY CHECK <-----------------------
SYSTEM   SecureBoot            : -1 -> Not Set (not installed, good!)
SAM      Account\F             : 0 -> off
SECURITY PolSecretEncryptionKey: -1 -> Not Set (OK if this is NT4)
Syskey not installed!

RID     : 0500 [01f4]
Username: Administrator
fullname:
comment : Built-in account for administering the computer/domain
homedir :

User is member of 1 groups:
00000220 = Administrators (which has 1 members)

Account bits: 0x0010 =
[ ] Disabled        | [ ] Homedir req.    | [ ] Passwd not req. |
[ ] Temp. duplicate | [X] Normal account  | [ ] NMS account     |
[ ] Domain trust ac | [ ] Wks trust act.  | [ ] Srv trust act   |
[ ] Pwd don't expir | [ ] Auto lockout    | [ ] (unknown 0x08)  |
[ ] (unknown 0x10)  | [ ] (unknown 0x20)  | [ ] (unknown 0x40)  |

Failed login count: 25, while max tries is: 0
Total  login count: 37

- - - - User Edit Menu:
 1 - Clear (blank) user password
 2 - Edit (set new) user password (careful with this on XP or Vista)
 3 - Promote user (make user an administrator)
 4 - Unlock and enable user account [probably locked now]
 q - Quit editing user, back to user select
Select: [q] > 4

Hives that have changed:
 #  Name
 0  <SAM>
Write hive files? (y/n) [n] : y
 0  <SAM> - OK