编辑
2022-11-11
Markdown
00

CloudFlare+githubpages 配置

1.概述

1.1CDN简介

关于 CDN 是什么,我想应该不用做过多的介绍,毕竟现在是一个 “云” 的时代,你至少也听说过 阿里云 或者 腾讯云 吧,当然其中就包括 CDN 业务。

CDN 的作用有很多,比如可以用来加速网站的访问,可以用来防护网站等。本篇文章讨论的就是使用 cloudflare 作为 CDN 来加速博客网站,并让博客开启 https,提升博客安全等级。

由于 GitHub Pages 在国外,而且有时候因为图片过多等原因,静态博客页面在国内访问速度可能会非常慢,我们可以用 CDN 来加速,选择 CDN,对于个人来说,主要考虑的还是访问速度以及价格,既免费又快的 CDN就最好了。经过一番寻找,发现 Cloudflare 免费版速度还可以,而且配置起来非常简单,所以在此选用 CloudFlare CDN 来加速页面访问。也就是说,借用了cloudflare免费提供的serveless服务:workers。搭建一个反向代理。

反向代理的话相当于是我们的节点代替github pages接受了客户端的请求,所以其实我们只需要做两件事:

  1. 接收客户端的请求,对其进行必要的修改之后发送给真正的服务端(github pages)。这些修改主要是针对一些headers的设置,包括替换Host地址,允许任意源头资源共享(access-control-allow-origin: *)等,具体见代码。
  2. 接收服务端的响应,同样地我们需要对响应的内容做一些修改再发送给客户端的浏览器。这部分主要是把响应中所有的github pages出现的部分改换成workers站点的url,否则我们的客户端就获取这些信息之后下一次就会直接访问github pages源站了。这一步可以通过简单的文本查找和替换来实现,我们可以维护一个替换对字典,对响应的内容进行正则查找替换后把响应发送给客户端。
编辑
2022-11-08
00

一、树的概念和结构

1.1树的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合(n=0 时称为空树)。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。

  • 有一个特殊的结点,称为根结点,根节点没有前驱结点。
  • 除根节点外,其余结点被分成几个互不相交的集合,每个集合又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。
  • 因此,树是递归定义的。

如下图,A为整个树的根节点。而B,C,D可以看做子树的根节点,在下面分别长出三棵子树。

image-20221013090611615

1.2树的逻辑结构

树的逻辑结构表示有:树状表示法,文氏图表示法,凹入表示法和括号表示法。

1.2.1树状表示法

树是最基本的逻辑结构表示法,使用一棵树倒置表示,非常直观。

image-20221013091243522

1.2.2文氏图标表示法

使用集合以及集合包含关系描述树结构。

image-20221013091337123

1.2.3凹入表示法

使用线段的伸缩的关系描述树结构。

image-20221013091429524

1.2.4括号表示法

将树的根结点写在括号的左边,除根结点之外的其余结点写在括号中,并用逗号分隔。

image-20221013091633741

1.3 树的一些专业术语

节点:树的数据元素。 叶节点和终端节点:度为零的节点(除根节点外,分支节点也称为内部节点)。 终端节点或分支节点:度不为0的节点。 双亲结点或父节点:上层的那个节点,也是直接的前驱。如图,C为G的父节点。 孩子节点或子节点:下层的节点的子树,也是直接后继。如图,G为C的子节点。 兄弟节点:拥有相同父节点(同一双亲下的同一层)的节点称为兄弟节点。 堂兄弟节点:双亲位于同一层的节点,但是并非同一个双亲。 节点的度:一个节点含有的子节点的个数称为该节点的度,有几个直接的后继就是几个度 ,也称为次数。 树的度:一棵树中最大的节点的度称为树的度。 树的高度或深度:树中节点的最大层次,如图,高度为4。 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推。 祖先:从跟到该节点所经分支上的所有节点。A是所有节点的祖先。 子孙:该节点下层子树中的任意一个节点。 森林:由m(m>0)棵互不相交的树的集合称为森林。 有序树:节点各个子树从左到右有顺序关系,也称为自由树,不能互换。 无序树:与有序树相反,可以互换的。 二叉树:每个节点最多含有两个子树的树称为二叉树。 完全二叉树:叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。

