怎样变得更快乐

随理解持续更新

玩游戏

玩到一定程度会觉得厌倦,但没有玩的时候却具有吸引力。游戏过程不一定多好玩,但MOBA类游戏容易进入状态,可以减少烦恼。

娱乐节目

脱口秀、综艺、电视剧、情景剧等。

充足的睡眠&合理的作息

晚上如果没有休息好,第二天很容易疲倦不堪。

(更多…)

QQ互联的注意事项

业务逻辑

最近试了一下用QQ登陆联系原有的账户体系,由于用了LeanCloud提供的后台服务,我只用关心QQ互联的部分。

首先,它的业务逻辑是:你先设置一个按钮,要跳转到QQ登陆页面,登陆完成后跳转到回调页面。回调页面即可以是用户主页也可以是一个中间页面用于跳转。

在PC上,曾经常见的模式是弹出QQ登陆小窗,登陆后原页面收到登陆成功的回调更新登陆状态。

但以上的方式如果在移动端使用,由于没有回调地址,唤起QQ登陆后无法跳转到用户界面,并且原页面也不会收到回调。

所以现在有一个模式,就是点击QQ登陆后原页面直接跳转到QQ登陆页面,登陆成功后回调地址收到accessToken与openId,之后再处理业务逻辑。

OAuth 2.0

A->B->C->D->E
先获取Code,然后再获得Token,重定向URI必须保持一致

现在你可以用他们的API来实现以上功能,比如QQ互联提供了QQ登陆地址的格式,通过Authorization获取AccessToken,通过AccessToken获取openId的接口,以及getUserInfo等api的接口。但我尝试后发现这些api没有设置跨域头,如果直接在前端获取会被浏览器拦截,因此我选择用他们的PHP SDK。

PHP SDK

SDK使用虽然很方便,但还是没有设置跨域头,你需要在页面输出前设置Access-Allow-Control-Origin。还没完,PHP SDK使用了session,不能像官方的获取用户信息的api一样直接请求,你还需要设置Access-Alllow-Control-Credentials,在前端请求时如果用AXIOS,也要加上withCredentials的配置。

由于我习惯把不涉及安全业务逻辑放到前端,所以我在callback.php里将AccessToken与OpenId传给前端的Login组件,由前端请求后判断是否是新用户等等。(也由于使用了LeanCloud,php并不能直接查数据库,所以干脆放在前端)

JS SDK

QQ互联我花了不少时间,主要是理解它的业务逻辑,还有跨域的问题。我开始用的是JS SDK,但似乎它已年久失修(12年更新过),而且它要求用script标签引入,我在前端还要检查SDK对象是否已加载完成,让我的代码很混乱,加上还是要后端协助解决跨域,所以还是不用了。

PHP&CURL 小插曲

其实还有一个小插曲,PHP SDK需要curl,但我安装的php 7.3 似乎并编译不上,而且php7.2-curl都是有的,但php7.3-curl还没有。。。只好换成7.2。

A-star寻路记

前段时间研究小游戏的同学用过A*算法寻路,当时我只是有个印象,恰巧最近有同学做数模问我,我也只能硬着头皮看一看了。先声明,太low或者有差错也不管哈。

题目要求

给定一个n*n的地图,其中有障碍物和跨越难度各不相同的地形,现要求找到总代价最小的路径。

如果光溜溜地摆出地图,要凭空想出一个方法挺难的,而且最重要的是复杂度也许很高。但我们有a-star。

启发式算法

这个名词大家一定不陌生,但对它的含义可能一知半解。常见的启发式算法如模拟退火算法、神经网络、蚁群算法等,它们在面对最优化问题时,并不从某个精妙的逻辑出发(像数学证明那样),而是以直观的感受构建算法,消耗有限的时间和空间尽量得到接近最优的可行解(但通常无法证明)。

A-star

直观地讲,你要找最小路径,那只能从出发点开始,一步步地试出来,不过呢,复杂度不仅达到了n次方,还有可能存在回路。A-star算法提供的解决方案是,用两张表分别存储被考虑用来寻找最短路径的区块(open)与不再考虑用来寻找最短路径的区块(closed),同时启发式算法能保证尽量选择较优的路径。

