愿你出走半生,归来仍是少年。

我眼中的元宇宙

莫说当下最流行的什么?莫过于元宇宙了,自从2021年10月28日,机器人马克扎克伯格将facebook改名meta,进军元宇宙,引起了全球关注,【元宇宙】这个词又火了起来。

其实互联网大概每2-3年就会有一个新风口,在2015年就有伪风口,VR、AR、MR,我统称为虚拟现实,但直到现在,还是不温不火的,我一直很看好这个风口,很火起来着实让我无语了,可能是那个时候技术还不成熟吧,但现在随着技术发展,很多歌手通过AR技术隔空对唱,让我看到了当年触摸屏的影子。

触摸屏还未普及的时候,你只能在电视媒体上看到它的样子。很多先进的技术,往往都是少部分人先使用,例如大哥大,汽车,触摸屏技术,然后越来越多的商人加入,从而竞争,从而普及,所以虚拟现实绝对会越来越普及,会走进千家万户,走进每个人的生活,以后通话估计都是虚拟现实。只是时间的问题了。

目前大家都在炒元宇宙房地产,动不动炒到几千万,其实商人逐利无可厚非,但是老是割韭菜,非蠢即坏,能成为一名商人,不可能蠢,所以只能是坏了。

随着时代的发展,人类面临着很多困难,也有2个大方向,一个是星辰大海,一个是虚拟世界,类似于黑客帝国和头号玩家。

星辰大海先不说,有火星移民计划,也有开普勒-452b等待探索,马斯克也已经在计划了。

很有意思的是,马斯克也在研发脑机,这个可操作空间太大了,人可以直接与互联网对接,实现无限可能。

先来说一说我眼中的元宇宙吧。他需要具备以下条件:

1、这个宇宙不是某一个公司,某一个国家去控制的。

2、货币是唯一的,不能通货膨胀,也是无国界的。比特币就很适合。

3、地图是无限大,可以扩充的,用浩瀚无边来形容才合适。

4、元宇宙肯定是多样的,不单单是未来的样子,而应该是由全世界的开发公司去丰富这个生态圈,可以有古希腊风格、唐朝风格等等。

要达到这些条件,更应该是由世界各国互联网巨头成立一个联盟,共同组建研发团队,去研发基建,相当于入口,是相当挣钱的,例如一些用户的基本信息,安全管理,提供统一标准接口,类似于usb接口。

后续如果有人想加入这个联盟去维护这个基础,需要开会投票决定。类似于现在的世贸组织,五常等,并不是一般的组织或公司能进入的。

如果有公司想做元宇宙,只需要申请对接这些标准接口,我们统称为开发商,不管开发商研发是古代风格的世界,还是未来风格,这些都不是问题,只要他能够吸引用户进入,这些就是流量,有流量,你里面的东西才值钱。

这样做的话,就类似于游戏中的副本,游戏中的每个服,也好像是王者荣耀中的每个区,他们的数据可以互通,也可以不互通,因为货币是统一的。所以用户可以去任意一个风格世界。

想想一下,用户在基础界面创建用户角色后,可以自由选择去网易开发的唐朝,也可以选择去腾讯开发的三国,当然也可以选择阿里开发的未来世界。

当你选择一个地方后,里面提供吃喝玩乐,你看中了一个家居,总不能随时带在身上吧,所以这个时候由开发商提供房子出售,把这些虚拟物品放到自己的房子内,其实就是游戏中的包裹。

例如网易开发的世界是唐朝风格,我们称之为唐城,那些互联网公司或个人想挣钱,可以申请网易提供的接口,开发游戏类的,这样就类似于线下的商户,个人是没有开发能力,可以由这些互联网公司提供一些基础功能,好比现实中出租、出售软件,也可以定制一些功能。

如果这样发展的话,世界才是无限可能。

写在最后的话:

1、机器人马克扎克伯格,娶了中国媳妇,然后来中国晨跑,收获很多好评,后来在听证会上诋毁中国,均是商人逐利,一场作秀。

2、尤记得奥巴马竞选,我的很多朋友在QQ空间里欢欣鼓舞,也在热血沸腾,结果又怎样了呢?

其实我想说的是:任他风起云涌,努力挣钱才是上策,挣到钱后能解决80%的烦恼,日常生活的吵闹大部分基于此,有多少情侣败在了柴米油盐上,又有谁想一地鸡毛?也只有挣到钱后,才有能力去帮忙更多的贫困的人,去捐助那些上不起学的人。

当元宇宙真的来临,现实中怎样,在元宇宙也会怎样,如果现实贫穷,元宇宙翻身的机会也不会太大,正如游戏氪金,有钱可以使你更强,皮肤更好看。

所以,那些国家大事,与你我无瓜,搞钱才是王道。

未来已来,你准备好了吗?

牢骚之下

白云苍狗,当我静下心来回顾我的前半生,想一想经历了什么?

很多时候,不要自己觉得,而是多以第三视角,跳出这个圈,好好看一看,去对自己的言行、经历去复盘。