image-20221013091841786

1.4树的性质

性质一:树中结点数等于所有结点的度数加一 根据树的定义,在一棵树中,除根结点以外,每个结点有且仅有一个直接前驱,也就是说,每个结点与指向它的 一个分支一一对应,所以,除根结点以外的结点数等于所有结点的分支数(即度数),而根结点无直接前驱,因此,还要加一。 性质二:度为m的树中第i层上至多有m的(i-1)次方个结点((m^i-1)i大于等于1) 性质三:高度为h的m次树至多有(m^h)-1除以(m-1)

1.5树的表示法

利用顺序存储和链式存储的特点,完全可以实现对树的存储结构的表示。介绍三种不同的表示法:双亲表示法、孩子表示法、孩子兄弟表示法。

1.5.1双亲表示法

我们假设以一段连续空间存储树的结点,同时在每个结点中,附设一个指示器指示其双亲结点到链表中的位置。也就是说,每个结点除了直到自己是谁外,还要直到自己的双亲在哪里。就像

dataparent

其中data就是数据域,存储结点的信息。而parent是指针域,存储该结点的双亲在数组中的下标。 双亲表示法的结点结构定义代码:

//树的双亲表示法结点结构定义 #define MAX_TREE_SIZE 100 typedef int TElemType; //树结点的数据类型,目前暂定整形 typedef struct PTNode{ //结点结构 TElemType data; //结点数据域 int parent; //双亲位置 }PTNode; typedef struct{ //树结构 PTNode nodes[MAX_TREE_SIZE]; //结点数组 int r,n; //根节点的位置和结点数 }

有了这样的结构定义,我们就可以实现双亲定义法了。由于跟结点没有双亲,所以我们约定根结点的位置域设置为-1,这就意味着,我们所有结点都直到他双亲的位置。如图为树结构和双亲表示法的图表。

image-20221013092815824

我们可以通过上面快速的找到结点的双亲。但是我们要知道结点的孩子只有遍历整个结构了。

1.5.2孩子表示法

换一种完全不同的想法。由于树中每个结点可能有很多的子树,可以考虑用多重链表,即每一个结点有多个指针域,其中每个指针指向一个子树的根节点,我们把这种方法叫做多重链表表示法。不过,树的每个结点的度,也就是它孩子个数是不同的。所以可以设计两种方案来解决。

  • 方案一

指针域的个数等于树的度。

image-20221013093016781

如图,data就是数据域,child1····是指针域,用来指向该结点的孩子结点。

以1.5.1中的树结构为例来实现。

image-20221013093240974

我们可以看到。^这个符号就是代表当前这个指针域并没有用到。这样如果树的各结点的度差距过大的话,显然非常浪费空间。按需分配空间显然更好,这样就有第二种方案了。

  • 方案二

每个结点指针域的个数等于该结点的度,我们专门来取一个位置来存储结点指针域的个数。如图。

image-20221013093415543

如图,data就是数据域。degree是度域,也就是存在该结点的孩子结点数。child1····是指针域,用来指向该结点的孩子结点。

那么对应的树图就应该是这样。

image-20221013093532615

显然,方案二克服了浪费空间的缺点,但是由于各个结点的链表结构是不相同的,在加上要维护结点的度的数值,在运算上显然有损耗。 能否有更好的方法?既可以减少浪费,又能使结点结构相同。

我们把每一个结点放入顺序存储结构中是合理的,但是每个结点的孩子多少是不确定的,所以我们再对每个结点的孩子建立一个单链表来体现他们的关系。这就是我们的孩子表示法

具体办法:把每个结点的孩子排列起来,以单链表作存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为空。然后n个头指针有组成一个线性表,采用顺序存储结构,存进一个一维数组。如图。

image-20221013093648966

为此,设计两种结构,一个是孩子链表的孩子结点。

image-20221013093730770

child是数据域,存储某个结点在表头数组中的下标。next是指针域,用来存储某结点的下一孩子结点的指针。

另一个是表头数组的表头结点。

image-20221013093803483

data是数据域,存储某结点的数据信息。firstchild是头指针域,存储该节点的孩子链表的头指针。

以下是孩子表示法的结构定义代码。

