徒手攀岩的风险很低,只是后果很严重

今年的奥斯卡最佳纪录片奖,颁给了一部纪录片,叫做《徒手攀岩》。我早就知道这部片子的大名,但是最近才有时间把它看了。看完之后,给了我一个巨大的启发。

什么启发?先卖个关子,咱们后面再说。先来简单介绍一下这部片子。

《徒手攀岩》记录的是一位叫做Alex的职业攀岩运动员,徒手爬上一座悬崖的过程。那座悬崖,叫做酋长岩,在美国的优山美地国家公园。这块岩石,是地球表面上最大的一块单体花岗岩。高914米,比世界上最高的建筑,迪拜的哈利法塔还要高。纪录片里有一个镜头,Alex在上面爬的时候,就像蚂蚁一样渺小。我在节目文稿里放了一张照片,你可以感受一下,有多么地惊险


请注意,这是徒手攀岩啊。没有任何工具和保护措施,在近乎笔直的悬崖上,要往上攀登将近一公里,全程要几个小时。攀岩者全身的重量,只靠手指和脚尖支撑。而支撑手脚的,可能只是山崖上一块不到2厘米宽的突起。当前进的时候,也就是要换手换脚的时候,全身的支撑点会减少到两个。只要一次失误,只能是粉身碎骨,不会有第二种可能性。

即使是在专业的攀岩运动员看来,这也是一个不可能完成的任务。说白了,就等于送死。但是在纪录片中,Alex说了一句话,非常地奇怪,他说:“风险和后果是两回事。徒手攀岩的风险很低,只是后果很严重。”

哎,这话什么意思?

只要抽身出来一想,就明白了。我们每天出门上班,如果出车祸死了。这个后果确实是很严重。但是这件事风险很高吗?不高啊。只要你小心走路,驾车,遵守交通规则,风险是可控的啊。

他说,最大的风险,不是外界的风吹草动,而是内心的情绪和压力。最大的敌人不是眼前那块陡峭的岩壁,最大的敌人就是自己。

徒手攀岩和一般的攀岩有什么区别?无非就是有绳和没绳嘛。有绳的时候,你会感到安全,可以轻松上阵。没绳的时候,你的每一步行动都事关生死,那个压力是惊人的。压力会把我们击倒,让我们陷在深深的恐惧里,彻底丧失行动的能力。

那怎么办呢?Alex的答案很简单,只能是增加对自己情绪的控制感。

这部纪录片介绍说,Alex每天不是住在房子里,而是住在一辆拖车里,吃饭睡觉都在车里,就是为了靠近悬崖峭壁,好进行训练。他在攀岩以外,主要的时间,就是在拖车里练习引体向上。不是用手掌,而是用手指吊起全身的重量,一吊就是一个小时。这么做,除了训练自己的身体之外,还是对自己情绪的训练,要建立百分之百的控制感。控制到什么程度?控制到能够抑制自己杏仁核的程度。

杏仁核,我们都知道,是人的情绪中枢。人之所以会感到恐惧,就是杏仁核活跃的结果。在纪录片里,医生对Alex的大脑做过一次核磁共振,发现他的杏仁核比普通人要平静。换句话说,Alex在攀岩的时候,不会像普通人那样感到恐惧。这是为什么呢?你可以说是基因的原因,Alex的大脑就是异于常人。但Alex自己的解释是,他跟悬崖峭壁相处的时间太长了,所以,他的杏仁核已经习惯了,不会那么容易恐惧了。这是练习的结果。

纪录片中有一个细节,在Alex成功攀登上酋长峰以后,有人问他:“你下午怎么安排?”正常人的回答,要么是说开个Party,庆祝一下,要么是赶紧回家,休息一下。但是Alex的回答是:“我要回拖车,继续引体向上。”你看,八年辛苦训练,一朝成功,一般人肯定是狂喜啊,但是Alex居然都没有一点情绪上的波动。连行为方式上的波动都没有,他还是要回去引体向上。他把自己的情绪已经控制到这种程度。

