友情至上

能记下来的心情就记下吧,不然以后会忘掉的。

记得大一的时候,企鹅还在岛上。有一次我们在南亭吃烤鱼,我表示这样子和朋友吃烤鱼很有气氛,热腾腾的水雾往上冒,即使在寒冷的冬天,也使人感到温暖。

席间,我们聊到我们对友情的态度。至今我仍清晰地记得,这次吃饭,是我对关于朋友的价值观发生重大改变的转折点。

从小我就是一个理性的人,并确立过某些价值观。当时认为读书时候的朋友是临时的,过了一个阶段认识新的人,就会和以前的同学少联系了。事实证明,至今和我仍有联系的老同学为数不多。我觉得这有两方面因素,一是现在不联系的同学本来以前交往就不深,二是我没有刻意去挽留(对方也是。

学计算机网络的时候了解到分层设计的思想,下层向上层服务,下层屏蔽细节。私以为,人也应该这样吧,把自己艰辛的一面放在下层,向上提供屏蔽细节的服务。

以上内容编辑于2019年11月29日,当时不知什么原因没有继续写下去。今天是2020年4月10日,翻开这篇草稿,发现以前写下的内容已经不完全符合现在的价值观了。但是我不打算删改它,至少它代表了我某个时期的心情。

我猜当时的我要表达的是经历了岁月的洗礼仍能存留到现在的友情很重要,且行且珍惜。

随着认识的人越来越多,会发现大家的价值观很不一样,牛人的牛法不尽相同,因此不应在人际交往中苛刻求同。只要是积极向上的价值观就都是好的。

庚子#5 | 课务繁忙

组网

组网也布置上机作业了,要好好听课了。

Linux

在上个星期上完Linux课不久后,我着手开始实验,并把实验报告写完了。可是本周上课的时候,张老师对作业提出了更高的要求。补充作业将是耗时耗力的事情。

法语退课

昨天晚上上了法语课的前半节,冯老师讲课条理清晰。但是随着知识难度的增加,我预料到法语课的知识需要在课后花一定的时间消化。于是在课间休息的时候,我通过企业联系冯老师,恳请退课事宜。

老师对此表示理解。于是我去教务系统把课退了。

小结

现在是2020年3月20日。自由的时间总是越多越好。

庚子#4 | 迎来课多的第一天

闹钟打破清静的早晨,慵懒的少年从被窝中坐起,缓缓下床,开始了他繁忙的一天。

今天的第一件事情莫过于抢阿里云半年免费的云服务器。用云服务器做完作业就扔是一个再好不过的选择。然鹅我因操作的时候犹豫了一下选哪个Linux发行版而错失良机。明日手速快起来,Arch Linux预定!

今天总共上了组网、Linux、Linux实验和法语课。上完Linux实验的时候不想继续上课差点把法语课给退了。不过考虑到还有七天的退课时间,还是先上上课再考虑。不过本次法语课体验不错,所以我得上完下周的课再考虑退不退,大概率不退吧。

法语比俄语明显简单好多,跟日语相比的话我比较不出来。

前天做完了2017英语一的卷子还没来得及整理相关笔记,今天又获得了新的课程作业。布置作业是不对的,委屈。

今天的吃饭时间受到了课程影响,不过久违地吃到了排骨和瘦肉,粗略算了一下价格感觉亏大了,近期不宜猪肉宜鸡鸭。

每周只有星期四课多其实还好啦。明天写作业,刻海星~

《Tu me manques》Sheryfa Luna

庚子#3 | 寒假终了

按常理来说,今天是开学的第一天,但我星期三才有课。所以今天姑且也算是我的寒假。

这个寒假原本打算会独居很久的。为了应对新冠疫情,我在除夕前夕和家人团聚,并且至今也没有独居。 过年期间打了几天麻将。

翡翠台的《黄金有罪》《大酱园》《独孤皇后》成为了茶余饭后的消遣。其中《独孤皇后》 现在还没大结局 。在初一的时候看了《重啟咲良田》,《超炮T》一直有跟进,白井黑子牛逼!很喜欢up主机智的党妹的说话风格。

疫情期间虽然有新电影免费放在了网上,但是我没有去看,倒是花钱重温了《速度与激情8》。一直很喜欢速度与激情这个系列的电影,并非纯粹因为其中的街头情节和人物放荡不羁的个性,更因为他们无论遭遇何种困难始终把家庭放在很很重要的位置。

把学习强国刷到了4700分,最近开始着手经典诵读。

因为个人原因,我退出了一个十多人的里面全是放假就会聚到一起玩的初中同学的微信群。因为我希望今年的社交活动少一点。为了降低自己发说说和发朋友圈的欲望,把QQ空间设成了私密,把朋友圈设成了三天可见。里面没什么隐私,仅仅为了降低自己发说说和发朋友圈的欲望而已。

kx的社恐比我想象中的严重。

和wuli成了研友,互相打卡日常工作。

最近每天下午四点都会条件反射地觅食,主要是鸡蛋炒饭,衣带渐紧终不悔。

不爱听音乐的程序员不是好吃货。

《苏丽珂》The Red Army Choir

己亥#13 | 向恶势力低头

开学的时候本以为自己有充足的时间考一下证,于是当时一冲动就报了BEC-H。记得国庆回家的时候,我带了BEC-H的书和数据结构的书回家,本来打算在家主要看BEC的,但结果BEC实在太难了,在家一直看数据结构。

这个学期要修的学分还是比较多,能自由安排的时间有限。之前曾探索过光年的时间安排方式,即以日历安排行程,不过现在已经弃坑了。本人还是比较喜欢随性的生活。

2019.11.16,这一天早上我去中大东校区考了BEC-H的阅读、写作、听力。阅读做了前面两大题就想离场放弃了。不过看到旁边的人都在认真做,我才坚持了下来。就感觉写作好写一点。听力听着听着手就微微颤抖。向恶势力低头。

早上考完听读写的我已经是没有灵魂的我了。回我校睡了一觉。按照准考证的时间,晚上18:45~19:00是口语考试时间。我在睡觉期间辗转反侧悲愤难眠,最终决定放弃口语部分的考试。

晚上没有去考试,取而代之的是,我去了GOGO和kx喝奶茶聊天。主要是聊天。从中我了解到广外的外语氛围真的比我校好很多。她舍友今天也考BEC,这位在我看来很神奇的她的舍友此前已经考过托福/雅思了的。

广外真是一个神奇的地方。在这个地方,外语大佬真多。

初探C++多线程和锁机制

C++11开始支持多线程编程,并在之后的版本中不断完善。

Hello World单线程写法:

1
2
3
4
5
#include <iostream>
int main()
{
    std::cout << "Hello World\n";
}

Hello World多线程写法:

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <thread> // 1
void hello()      // 2
{
    std::cout << "Hello Concurrent World\n";
}
int main()
{
    std::thread t(hello)// 3
    t.join();             // 4
}

量产线程的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <thread>
void do_work(unsigned id)
{
    std::cout << i << std::endl;
}

void f()
{
    std::vector<std::thread> threads;
    for (unsigned i = 0; i < 20; ++i)
    {
        threads.emplace_back(do_work, i); // 产生线程
    }
    for (auto &entry : threads) // 对每个线程调用 join()
        entry.join();
}

使用 std::lock_guard 保护共享数据:

C++中通过实例化std::mutex创建互斥量实例,通过成员函数 lock() 对互斥量上锁,unlock() 进行解锁。不过,实践中不推荐直接去调用成员函数,调用成员函数就意味着,必须在每个函数出口都要去调用 unlock(),也包括异常的情况。C++标准库为互斥量提供了一个RAII语法的模板类std::lock_guard,在构造时就能提供已锁的互斥量,并在析构的时候进行解锁,从而保证了一个已锁互斥量能被正确解锁。

代码来源于 std::lock_guard

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
#include <thread>
#include <mutex>
#include <iostream>

int g_i = 0;
std::mutex g_i_mutex; // 保护 g_i

void safe_increment()
{
    std::lock_guard<std::mutex> lock(g_i_mutex);
    ++g_i;

    std::cout << std::this_thread::get_id() << ": " << g_i << '\n';

    // g_i_mutex 在锁离开作用域时自动释放
}

int main()
{
    std::cout << "main: " << g_i << '\n';

    std::thread t1(safe_increment);
    std::thread t2(safe_increment);

    t1.join();
    t2.join();

    std::cout << "main: " << g_i << '\n';
}

使用 std::shared_timed_mutex 避免数据竞争

shared_timed_mutex 类是能用于保护数据免受多个线程同时访问的同步原语。与其他促进排他性访问的互斥类型相反,拥有二个层次的访问:

  • 共享 - 多个线程能共享同一互斥的所有权。
  • 排他性 - 仅一个线程能占有互斥。

共享互斥通常用于多个读线程能同时访问同一资源而不导致数据竞争,但只有一个写线程能访问的情形。

代码来源于std::shared_timed_mutex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <mutex>
#include <shared_mutex>

class R
{
    mutable std::shared_timed_mutex mut;
    /* 数据 */
public:
    R &operator=(const R &other)
    {
        // 要求排他性所有权以写入 *this
        std::unique_lock<std::shared_timed_mutex> lhs(mut, std::defer_lock);
        // 要求共享所有权以读取 other
        std::shared_lock<std::shared_timed_mutex> rhs(other.mut, std::defer_lock);
        std::lock(lhs, rhs);
        /* 赋值数据 */
        return *this;
    }
};

int main()
{
    R r;
}

使用 std::scoped_lock 避免死锁

线程有对锁的竞争:一对线程需要对他们所有的互斥量做一些操作,其中每个线程都有一个互斥量,且等待另一个解锁。这样没有线程能工作,因为他们都在等待对方释放互斥量。这种情况就是死锁,它的最大问题就是由两个或两个以上的互斥量来锁定一个操作。

C++标准库有办法解决这个问题,std::scoped_lock——可以一次性锁住多个(两个以上)的互斥量,并且没有副作用(死锁风险),而且是RAII风格喵~。

以下示例用 std::scoped_lock 锁定互斥对而不死锁,且为 RAII 风格。

代码来源于std::scoped_lock

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <functional>
#include <chrono>
#include <string>

struct Employee
{
    Employee(std::string id) : id(id) {}
    std::string id;
    std::vector<std::string> lunch_partners;
    std::mutex m;
    std::string output() const
    {
        std::string ret = "Employee " + id + " has lunch partners: ";
        for (const auto &partner : lunch_partners)
            ret += partner + " ";
        return ret;
    }
};

void send_mail(Employee &, Employee &)
{
    // 模拟耗时的发信操作
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

void assign_lunch_partner(Employee &e1, Employee &e2)
{
    static std::mutex io_mutex;
    {
        std::lock_guard<std::mutex> lk(io_mutex);
        std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl;
    }

    {
        // 用 std::scoped_lock 取得二个锁,而无需担心
        // 其他对 assign_lunch_partner 的调用死锁我们
        // 而且它亦提供便利的 RAII 风格机制

        std::scoped_lock lock(e1.m, e2.m);

        // 等价代码 1 (用 std::lock 和 std::lock_guard )
        // std::lock(e1.m, e2.m);
        // std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock);
        // std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);

        // 等价代码 2 (若需要 unique_lock ,例如对于条件变量)
        // std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock);
        // std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock);
        // std::lock(lk1, lk2);
        {
            std::lock_guard<std::mutex> lk(io_mutex);
            std::cout << e1.id << " and " << e2.id << " got locks" << std::endl;
        }
        e1.lunch_partners.push_back(e2.id);
        e2.lunch_partners.push_back(e1.id);
    }

    send_mail(e1, e2);
    send_mail(e2, e1);
}

int main()
{
    Employee alice("alice")bob("bob")christina("christina")dave("dave");

    // 在并行线程中指派,因为就午餐指派发邮件消耗很长时间
    std::vector<std::thread> threads;
    threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob));
    threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice));
    threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));

    for (auto &thread : threads)
        thread.join();
    std::cout << alice.output() << '\n'
              << bob.output() << '\n'
              << christina.output() << '\n'
              << dave.output() << '\n';
}