才发现,没啥大事,儿时的记忆已渐渐模糊了,我已记不起去年的今天发现了什么,唯有平庸二字来诠释吧,细思极恐,当我耋耄之年,我又能记得起哪些?是否只有刻骨铭心才依稀记得。

是否在为平庸的一生而忏悔?也是否在轮回前,苦苦求那再来一次的机会,如果有的话。

所以我最近都在告诉自己,多拍照,不管好的坏的,记录下来,无论贫贱富贵,时间是公平的。

也在告诉自己,多写写日记,不管欢喜的还是悲伤的。

孩童时代顽皮,学校时代懵懂,步入社会后呢,慢慢的磨平了菱角,曾经我也热血,我也憧憬,我也向往。

但是一次次碰壁,一次次失望,总是会失去耐心的,当能力匹配不上野心的时候,就会自怨自艾,在求活中透露出许许无奈吧。

或者这是大多数人的烦恼吧。在这芸芸众生中,我也不例外。

十年之前,我在老家,思考着我该去哪座城市施展我的抱负。

在北上广深四座城市抉择

北京:首都,太多的高学历人才,冬天风暴肆虐;

上海:比较排外,天气跟江西老家差不多;

广州:主要是讲白话,也是比较排外;

深圳:一座年轻的城市,基本都是外地人,年轻人有朝气,机会不比北上广差。

所以我怀揣着梦想选择了深圳,深圳有十个区,我在这些区域四处流浪,也没有安放下我的灵魂。

如果再选一次,我是否还会选择深圳?

年少的我,工作干的不顺利就会辞职,看见同事辞职,竟然也有辞职的冲动。

在跌跌撞撞中,步入不惑之年,在颠沛中,满脸风霜。成了其他人眼中的中年大叔。

曾经幻想的一屋二人三餐四季,也是遥不可及,想想还是有些可悲啊。

对于目前的自己,假想一下,如果碰见另一个一模一样的自己,是否觉得这个人还好。

我想了良久,其实觉得不太行,干啥啥不行,脾气还古怪,恨不得打死自己啊。

连自己都觉得接受不了,何况是其他人呢?

所以,我在想,我自己该活成什么样?

我在想,我的未来又该如何规划?

我在想,我该何去何从?

听闻王力宏离婚,有感而发

这1-2日王力宏曝出离婚消息,原因是婆媳不和,结束了8年爱情婚姻,查了下他老婆的信息,也是个学霸,曾在摩根大通咨询服务部门担任助理副总裁,还在爱马仕、雅诗兰黛等企业工作过,主要从事奢侈品的运营和管理。

在微博上秀恩爱也成为了过去式。自此一别二宽,欢不欢喜就不得而知了,或者曾经也有山盟和海誓,8年说长不长,说短其实也不短,可惜了这一对。

在高中时代,从杂志上了解了周杰伦,林俊杰、王力宏,很多歌也是我蛮喜欢的,《改变自己》、《需要人陪》、《大城小爱》、《龙的传人》等等。

其实无论是明星还是常人,身价亿万富翁还是穷困潦倒,婚姻这件事也无法称心如意吧!

在现实中,又有多少人,走着走着就散了,时间能消磨一切,腐蚀了爱情,冲淡了感情,多想一想初心,以及当初走在一起的不容易吧。世界有70多亿人,相遇的概率是0.00487,相识的概率是0.0000005,相爱的概率是0.000000003。这概率是多么的小。

在网易新闻看到王力宏离婚相关的新闻,文章中说浙江省全省法院曾经一年处理过近5万起离婚官司后得出一个数据,离婚原因排名第一的并不是我们普遍认为的出轨,家暴等,而是不起眼的生活琐事,占的比例高达34.21%。这比例又是多么高的可怕。

有人说,爱情很简单,你喜欢我,我喜欢你,就足够了,但是婚姻就复杂得多了,完全不同的家庭,培养出完全不同生活习惯的两个人,需要在同一个屋檐底下慢慢磨合。你看不惯我乱扔袜子,我看不惯你有生活洁癖,你看不惯我迷恋游戏,我无法理解你对偶像剧的痴迷。时间久了,就会把缺点放大,
慢慢的变成争吵,然后爆发。曾经相互喜欢的人,成了伤害最深的那个人。其实如果不想被拒绝,那就先拒绝别人。如果不靠近,谁又伤的了自己呢?所以,我在修:修一场无欲无求,我在等:等一个相知相守的那个人。

很多人恐婚,这真的很正常,毕竟现在节奏那么快,离婚率那么高,身边的很多人都过的不幸福,那更会加深这种恐惧,难道不结婚?孤独终老吗?

有的人问:结婚是为了什么?2个不同性格的人在一起,背后是2个家庭,是束缚,是失去了自由。身边的好几个已婚朋友说:其实结婚没有你想的那么好,很多事很烦,还不如一个人。

我也在问自己,我未来的另一半是怎么样的?她性格怎么样?能否永远忽略她的缺点?也能否包容她的小脾气?