下面就要说到,我看这部纪录片受到的启发了。

我的启发,其实不仅是训练的重要性。而是一个人成为高手,到底意味着什么?

过去,我们总是觉得,高手,就是获得了自由。别人做不到的,他们做到了。所以他们可以享受更多的随心所欲。

但是,看着Alex攀岩的过程,我突然意识到:不对。高手不是享受更多的自由。恰恰是反过来的,高手是看到了更多的限制。

Alex长期的训练,不只是做到动作熟练而已。他实际上是在感知一个个的限制。这条路线只能这么设计、这块石头只能用这个姿势踩、这个地方的手脚挪动只能按照这个顺序。914米的成功攀登,每一步、每一秒,都是被各种维度的限制规定出来的。这里面哪有什么自由?哪有什么随心所欲?

我举个生活中的例子你就明白了。

比如,我家里要买一个新窗帘,如果不是专业的家居设计师,我只能说,我喜欢哪个颜色的窗帘,能接受的价格区间是什么。但是如果换成专业的家居设计师呢?他会意识到各种维度的限制。比如颜色、材质、式样、材质式样和墙面的配合、不同光照条件下的效果、好不好拆卸、好不好洗涤、耐不耐脏。

你看,专业和业余的区别,不是他更自由,而是他更受限制。所以我一个普通人进到窗帘市场,觉得到处都是选择,而一个专业的家居设计师面对上万个窗帘,可能会觉得,几乎没得选。

认证机制JWT的应用

几种常见的认证机制

HTTP Basic Auth

最简单最基础的验证方式。
简单点说明就是每次请求API时都提供用户的username和password。

OAuth

无需将用户名和密码提供给第三方应用。
OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。
OAuth2.0的流程:

Cookie Auth

不支持跨域
Cookie认证机制就是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象;通过客户端带上 来Cookie对象来与服务器端的session对象匹配来实现状态管理的。默认的,当我们关闭浏览器的时候,cookie会被删除。但可以通过修改 cookie 的expire time使cookie在一定时间内有效;

Token Auth

支持跨域访问
更适用CDN
缺点 一旦颁发token就无法收回权限,但可以用后端逻辑来控制token的权限,比如利用有效期。

基于JWT的Token认证机制实现

  JSON Web Token(JWT)是一个非常轻巧的规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。它是基于RFC 7519标准定义的一种可以安全传输的小巧和自包含的JSON对象。由于数据是使用数字签名的,所以是可信任的和安全的。JWT可以使用HMAC算法对secret进行加密或者使用RSA的公钥私钥对其进行签名。

验证流程如图:

基于PHP的实现:
demo代码地址
https://dev.tencent.com/u/xuxiao8/p/88/git
部分实现代码如下:

<?php 
date_default_timezone_set("PRC");   //系统使用北京时间

require 'vendor/autoload.php';

use \Firebase\JWT\JWT;

define('KEY', '1gHuiop975cdashyex9Ud23ldsvm2Xq');
// php CROS 跨域解決方案

// header('content-type:application:json;charset=utf8');
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:PUT,POST,GET,DELETE,OPTIONS');
header('Access-Control-Allow-Headers:x-requested-with,content-type,X-token');

$res['result'] = 'failed';

$action = isset($_GET['action']) ? $_GET['action'] : '';