使用更为灵活的std::unique_lock

std::unqiue_lock 使用更为自由的不变量,这样 std::unique_lock 实例不会总与互斥量的数据类型 相关,使用起来要比 std:lock_guard 更加灵活。首先,可将 std::adopt_lock 作为第二个参数传入 构造函数,对互斥量进行管理;也可以将 std::defer_lock 作为第二个参数传递进去,表明互斥量应 保持解锁状态。这样,就可以被 std::unique_lock 对象(不是互斥量)的 lock() 函数所获取,或传递 std::unique_lock 对象到 std::lock() 中。

当你想要锁定互斥锁时,可以创建类型为 std::unique_lock的局部变量,并将该互斥锁作为参数传递。 构造unique_lock时,它将锁定互斥锁,并且销毁该互斥锁后,它将解锁该互斥锁。 更重要的是:如果引发异常,则将调用 std::unique_lock 析构函数,因此互斥量将被解锁。

示例 1 代码来源于Stack Overflow

1
2
3
4
5
6
7
8
9
10
11
12
// 示例 1
#include <mutex>
int some_shared_var = 0;

int func()
{
    int a = 3;
    {  // Critical section
        std::unique_lock<std::mutex> lock(my_mutex);
        some_shared_var += a;
    }  // End of critical section
}