我想了很久,很久,然后告诉自己,多想想她的好,其实她也是一位小可爱,在她父母的眼中也是宝啊,先走出第一步,认识她,包容她,控制自己的脾气,毕竟一个女孩子相信你,才愿跟你在一起,走进一个陌生的家庭,或许这就是爱情的力量,换位思考,如果是男人上门,走进女人的家,是否也是一样的心理呢?

把初心和当初在一起的激情刻在内心深处,并常常唤醒它。

天下也不是所有的夫妻最后都分崩离析,那些恩恩爱爱白头偕老的,不过就是你付出一点,我付出一点,你退让一点,我退让一点,只有用心经营的夫妻,才能抵得过生活中的柴米油盐,才不会一地鸡毛。

愿有情人携手白头,把生活过好!

惜我者,我惜之; 嫌我者,我弃之。 懂我者,我幸之; 爱我者,我爱之!

最后,想起了一个笑话。

一位老奶奶推着老爷爷,老爷爷对老奶奶说:“宝贝,你真好。”

记者感觉好温馨,走上前去问老奶奶:“怎么保持这一辈子爱呢?”

老奶奶说:“以前他有外遇,一度想抛弃我。”

记者问:“你是怎么做的?”

老奶奶:“这不,我把他腿打断了!”

记者接着问大爷:“您都八十多了,还叫老伴儿宝贝儿,请问您是怎么做的?”

大爷:“别提了,前几年就忘了她叫啥名了,也不敢问,怕她弄死我……”

docker/ssh

一、先安装docker

这个很简单,因为我的系统是win10,我安装的是Docker Desktop,最好是更改一下docker镜像

二、运行docker,并用docker安装centos系统

先看以下命令会不会报错

$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.4, build 8d51620a
docker pull centos   <----执行这行,拉取镜像

Using default tag: latest
latest: Pulling from library/centos
8a29a15cefae: Already exists
Digest: sha256:fe8d824220415eed5477b63addf40fb06c3b049404242b31982106ac204f6700
Status: Downloaded newer image for centos:latest
docker.io/library/centos:late


docker images      <----执行这行,查看本地镜像
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hell178/lnmp        v1                  620a78c49b09        5 days ago          4GB
centos              latest              470671670cac        4 months ago        237MB

三、进入容器并安装lnmp

执行命令,这里用了-v,是目录映射,用做mysql数据存储目录,如果你不是用的Lnmp一键环境包,那么需要注意mysql安装目录

docker run -it -v D:\docker\mysql:/usr/local/mysql/var centos

使用git Bash进入容器,可能会报以下错误。

docker run -it centos
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

建议使用windows PowerShell工具执行
1、在桌面上,按住shift不放,单击鼠标右键即可看到
2、按键盘上的win+x也有

四、因为是在本地运行,懒得一个个装nginx,mysql等,我这里直接用的是lnmp一键环境

先安装wget

yum -y install wget

然后进到Lnmp官网,获取下载地址

lnmp官网地址 https://lnmp.org/install.html

执行以下命令,按自己的喜好安装版本吧

wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz -cO lnmp1.6.tar.gz && tar zxf lnmp1.6.tar.gz && cd lnmp1.6 && ./install.sh lnmp

五、安装ssh并使用密钥登录

安装openssh

yum install openssh-server openssh-clients -y

修改/etc/ssh/sshd_config配置文件

vi /etc/ssh/sshd_config

确定以下3个都没有被注释

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

注意:某些资料中让把配置文件中的UsePAM yes改为UsePAM no,经过实际测试,修改后启动ssh服务将报错,其实这个不用注释也行的

执行以下3条命令,生成对应的密钥,出现需要输入密码的地方,一路回车

ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key

修改root密码

passwd

启动ssh服务

/usr/sbin/sshd -D &

六、构建镜像并上传

lnmp安装好后,另外再开一个终端窗口。执行以下docker操作。千万别动刚才安装lnmp的窗口,否则刚才安装的东西全都没有了。

docker ps
docker commit a0f2b58c74af lnmp
docker tag lnmp:latest carl/lnmp:1.0
docker push carl/lnmp:1.0

等待推送完成后,在你的https://hub.docker.com/repositories即可看到了。

八、编写docker-compose.yml

  • 注意点
    一般mysql数据存储到宿主机,而不是docker容器中,所有
    
    