//树的孩子表示法结点结构定义 #define MAX_TREE_SIZE 100 typedef int TElemType; //树结点的数据类型,目前暂定整形 typedef struct CTNode{ //孩子结点 int child; struct CTNode * next; }*ChildPtr; typedef struct{ //表头结构 TElemType data; ChildPtr firstchild; }CTBox; typedef struct{ //树结构 CTBox nodes[MAX_TREE_SIZE]; //结点数组 int r,n; //根节点的位置和结点数 }

我们可以改进一下。把双亲表示法和孩子表示法综合一下,加一个双亲域。如图。(双亲孩子表示法)

image-20221013093942008

1.5.3孩子兄弟表示法

任何一棵树,它的结点的第一个孩子如果是唯一的,它的右兄弟如果存在也是唯一的,因此,我们设置两个指针,分别指向该结点的第一个孩子和此结点的右兄弟。

结点结构如图。

image-20221013094030339

data是数据域,firstchild为指针域,存储第一个孩子结点的地址,rightsib是指针域,存储该结点的右兄弟的地址。

结构定义代码如下.

//树的孩子兄弟表示法结构定义 typedef struct CSNode{ TElemType data; struct CSNode *firstchild,*rightsib; }CSNode,*CSTree;

仍然以1.5.1的树为例,这种方法实现的示意图如图。

image-20221013094149781

这种方法给查找某结点的某个孩子带来了方便,只需要通过firstchild 找到此结点的左儿子,然后再通过左儿子找到二弟,一直下去,知道找到具体的孩子。当然,如果想要找到双亲,完全可以增加一个parent 指针域来解决。

编辑
2022-11-07
学习
00

1.为什么需要权限管理

日常工作中权限的问题时时刻刻伴随着我们,程序员新入职一家公司需要找人开通各种权限,比如网络连接的权限、编码下载提交的权限、监控平台登录的权限、运营平台查数据的权限等等。

在很多时候我们会觉得这么多繁杂的申请给工作带来不便,并且如果突然想要查一些数据,发现没有申请过权限,需要再走审批流程,时间拉得会很长。那为什么还需要这么严格的权限管理呢?

举个例子,一家支付公司有运营后台,运营后台可以查到所有的商户信息,法人代表信息,交易信息以及费率配置信息,如果我们把这些信息不加筛选都给到公司的每一个小伙伴,那么跑市场的都可以操作商家的费率信息,如果一个不小心把费率改了会造成巨大的损失。

又比如商户的信息都是非常隐秘的,有些居心不良的小伙伴把这些信息拿出来卖给商家的竞争对手,会给商家造成严重的不良后果。虽然这么做都是个别人人为的过错,但是制度上如果本身这些信息不开放出来就能在很大程度上避免违法乱纪的事情发生了。

总体来讲**权限管理是公司数据安全的重要保证,针对不同的岗位,不同的级别看到的数据是不一样的,操作数据的限制也是不一样的。**比如涉及到资金的信息只开放给财务的相关岗位,涉及到配置的信息只开放给运营的相关岗位,这样各司其职能避免很多不必要的安全问题。

如何让各个岗位的人在系统上各司其职,就是权限管理要解决的问题。

编辑
2022-09-09
教程
00

白嫖 IBM LinuxOne 教程

1.介绍

1.1前言

LinuxONE Community Cloud是IBM联合Marist大学为学生提供的用于测试应用程序和网站的平台,提供长达120天的免费VPS。

编辑
2022-09-05
教程
00

Typora使用教程

1.前言

一次偶然的机会,让我接触到了 .md 文档,进而开始摸索,并意外结识了 Typora 这个编辑器。

百度解释:Typora 是一款由 Abner Lee 开发的轻量级 Markdown 编辑器,与其他 Markdown 编辑器不同的是,Typora 没有采用源代码和预览双栏显示的方式,而是采用所见即所得的编辑方式,实现了即时预览的功能,但也可切换至源代码编辑模式.

也确实如此。Typora 是一款轻便简洁的 Markdown 编辑器,支持即时渲染技术,这也是与其他Markdown编辑器最显著的区别。即时渲染使得你写 Markdown 就像是写Word文档一样流畅自如。个人认为是一款很好用的 MarkDown 编辑器,特来分享给大家❤️