示例 2 代码来源于std::unique_lock

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
//  示例 2
#include <mutex>
#include <thread>
#include <chrono>

struct Box
{
    explicit Box(int num) : num_things{num} {}

    int num_things;
    std::mutex m;
};

void transfer(Box &from, Box &to, int num)
{
    // 仍未实际取锁
    std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
    std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);

    // 锁两个 unique_lock 而不死锁
    std::lock(lock1, lock2);

    from.num_things -= num;
    to.num_things += num;

    // 'from.m' 与 'to.m' 互斥解锁于 'unique_lock' 析构函数
}

int main()
{
    Box acc1(100);
    Box acc2(50);

    std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);
    std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);

    t1.join();
    t2.join();
}

小结

我们现在会用C++写多线程代码啦,但是如何避免死锁,何种情况该用std::lock_guardstd::shared_timed_mutexstd::scoped_lockstd::unique_lock,仍需要多加练习噢。

C++11 featureの右值引用

C++11的feature应该不能算new feature了叭,毕竟这个版本已经年代久远了。来,我们学习一下C++11的右值引用。

什么是左值,什么是右值?

lvalue这个词来自于C语言,指的是可以放在赋值表达式左边的事物——在栈上或堆上分配的命名对象,或者其他对象成员——有明确的内存地址。