以下为官网说明:https://lnmp.org/faq.html
MySQL目录的更改,首先需要停掉mysql服务器/etc/init.d/mysql stop,下面新目录以/data/mysql/ 为例,然后cp -a /usr/local/mysql/var/* /data/mysql/,再chown mysql:mysql -R /data/mysql/ 下面再修改/etc/my.cnf ,查找[mysqld] ,在下面加入datadir = /data/mysql/ 保存,如果开启了innodb还需要修改innodb_data_home_dir 和innodb_log_group_home_dir为新的/data/mysql,启动mysql。

这里的version需要注意,Compose 文件格式有3个版本,分别为1, 2.x 和 3.x

使用docker-compose -v查看版本号,如果是1.xx,version就填2

version: ‘2’
services:
#服务名称,用户自定义
lnmp:
#镜像名称/镜像ID,如果本地不存在compose会拉取镜像,填刚才构建的镜像名
image: carl/lnmp:v1
#容器名称
#container_name: lnmp
#设置镜像变量,启动后的容器会包含这些变量设置
environment:
TZ: Asia/Shanghai
volumes:
- D:\works:/home/wwwroot
- D:\docker\vhost:/usr/local/nginx/conf/vhost
#这里把Mysql数据存储目录映射到宿主机,在第三步有临时映射
- D:\docker\mysql:/usr/local/mysql/var
ports:
- “80:80”
- “81:81”
- “82:82”
- “10022:22”
- “8090:8090”
- “800:8080”
- “10000:10000”
- “443:443”
command:
- /bin/bash
- -c
- |
lnmp start && /usr/sbin/sshd -D &
tty: true

执行命令开始使用

docker-compose exec lnmp /bin/bash


### 八、下次使用
把网站内容映射到了linux容器中的/home/wwwroot中,vhost也映射了
下次电脑重启了,有2种方式打开继续使用
1、在docker-composer.yml执行命令

docker-compose exec lnmp /bin/bash

2、docker desktop桌面工具,点击setting->右上角关闭->这里有容器列表


### 其他可能注意的点
1、如果Mysql没有启动,执行以下命令

yum install initscripts -y


2、如果navicat mysql连接不上数据库,请参考

https://blog.csdn.net/me_Lany/article/details/82770948


参考站点:[https://www.jianshu.com/p/34a625621a9a](https://www.jianshu.com/p/34a625621a9a)

使用vue+SheetJS/js-xlsx修改表头并导出excel

先写个静态的数据试试

<button @click="downloadMater">导出excel</button>
methods: {
    //创建表头
    createWs(data, titles) {
        const ws = XLSX.utils.json_to_sheet(
            data,
            {
                header: Object.keys(titles)
            }
        )
        const range = XLSX.utils.decode_range(ws['!ref'])

        for (let c = range.s.c; c <= range.e.c; c++) {
            const header = XLSX.utils.encode_col(c) + '1'
            ws[header].v = titles[ws[header].v]
        }

        return ws
    },
     //导出excel
    downloadMater() {

        const titles = {
            name: '姓名',
            age: '年龄'
        }
        const data = [
            {
                name: 'jzx',
                age: 17
            },
            {
                name: 'wmp',
                age: 17
            }
        ]
        const ws = this.createWs(
            data,
            titles
        )

        let wopts = {
            bookType: 'xlsx',
            bookSST: true,
            type: 'binary'
        };
        let workBook = {
            SheetNames: ['Sheet1'],
            Sheets: {
                'Sheet1': ws
            },
            Props: {}
        };

        FileSaver.saveAs(new Blob([this.changeData(XLSX.write(workBook, wopts))], {type: 'application/octet-stream'}), "lists.xlsx")
    },
    // 字符串转字符流
    changeData(s) {
        let buf
        //如果存在ArrayBuffer对象(es6) 最好采用该对象
        if (typeof ArrayBuffer !== 'undefined') {

            //1、创建一个字节长度为s.length的内存区域
            buf = new ArrayBuffer(s.length);

            //2、创建一个指向buf的Unit8视图,开始于字节0,直到缓冲区的末尾
            let view = new Uint8Array(buf);

            //3、返回指定位置的字符的Unicode编码
            for (let i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
            return buf;

        } else {
            buf = new Array(s.length);
            for (let i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
            return buf;
        }
    }
}

这样就自定义了表头。

再把从api请求到的数据放入,用titles做个对应即可。

参考网站:https://blog.csdn.net/juzipidemimi/article/details/90815730

git对比工具破解方法

在用git做项目管理的时候,时常会有冲突,这时候手动修改肯定会覆盖了其他小伙伴的代码。那么就需要使用到对比工具。

Beyond Compare 4官方注册需要249。所以网上找个方法破解吧。

1、永久使用需删除目录下所有:

C:\Users\***\AppData\Roaming\Scooter Software\Beyond Compare 4

2、默认点击输入密钥会跳转到网站购买或者输入框闪退问题:

删除安装目录下的BCUnrar.dll,然后可以在 帮助-输入秘钥弹出秘钥框

3、如果Beyond Compare 4已经过期,无法打开的激活界面方法

修改一下下边文件内容为空就可以打开了
C:\Users\用户\AppData\Roaming\BeyondCompare\BeyondCompare419.ini

4、密钥,如果密钥无法使用,可以再在网上搜搜

w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPcHAIQWfwfXv5n0IHDp5hv
1BM3+H1XygMtiE0-JBgacjE9tz33sIh542EmsGs1yg638UxVfmWqNLqu-
Zw91XxNEiZF7DC7-iV1XbSfsgxI8Tvqr-ZMTxlGCJU+2YLveAc-YXs8ci
RTtssts7leEbJ979H5v+G0sw-FwP9bjvE4GCJ8oj+jtlp7wFmpVdzovEh
v5Vg3dMqhqTiQHKfmHjYbb0o5OUxq0jOWxg5NKim9dhCVF+avO6mDeRNc
OYpl7BatIcd6tsiwdhHKRnyGshyVEjSgRCRY11IgyvdRPnbW8UOVULuTE

uniapp

TypeError: Cannot read property 'components' of undefined
Failed to resolve async component: function (resolve)

vi

此文特编辑

1.跳转到命令行行首:ctrl+a
2.跳转到命令行行尾:ctrl+e
3.删除行首到光标位置的字符:ctrl+u
4.删除光标位置到行尾的字符:ctrl+k
5.清理屏幕:ctrl+l或者clear命令

生命在于折腾,VI还是要练练的.很早之前就学过VI了,这次重新练练。

1. 文件操作

vi FileName 打开文件 FileName,并将光标置于第一行首。

vi +n FileName 打开文件 FileName,并将光标置于第 n 行首。

vi + FileName 打开文件 FileName,并将光标置于最后一行。

vi + /pattern File 打开文件 File,并将光标置于其中第一个于 pattern 匹配的字符串处。

vi –r FileName 在上次正用 vi 编辑 FileName 发生系统崩溃后,恢复FileName。

2. 插入

i 在光标前插入。

a 在光标后插入。

I 在当前行首插入。

A 在当前行尾插入。

o 在当前行之下一新行插入。

O 在当前行之上新开一行插入。

3. 光标的移动

1G 光标移动到文件第一行的行首。

K 光标移动到文件上一行的同一列。

h 光标移动到当前行的前一个字符。

l 光标移动到当前行的后一个字符

j 光标移动到下一行的同一列。

G 光标移动到文件最后一行的行首。

4. 整行的删除、移动

dd 删除光标所在行

yy 复制光标所在行

p(小写) 在光标的下一行粘贴yy命令复制的行

P(大写) 在光标的上一行粘贴yy命令复制的行

J 对光标所在行和光标所在下一行进行合并成一行。

5. 删除单个字符、删除一个单词

X(大写) 删除光标前一个字符

X(小写)删除光标后一个字符

xx 删除单个字符

dw 删除一个单词

6. 查找替换

/ 在文件中查找输入的内容

n 进入查询结果的下个内容(由光标所在行进行往上查询)

N 进入查询结果的下个内容(由光标所在行进行往下查询)

7. 回退操作

u 回退之前的操作

:e! 重新编辑当前文件,忽略所有的修改

8. 文件保存

ZZ 保存后退出文件

:w保存并返回指令模式

:w!覆盖已存在的文件

:q退出

:q!退出并丢掉所有未保存信息

:wq!保存并退出

别再百度行天下了,多用google吧

做为一名程序猿,会经常搜索问题,我的博客是用 git 管理项目,webhook 拉取代码,使用了 cloudflare 的 ssl 和 cdn,开启了缓存,所以每次 git push 了代码后,需要点击 cloudflare 中的 Purge Cache 清除,然后就百度了一下这个问题。

发现如下文章免登後台!手動快速清除 CloudFlare 的 Page Rules 頁面快取 https://www.minwt.com/website/server/21289.html,按操作直接复制粘贴,放到 mac bash 下执行,提示

-bash: br: No such file or directory

咦,提示没有这样的文件或目录,我 curl 没装?
查看一下 crul,执行

curl --version

发现有啊,然后果断去 cloudflare 官网看 api,发现百度到的文章多了几个 br

</br>

小坑了一把,然后放到自己的 webhook 中,完工

curl -X DELETE “https://api.cloudflare.com/client/v4/zones/ZoneID/purge_cache”
-H “X-Auth-Email: Email
-H “X-Auth-Key: Global API Key
-H “Content-Type: application/json”
–data ‘{“purge_everything”:true}’

提示清除成功

{"result":{"id":"c14fc1a5df8629ba7e1c7d153836b9ad"},"success":true,"errors":[],"messages":[]}

最后吐槽一下,很多文章都是复制粘贴,格式错乱,严重影响阅读体验,很多时候,30%的精力浪费在填坑中,来自自己挖的坑,网上复制粘贴的坑,希望多点原创,少点ctrl+c。
答应我,别再百度行天下了.

cloudflare 官方 api https://api.cloudflare.com/#railgun-connections-for-a-zone-list-available-railguns

总结网上的前端面试题

整理了网上的一些前端面试题,也算是为自己做一个笔记吧

1. 什么是防抖和节流?有什么区别?如何实现?

1.1 防抖

触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间;

1.2 节流

高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。

每次触发事件时都判断当前是否有等待执行的延时函数。

html& css

1. 简述一下src与href的区别

href是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。
当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。

2. Css单位px,rem,em,vw,vh的区别

px

px就是pixel像素的缩写,相对长度单位,网页设计常用的基本单位。像素px是相对于显示器屏幕分辨率而言的

em

em是相对长度单位。相对于当前对象内文本的字体尺寸(参考物是父元素的font-size)
如当前父元素的字体尺寸未设置,则相对于浏览器的默认字体尺寸
特点:
  1. em的值并不是固定的;
  2. em会继承父级元素的字体大小

rem

rem是CSS3新增的一个相对单位,rem是相对于HTML根元素的字体大小(font-size)来计算的长度单位
如果你没有设置html的字体大小,就会以浏览器默认字体大小,一般是16px

html{font-size: 62.5%}  /* 10 ÷ 16 × 100% = 62.5% */