“代价”优先搜索

最基础的,从起始点出发,每次从open表中选总代价最小的项(F最小),向周围8个方向前进(将这些区块加入open表),这是A-star的主循环。

剪枝

新遇到的区块可以加入open列表,但扫描后的点会加入closed列表。

路径

搜索的路径需要被记录,可以用一个栈结构,从open列表进入时入栈,如果一个区块周围不再有符合要求的区块则回退。

要求

不能在closed表中,不能超出边界,不能是建筑,如果已在open列表,当前G值大于open表中记录的G值也不符合要求。

启发式

F=G+H

F即总代价,包括G实际经过的路程和H估算的该点离终点的距离。

估计路径

可以直接用笛卡尔距离,也可以直线+拐弯etc,总之提供一个大概的参考值。

JavaScript实现

等等,还没写

一直在想脚手架

最初用的就是vue-cli,但每次都是向导式的配置,很不透明,希望能从尽量简单的系统开始研究。然后就发现了poi。

vue-cli创建好的项目不仅配置好了代码检查、babel、ts、css预处理等功能,还带一个目录结构,即main.js、App.vue等。

poi创建好的项目目录是空的,我可以稍微做两步。比如新建一个js文件,然后createElement,appendChild,再启动dev-server,我一下就明白了入口文件(entry)是什么意思(虽然以前也明白,但理解方式不同),那就是编译好的代码从这里执行,打包的时候,如果用到了某个模块,在引入的时候,那个模块的代码就会执行,但这个模块导出的东西可以在之后用,循环引用时模块可能不会被编译到最终的文件等等。

然后是Vue的使用,如果用Vue-cli,那么就不会注意到main.js里的new Vue,实际上这里新建了一个根实例,并且挂载到一个html元素上($mount)。它的render属性是一个函数,接受一个渲染函数h,并且返回h(App),App是引入的一个vue组件(被vue-loader从vue文件编译成了js)。为什么用render而不用template呢,因为vue通常用runtime版本的,不带编译模板的功能,需要build时编译好(编译vue文件),如果用template的话,main.js或index.js又不会被编译,所以就会出错。所以可以引入vue.esm,也可以自己写渲染函数,也可以引入一个vue组件,再在vue组件内引用别的文件。

计网实验操作记录

DHCP

在config模式下新建地址池 ip dhcp pool xxx

在dhcp-config模式下设置地址范围和子网掩码,network x.x.x.x 255.255.255.0

在dhcp-congfig模式下设置默认网关与dns,default-router x.x.x.x与dns-server x.x.x.x(不必要)

然后开启相应端口,连接交换机即可自动分配ip,记住dhcp地址池排除网关,config模式下,ip dhcp excluded-address x.x.x.x

不能自动分配

可能是接口的子网掩码设置不对

单区域OSPF

对相互连接的路由器,先在config模式下,router ospf xxx 启动ospf进程,xxx是区域id,比如1,同一区域内应一致

此时处于config-router模式,先设置唯一的路由器id,router-id xxx

继续在此模式下添加所有的网络(端口ip)和子网掩码(你可以直接写0.0.0.0)network x.x.x.x x.x.x.x area 0

RIP

直接在routing的rip选项卡添加连接的网络

STATIC

直接在routing的static选项卡添加记录

路由重发布

多种协议间相互学习,中间的路由器同时运行多种协议,重发布使不同协议可以相互学习,连通不同网络。

比如先router rip,然后redistribute ospf 1(ospf的id) metric 10

移动端Safari对z-index与绝对定位的不佳处理

我尝试用z-index和绝对定位结合做一个时光轴,但在IOS设备上的表现很差:尽管我滑动了页面,时光轴相对屏幕的位置仍然不变(但时光轴的父元素已经设定了relative)。这还和放在overflow:scroll容器里有关,总之满足以上3点才会100%触发这个bug。我不清楚web标准是否应该这么呈现,但估计是Safari自身的原因。说不定是因为内容放在了容器里,容器内的scroll不会触发safari对这种元素重新渲染。

解决方案就不用z-index,通过改变元素在html中的排列顺序实现z-index的效果(同一级元素中后面的元素会覆盖前面的元素)。