rvalue这个词也来源于C语言,指的是可以出现在赋值表达式右侧的对象——例如,文字常量和临时变量。

左值引用

首先我们回顾一下年代更为久远的左值引用。

1
2
3
4
int var=42;
int& ref=var; // 创建一个var的引用
ref=99;
assert(var==99); // 原型的值被改变了,因为引用被赋值了

左值引用只能被绑定在左值上,而不是右值。 因此左值引用不能这样子写:

1
int& i=42;  // 编译失败

不过我们可以钻空子。像这样:

1
int const& i = 42;

右值引用

C++11标准介绍了_右值引用_(rvalue reference),这种方式只能绑定右值,不能绑定左值,其通过两个&&来进行声明:

1
int&& i=42; // 正确

不能绑定左值噢:

1
2
int j=42;
int&& k=j; // 编译失败

右值引用用途の移动语义

右值通常都是临时的,所以可以随意修改;如果知道函数的某个参数是一个右值,就可以将其看作为一个临时存储或“窃取”内容,也不影响程序的正确性。这就意味着,比起拷贝右值参数的内容,不如移动其内容。动态数组比较大的时候,这样能节省很多内存分配,提供更多的优化空间。

精简版:在传参的时候使用右值引用可以避免在内存中创建重复的变量副本,空间复杂度更低。