body{font-size: 1.4rem;} /* 1.4 × 10px = 14px */

/*在根元素中定义了一个基本字体大小为62.5%(也就是10px。设置这个值主要方便计算,如果没有设置,将是以“16px”为基准 )*/

优点是,只需要设置根目录的大小就可以把整个页面的成比例的调好
rem兼容性:除了IE8及更早版本外,所有浏览器均已支持rem
em与rem的区别:
  rem是相对于根元素(html)的字体大小,而em是相对于其父元素的字体大小
两者使用规则:
如果这个属性根据它的font-size进行测量,则使用em
其他的一切事物属性均使用rem
这里提供了一个px、em、rem单位的转换工具:http://pxtoem.com/

vw、vh

vw、vh、vmax、vmin这四个单位都是基于视口
vw是相对视口(viewport)的宽度而定的,长度等于视口宽度的1/100
假如浏览器的宽度为200px,那么1vw就等于2px(200px/100)
vh是相对视口(viewport)的高度而定的,长度等于视口高度的1/100
假如浏览器的高度为500px,那么1vh就等于5px(500px/100)
vmin和vmax是相对于视口的高度和宽度两者之间的最小值或最大值

/*
如果浏览器的高为300px、宽为500px,那么1vmin就是3px,1vmax就是5px;如果浏览器的高为800px,宽为1080px,那么1vmin也是8px,1vmax也是10.8px
*/