if ($action == 'login') {
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        $username = htmlentities($_POST['user']);
        $password = htmlentities($_POST['pass']);

        if ($username == 'demo' && $password == 'demo') { //用户名和密码正确,则签发tokon
            $nowtime = time();
            $token = [
                // 'iss' => 'http://192.168.1.214', //签发者 可选
                // 'aud' => 'http://192.168.1.214', //jwt所面向的用户 可选
                'iat' => $nowtime, //签发时间 可选
                // 'nbf' => $nowtime + 10, //在什么时间之后该jwt才可用 可选
                'exp' => $nowtime + 20, //过期时间20秒 可选
                'data' => [
                    'userid' => 1,
                    'username' => $username
                ]
            ];
            $jwt = JWT::encode($token, KEY);
            $res['result'] = 'success';
            $res['jwt'] = $jwt;
        } else {
            $res['msg'] = '用户名或密码错误!';
        }
    }
    echo json_encode($res);

} else {
    $jwt = isset($_SERVER['HTTP_X_TOKEN']) ? $_SERVER['HTTP_X_TOKEN'] : '';
    if (empty($jwt)) {
        $res['msg'] = 'You do not have permission to access.';
        echo json_encode($res);
        exit;
    }

    try {
        JWT::$leeway = 60; //当前时间减去60,把时间留点余地
        $decoded = JWT::decode($jwt, KEY, ['HS256']);
        $arr = (array)$decoded;
        if ($arr['exp'] < time()) {
            $res['msg'] = '请重新登录';
        } else {
            $res['result'] = 'success';
            $res['info'] = $arr;
        }
    } catch (\Firebase\JWT\SignatureInvalidException $e) {
        //签名不正确
        $res['msg'] = $e->getMessage();
    } catch (\Firebase\JWT\BeforeValidException $e) {
        // 签名在某个时间点之后才能用
        $res['msg'] = $e->getMessage();
    } catch (\Firebase\JWT\ExpiredException $e) {
        // token过期
        $res['msg'] = $e->getMessage();
    } catch (Exception $e) {
        //其他错误
        $res['msg'] = $e->getMessage();
    }

    echo json_encode($res);
}

JS的宏任务和微任务

机制如下:



宏任务后的微任务队列执行完后执行下一个宏任务;

宏任务

  • I/O,事件队列中的每一个事件都是一个macrotask
  • setTimeout / setInterval
  • MessageChannel是通信渠道API,ie11以上和其它浏览器支持。
  • setImmediate 目前只有IE10以上实现了该方法其它浏览器不支持.作用回调功能,node支持。
  • requestAnimationFrame 也算宏任务 node不支持。

微任务包括

  • Promise.then catch finally
  • MutationObserver 浏览器支持 IE11以上 node不支持,它会在指定的DOM发生变化时被调用
  • process.nextTick 浏览器不支持 node支持

async函数在await之前的代码都是同步执行的

案例

async function async1() {
    console.log("async1start");
    await async2();
    console.log("async1end")
}
async function async2() {
    console.log("async2")
}
console.log("scriptstart");
setTimeout(function () {
    console.log("setTimeout")
},0);
async1();
new Promise(function (resolve) {
    console.log("promise1");
    resolve()
}).then(function () {
    console.log("promise2")
});
console.log("scriptend");
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout

正向代理与反向代理

看图

正向代理

应用场景:

  1. 隐藏客户端身份,翻墙访问google
  2. 可以做缓存,加速访问资源
  3. 对客户端访问授权,上网进行认证
  4. 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

反向代理

应用场景:

  1. 负载均衡
  2. 保证内网安全
  3. 解决跨域问题

FullCalendar中文汉化

FullCalendar中文汉化

            $('#calendar').fullCalendar({
                buttonText: {
                    today: '今天',
                    month: '月',
                    week: '周',
                    day: '日'
                },
                allDayText: "全天",
                timeFormat:'H(:mm)',
                views: {
                    month: {titleFormat: 'YYYY MMMM'},
                    week: {titleFormat: 'YYYY MMMM'},
                    day: {titleFormat: 'YYYY MMMM D'}
                },
                monthNames: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
                monthNamesShort: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
                dayNames: ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
                dayNamesShort: ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                defaultDate: '2018-03-12',
                navLinks: false, // can click day/week names to navigate views
                editable: false,
                eventLimit: true, // allow "more" link when too many events
                events: []
            });