举个例子叭,比如老的这种写法就很耗内存:

1
2
3
4
5
void process_copy(std::vector<int> const& vec_)
{
std::vector<int> vec(vec_);
vec.push_back(42);
}

在以上代码中,一个函数以std::vector<int>作为一个参数,就需要将其拷贝进来,而不对原始的数据做任何操作。

如果使用右值引用版本的函数来重载这个函数,就能避免在传入右值的时候,函数会进行内部拷贝的过程:

1
2
3
4
void process_copy(std::vector<int> && vec)
{
vec.push_back(42);
}

右值引用用途の 函数模板

如果函数模板参数以右值引用作为一个模板参数,当对应位置提供左值的时候,模板会自动将其类型认定为左值引用;当提供右值的时候,会当做普通数据使用。

我帮你整理一下思路:

1
2
3
4
5
6
7
8
if(函数模板参数以右值引用作为一个模板参数){
if(对应位置提供左值){
模板会自动将其类型认定为左值引用
}
if(对应位置提供右值){
会当做普通数据使用
}
}

举个栗子,定义一个函数模板:

1
2
3
template<typename T>
void foo(T&& t)
{}

随后传入一个右值,T的类型将被推导为:

1
2
3
foo(42);  // foo<int>(42)
foo(3.14159); // foo<double><3.14159>
foo(std::string()); // foo<std::string>(std::string())

不过,向foo传入左值的时候,T会被推导为一个左值引用:

1
2
int i = 42;
foo(i); // foo<int&>(i)

因为函数参数声明为T&&,所以就是引用的引用,可以视为是原始的引用类型。那么foo()就相当于:

1
foo<int&>(); // void foo<int&>(int& t); 

这就允许一个函数模板既可以即接受左值,又可以接受右值参数。

小结

我萌先回顾了左值、右值的术语概念和左值引用的语法,然后介绍了右值引用的语法,最后讲了右值引用的两种用途:移动语义和函数模板。

加油啦,你最棒!

ES6箭头函数の小陷阱

ES6箭头函数语法糖真好吃,不过也有一些小陷阱噢~

噜啦啦噜啦啦噜啦噜啦咧~我萌一起来看看箭头函数の两种陷阱叭!!

箭头函数和对象字面量

箭头函数提供了更简短的语法,可以将函数编写为具有隐式返回值的 lambda 表达式。比如使用一个函数映射一些数组。使用常规函数可能会多出很多空行。

例如:

1
2
3
4
const numbers = [1, 2, 3, 4];
numbers.map(function(n) {
return n * n;
});

用 lambda 样式的箭头函数来写的话,就会写成两行优雅、易读的代码:

1
2
const numbers = [1, 2, 3, 4];
numbers.map(n => n * n);

在这种用例中,箭头函数的表现符合预期,它将值本身相乘并返回到包含 [1, 4, 9, 16] 的新数组。

如果你尝试映射到对象,那么结果可能和你想象的不一样了。例如,假设我们试图将数字映射到包含如下值的对象数组中:

1
2
const numbers = [1, 2, 3, 4];
numbers.map(n => { value: n });

这里的结果实际上是一个包含未定义值的数组。虽然看起来在这里返回一个对象,但是解释器看到的东西完全不一样。花括号被解释为箭头函数的块作用域,而值语句最后实际上成为了标签。在解释器眼里,它看起来是这样的

1
2
3
4
5
6
const numbers = [1, 2, 3, 4];
numbers.map(function (n) {
value:
n
return;
});

解决方法在这里。只需要将对象包装在括号中,就可以将它变成一个表达式而不是一个块语句,如下所示:

1
2
const numbers = [1, 2, 3, 4];
numbers.map(n => ({ value: n }));