其他单位:

%(百分比)
一般来说就是相对于父元素
1、对于普通定位元素就是我们理解的父元素
2、对于position: absolute;的元素是相对于已定位的父元素
3、对于position: fixed;的元素是相对于ViewPort(可视窗口)

vm

css3新单位,相对于视口的宽度或高度中较小的那个
其中最小的那个被均分为100单位的vm
比如:浏览器高度900px,宽度1200px,取最小的浏览器高度,1 vm = 900px/100 = 9 px
缺点:兼容性差

JS

  1. (0.1 + 0.2) 等于多少 为什么?

    0.30000000000000004
    因为 JS 采用 IEEE 754 双精度版本(64位),并且只要采用 IEEE 754 的语言都有该问题。我们都知道计算机表示十进制是采用二进制表示的,所以 0.1 在二进制表示为

0.1 = 2^-4 * 1.10011(0011) // (0011) 表示循环

小数算二进制和整数不同。乘法计算时,只计算小数位,整数位用作每一位的二进制,并且得到的第一位为最高位。所以我们得出 0.1 = 2^-4 * 1.10011(0011),那么 0.2 的演算也基本如上所示,只需要去掉第一步乘法,所以得出 0.2 = 2^-3 * 1.10011(0011)。

回来继续说 IEEE 754 双精度。六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位。因为 0.1 和 0.2 都是无限循环的二进制了,所以在小数位末尾处需要判断是否进位(就和十进制的四舍五入一样)。

所以 2^-4 * 1.10011…001 进位后就变成了 2^-4 * 1.10011(0011 * 12次)010 。那么把这两个二进制加起来会得出 2^-2 * 1.0011(0011 * 11次)0100 , 这个值算成十进制就是 0.30000000000000004

下面说一下原生解决办法,如下代码所示

前端框架

VUE

参考资料

几道高级前端面试题解析 https://yq.aliyun.com/articles/613474

MAC系统工具推荐

MAC工具下载站推荐

xclient http://www.xclient.info/

前端工具

  • webstorm

后端工具

全栈工具

  1. Sourcetree

    用来管理git,方便push、pull,以及合并冲突,有window和mac多端

  2. 本地WEB服务器,一键配置

    MAC推荐使用MAMP PRO
    WINDOW推荐使用PHPSTUDY

  3. 终端

    MAC推荐使用iTerm
    WINDOW推荐下载git,然后在git里输入命令,告别cmd

  4. 抓包

    MAC推荐使用Charles
    WINDOW也还是推荐使用Charles,虽然很多人使用Fiddler,二者差不多

  5. phpstorm

    请求api地址

系统必备工具

  1. Snipaste

    截图工具,可以在屏幕上贴图,方便再次截图,以前都是用QQ截图,总是觉得也方便省事,不需要单独下载一个软件

  2. ShadowsocksR

    梯子,IT程序猿必备,多用GOOGLE,多看国外文档

  3. chrome

    简洁啊,比什么360之流好的不是一点点

  4. chrome插件Bitwarden

    一个密码管理插件,也有提供软件下载,登录后可以同步你的密码,生成强密码,如果觉得不放心,可以自己搭个服务器来存放

让你的项目自动化部署到服务器

通俗点讲,就是在本地开发完成,然后 git push 到 gitlab 上,然后自动更新到服务器,无需手动进入服务器手动 git pull