这会计算出一个包含对象数组的数组,该对象数组具有预期的值。

箭头函数和绑定

箭头函数没有自己的 this 绑定,即它们的 this 值和封闭词法作用域的 this 值是一样的。

箭头函数的this 绑定很可能与你原本所想的不一样。例如:

1
2
3
4
5
6
7
8
let calculator = {
value: 0,
add: (values) => {
this.value = values.reduce((a, v) => a + v, this.value);
},
};
calculator.add([1, 2, 3]);
console.log(calculator.value); // 0

我们希望这里的 this 绑定为此处的 calculator 对象,但实际上 this 绑定最后要么是未定义,要么是全局对象,具体取决于代码是否在严格模式下运行。这是因为这里最接近的词汇作用域是全局作用域。在严格模式下这是未定义的。(否则,它会是浏览器的窗口对象(或 Node.js 兼容环境中的过程对象。

常规函数具有 this 绑定。在对象上调用时,this 将指向该对象,因此常规函数依然是获得成员函数的正确途径:

1
2
3
4
5
6
7
8
let calculator = {
    value0,
    add(values) {
        this.value = values.reduce((a, v) => a + v, this.value);
    },
};
calculator.add([1, 2, 3]);
console.log(calculator.value);  // 6

另外,由于箭头函数没有 this 绑定,因此无法使用Function.prototype.call、Function.prototype.bind 和 Function.prototype.apply。声明箭头函数后,this 绑定设置为固定,无法更改。

因此,下面的示例将遇到与之前类似的问题:当调用 adder 的 add 函数时,this 绑定又成了全局对象,尽管我们尝试使用 Function.prototype.call 覆盖它:

1
2
3
4
5
6
7
8
9
const adder = {
add: (values) => {
this.value = values.reduce((a, v) => a + v, this.value);
},
};
let calculator = {
value: 0
};
adder.add.call(calculator, [1, 2, 3]); // undefined

什么时候IDE才能学会自己写代码 :)

参考链接:

Lesser-Known JavaScript Hazards

ECMAScript® 2018 Language Specification

己亥#12 | 乌拉~日漫好好看哦

今天久违地打了篮球。已经记不清上次打球是什么时候了。最近希望去游泳。上次游泳的时间是2019年8月13日,距今已有一个多月。我对游泳的向往是其他体育活动无法替代的,因为游泳使我感到安逸。

本周看了《热诚传说 X》《热诚传说第二季》,旷了很多课但是并没有把时间用来学习,而是看了一部讲述清朝康熙宫廷的古装电视剧。目前在追《某科学的一方通行》。

看日漫的过程中,可以感受到,日漫表达的主题大都是追求世界和平、人们和谐相处。在日漫的正面派人物中,少有猜疑、谋略和权术。而中国封建古装剧有所不同,凡事讲求智取,成事前需要总体谋划,顾全大局。

在一战、二战之时,日本是一个军国主义的君主立宪制国家,当时日本民众皆臣民,应当服从假借天王之名的一切号召。那为何发展至今,日本的动漫却表达出对美好纯净的世界的向往和对战争的厌恶呢?

自1889年起,日本是一个君主立宪制的国家,当时的宪法为《大日本帝国宪法》,又称明治宪法第二次世界大战后,新制定的日本国宪法规定,天皇是国民团结的象征,对政府不具有干涉力。

根据日本国宪法第九条,日本永远放弃战争的和平主义原则奉为神圣不可侵犯的权利,但同时为了灵活参与国际事务“威胁或使用武力作为解决国际争端的手段”写进宪法。

同盟国军事占领下现行宪法,1946年11月3日公布修改了大日本帝国宪法,1947年5月3日施行以来,日本国内一直存在修改宪法的议论。不少保守派政治家主张,因为现行宪法是美国草拟的,没有正统性。但长期以来,日本社会大多不重视宪法修改问题。

来源:维基百科-日本政治

二战后,日本战败,同盟军驻日。期间日本修改过宪法。自新宪法颁布以来,人们的人权大大提高,日军在宪法中的地位大大降低。久而久之,日军江河日下。

那么改宪对各方有何好处呢?首先,通过制定法律来降低日军在本国的地位,日军对同盟国的威胁降低。其次,日本人得到了更大程度的自由,更多地考虑如何过好日子而不是如何上阵杀敌。最后,对日军没有好处只有坏处。

日漫描绘理想化的环境,体现了人们对和平世界美好生活的向往。但是现实非理想,一味保持单纯清净的心,难以应付多变的世界。世事变坏莫测,掌握谋略权术是必须的。正是出于生存的需要, 才有了前人对谋略的总结,才有了《鬼谷子》《战国策》《孙子兵法》等。谋事在人,世界的美好发展有赖于人们的共同努力;生而为人,当为造福全人类而读书。

《Expelled from Paradise》观后感

因为光年推荐,我看了Expelled from Paradise这部电影。

不得不说,艺术源于生活又高于生活。女主的容貌、身材实在是太好了叭——可以想象艺术家设计女主身材的时候有多猥琐用心。萌萌的,即便是她倔强的一面,也很可爱。

男主的人品有点坏,不过坏得恰到好处,他耍无赖的时候情节略带戏剧性。在女主有需要的时候,会适时提供帮助。

光年之所以推荐这部电影,是因为我们之前聊到人工智能与人类是否能共存这个话题,而这部电影的乐园里的人格、弗隆提亞·賽格 (フロンティアセッター)是典型的人工智能形象。

弗隆提亞·賽格 是自我更新到有“我”的意识的人工智能新生事物,致力于独自完成发射火箭送人类探索太空的任务。乐园里的人格(比如女主)是二进制数据,表面上无痛无痒幸福快乐。

剧情伊始,人工智能新时代,数据人格比肉体人类先进多了,真是实名羡慕。剧情以 [ 乐园服务器被入侵,女主去调查 ] 展开。不过越往后看,会发现主编另有话说。

电影的主题应该是人生而自由。

在乐园里,地位越高的人格会得到越多的计算资源。计算资源越多,人格的行动力越强,本领越大。女主对工作认真负责,多年的付出从来不负女主所望,她现已身至三等官。

人的欲望是无限的人民对美好生活的需要是日益增长的,二进制人格也难以幸免。为了获得更多的计算资源,女主努力工作,盼望有朝一日升到一等官。

男主是一个凡夫俗子,对物质的看法比较现实。他多次帮助乐园(有酬)解决困难,并因为表现出色而多次收到乐园的邀请,请他加入乐园,成为二进制人格的一分子。

男主从来都不接受乐园的邀请。女主不解——乐园物质极大丰富日子可以过得很潇洒,为何男主不肯加入?

追求高质量生活的女主,并没有发现利益关系早已纠缠了她。举个例子:为了在同行中抢功劳,她趁早出发调查黑客身份。而打算抢功劳的人格又岂止女主一个?

男主的生活就比较随性了,在芜芜杂世中,他保留着对音乐的爱好,夜间开车累了就主张睡觉(这种表现是日出而作日落而息的一个缩影)。乐园里有阳光照射不到的地方,人际社会一样有。但是男主历尽千帆,仍是少年。

我并没有贬低奋斗者的意思。我建议一个人去追求自己内心想要的生活,而不要被束缚于追求社会风气所推崇的生活。而且,在追求自己内心想要的生活的过程中,难免会受到不必要的干扰,这时要认清自己内心的想法。

在影片最后,女主重新(之所以说是重新,是因为她曾是人类)回到人间生活。逃离乐园到人间生活,依然有可能被人间的利益关系所纠缠。不过当一个人已经被利益纠缠得狼狈不堪,那么请尽快用全力摆脱现状,重新开始生活,而女主也确实做到了这一点。

弗隆提亞·賽格的思想得到进一步解放,决定自行探索太空。

相关文章:自由是人最宝贵的权利——由电影《无问西东》想到的