简单点讲,就是 git push 后,有个钩子( http://www.a.com/update.php类似这样的网址 )请求一下,update.php 代码中会执行相关命令,代替手动 git pull

建议:建立一个 demo 项目,放到 git 上,把整个流程跑通了再用在其他项目中,要不然你的 git 记录会有很多垃圾 push 信息

第一步:登录你的服务器

不管用 password 还是 ssh 登录服务器均可,不是本地介绍重点,简单略过.建议用 ssh 登录
具体实现可以查看资料

Linux 篇:Linux ssh 登录
服务器搭建:(二)SSH 登录详解

第二步:查看你的 nginx 所属用户

因为是个人博客项目,偷个懒,直接 lnmp 一键环境搭建,没搭建环境的可以去官网lnmp 官网 https://lnmp.org/查看安装命令即可,在服务器搭建环境如下:
已安装好 nginx、PHP 等环境的忽略下面的命令

wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz -cO lnmp1.6.tar.gz && tar zxf lnmp1.6.tar.gz && cd lnmp1.6 && ./install.sh lnmp

安装好环境以后,执行命令

cd /usr/local/nginx/conf/  #每个人的安装路径可能不同,最关键是找到nginx.conf,查看执行用户名称
vi nginx.conf   #第一行,查看到当前nginx的执行用户是user  www www;

第三步:给服务器项目目录权限

cd /home  #先进入/home/目录
ll   # 或者 ls-a查看wwwroot所属权限

drwx—— 3 www www 111 Dec 26 09:26 www
drwxrwxrwx 2 root root 79 Dec 25 14:32 wwwlogs
drwxr-xr-x 6 www www 74 Dec 25 16:35 wwwroot

#如果权限这个不是 www,就执行以下命令

chown -R www:www /home/wwwroot/ #这个是LNMP默认存放项目的地方,换成你自己的

这样目录就可以移交给 www 用户了,现在 www 用户可以访问这个目录和.git 文件了。

切换到执行用户,接着我们我们切换到 www 用户

su www

结果显示“This account is currently not available.”,啥?这不让我登录?别急,这是因为 linux 连 www 帐户登录 shell 的权利都给剥夺了,我们暂时给 www 权利就好了。到/etc/passwd 中,把 www 用户的配置修改一下,让他的登录 shell 变成/bin/bash

vi /etc/passwd

www:x:1001:1001::/home/www:/sbin/nologin
(建议注释原来的,重新复制一行修改)
www:x:1001:1001::/home/www:/bin/bash

然后 www 用户就有登录权限了。我们用 su www 重新切换一次,就会发现你现在是以 www 用户登录了。

su www

第四步:为 www 这个用户生成密钥

第一步也有相关资料推荐

ssh-keygen

注意:.ssh 的存放目录,一般是/home/当前用户名,然后接下来的操作都是回车
Enter file in which to save the key (/home/www/.ssh/id_rsa):

第五步:把生成的 ssh key 加入到你的 gitlab

->注意:不建议把 root 密钥增加到 gitlab 上,root 的密钥用于登录管理服务器就好,把 www 用户所属的密钥增加到 gitlab 即可
不管你是用以下哪个 git 平台去管理,皆大同小异,目前列举比较流行的几种,一般都是在(个人设置->ssh 公钥->新增)

  1. 码云 https://gitee.com/
  2. 阿里云 http://code.aliyun.com/ ->我使用的是这个
  3. github https://github.com/
  4. CODING https://coding.net/
  5. gitlab 内部搭建的 git 服务器
  6. 等待添加

第六步:拉取 gitlab 上的项目

cd /home/wwwroot
git clone git@code.aliyun.com:personage/demo.git #改成你的项目地址,如果拉取不成功,说明你的密钥没弄好

第七步:配置 nginx

因为我用 lnmp vhost add 增加了我的域名配置,自动在/home/wwwroot 下生成了 www.chengtianzhu.com 目录,所以我直接修改

chattr -i www.chengtianzhu.com/.user.ini  #lnmp生成时有个.user.ini,默认无法直接删除
rm -rf www.chengtianzhu.com/ #删除默认生成的目录
mv demo/ www.chengtianzhu.com/  把git拉取下来的项目重命名

在浏览器中输入 www.chengtianzhu.com, 看是否能否访问,如果是子目录,需要自己去 nginx 配置中修改路径

第九步:把自动拉取git的php代码放到项目中

www.chengtianzhu.com/update.php 为例,最好是单独配置个地址,因为是外部公共访问的:

<?php

class Deploy {

    /**
     * A callback function to call after the deploy has finished.
     *
     * @var callback
     */
    public $post_deploy;

    /**
     * The name of the file that will be used for logging deployments. Set to
     * FALSE to disable logging.
     *
     * @var string
     */
    private $_log = 'deployments.log';

    /**
     * The timestamp format used for logging.
     *
     * @link    http://www.php.net/manual/en/function.date.php
     * @var     string
     */
    private $_date_format = 'Y-m-d H:i:sP';

    /**
     * The name of the branch to pull from.
     *
     * @var string
     */
    private $_branch = 'master';

    /**
     * The name of the remote to pull from.
     *
     * @var string
     */
    private $_remote = 'origin';

    /**
     * The directory where your website and git repository are located, can be
     * a relative or absolute path
     *
     * @var string
     */
    private $_directory;

    /**
     * Sets up defaults.
     *
     * @param  string  $directory  Directory where your website is located
     * @param  array   $data       Information about the deployment
     */
    public function __construct($directory, $options = array())
    {
        // Determine the directory path        
                // Create the log file
                file_put_contents($filename, '');

                // Allow anyone to write to log files
                chmod($filename, 0666);
            }

            // Write the message into the log file
            // Format: time --- type: message
            file_put_contents($filename, date($this->_date_format).' --- '.$type.': '.$message.PHP_EOL, FILE_APPEND);
        }
    }

    /**
     * Executes the necessary commands to deploy the website.
     */
    public function execute()
    {
        try
        {
            // Make sure we're in the right directory
            chdir($this->_directory);
            $this->log('Changing working directory... ');
            // Discard any changes to tracked files since our last deploy
            exec('git reset --hard HEAD', $output);
            $this->log('Reseting repository... '.implode(' ', $output));

            // Update the local repository
            exec('git pull '.$this->_remote.' '.$this->_branch, $output);
            $this->log('Pulling in changes... '.implode(' ', $output));
            // Secure the .git directory
            exec('chmod -R og-rx .git');
            $this->log('Securing .git directory... ');

            if (is_callable($this->post_deploy))
            {
                call_user_func($this->post_deploy, $this->_data);
            }

            $this->log('Deployment successful.');
        }
        catch (Exception $e)
        {
            $this->log($e, 'ERROR');
        }
    }

}

// This is just an example
$deploy = new Deploy('/home/wwwroot/www.chengtianzhu.com/'); //修改成你的项目路径

$deploy->execute();

?>

第十步:gitlab配置

在项目–>设置–>WebHooks,增加刚才的www.chengtianzhu.com/update.php
或者在setting–>integrations,增加钩子
增加完成后可以点击<测试钩子>按钮测试一下.
显示200成功

Hook executed successfully: HTTP 200
但是一般还是拉取不了代码,因为第九步的php代码使用了exec函数,默认是禁用的.
我们写一个简单的demo测试一下,在服务器环境下:
vi test.php
内容为:

<?php
    exec('php hello.php',$out,$status);
    var_dump($out);
?>

再创建一个hello.php

vi hello.php

内容为:

<?php
 echo 'hello world';
?>

保存后,执行试一下

php test.php

提示:exec() has been disabled for security reasons,说明exec用不了

PHP Notice:  Undefined variable: out in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Notice:  Undefined variable: return in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Warning:  exec() has been disabled for security reasons in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Notice:  Undefined variable: o in /home/wwwroot/www.chengtianzhu.com/test.php on line 3
NULL

第十一步:开启exec

首先要用find命令查找到php.ini所在位置

find / -name php.ini

得到好多结果,关注最后台一条信息

/usr/local/php/etc/php.ini

用VI修改一下

vi /usr/local/php/etc/php.ini

查找disable_functions = passthru,exec,system,chroot或者查找disable_functions,把exec删掉保存.
修改后要重启才能生效,这里的重启并不是重启nginx-一定要注意。
我这里使用的是Lnmp,使用lnmp reload

lnmp reload #或者 sudo /etc/init.d/php-fpm restart

这个时间再执行第十步的php test.php,显示结果为:

array(1) {
  [0]=>
  string(11) "hello world"
}

这时表示已经可以执行钩子(update.php),exec的代码了.回到你的本地测试一下,随便新增或者修改一些东西,再git提交.服务器显示已成功.

第十二步:恢复执行用户的 nologin

不要忘了第三步的时候修改了/etc/passwd配置,现在把 www 用户的 nologin 选项恢复回去哟

vi /etc/passwd

www:x:1001:1001::/home/www:/bin/bash
(改回原来的)
www:x:1001:1001::/home/www:/sbin/nologin

参考网站

  1. gitlab 通过 webhook 自动部署 https://www.jianshu.com/p/59a54e2e27d3
  2. Webhook 实践 —— 自动部署 https://segmentfault.com/a/1190000003908244?utm_source=tag-newest
  3. [后端]gitlab 之 webhook 自动部署 https://www.jianshu.com/p/00bc0323e83f

Mac默认python切换升级为python3

先查看系统环境和python环境

我的电脑为环境为mac OS High Sierra 10.13.6

第一步: 在终端输入命令查看python

    python -V

显示如下:

Python 2.7.10

第二步: 然后用brew安装pyhton3(建议使用brew管理

   brew install python3

第三步: 查看python3所在路径

    which python3

显示如下:

/usr/local/bin/python3

第四步: 修改配置

可以先在终端 cd /System/Library/Frameworks/Python.framework/Versions/2.7/bin/,看python2的路径是否存在

    vi ~/.bash_profile

增加以下3行:

alias python2='/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7'
alias python3='/usr/local/bin/python3' #第三步的路径,注意是不是一致的
alias python=python3

第五步: 让配置文件生效

source ~/.bash_profile

完工

最后:关闭终端,重新输入python -v

python -v

请我喝杯咖啡吧~

支付宝
微信
111