微信小程序TGIT检出远程master到本地master

先配置小程序开发工具中的版本控制
设置中用户信息填写由小程序后台TGIT添加的用户,需要填写全名,在小程序后台TGIT项目控制的链接进入腾讯云DEV,点击项目进入工蜂,查看全名通常比较长最后一个下划线后接的是后台输入的用户名。
邮箱是腾讯云分配的,通常是你的很长的用户名@git.cloud.tencent.com。
网络认证,认证方式选择最后一项填入用户名密码,即小程序后台新建用户的时候填入的账号密码,账号就是工蜂用户名,很长的那个。
远程,点添加将工蜂中的项目地址填入,名称跟工蜂中的名称一致即可。
配置正确之后,点击抓取,抓取项目,能看见项目中分支信息出现在左侧远程下面,然后拉取可以拉取源代码。
注意,第一拉取时,比如远程git项目为Estate/master分支。
从Tgit终端控制台中输入

1
git checkout -b master Estate/master

注意如果Tgit上有代码则需要将本地所有文件先删除,留空项目目录。如果没有应该首先提交本地代码,再推送,产生新git分支

使用PPA源安装支持HTTP2的apache2和php

1
2
3
4
5
6
7
8
LC_ALL=C.UTF-8 sudo add-apt-repository -y ppa:ondrej/apache2 &&
sudo apt-key update &&
sudo apt-get update &&
sudo apt-get upgrade -y &&
sudo apt-get install apache2 -y &&
sudo a2enmod rewrite mime include headers filter expires deflate autoindex setenvif ssl http2 &&
sudo apt-get install php5.6 -y &&
sudo apt-get install libapache2-mod-wsgi-py3 -y

创业者的自白

什么是创业?

创造新的事物,来给这个世界带来美好,关键词是“创造”和“新”,在没产生创新创造的前提下就不能称为创业,创业不等于就业,别人卖什么产品我复制过来我也做,别人做电商我也搬过来做,这种称之为就业,这只是一种维持生计的手段,因为没有注入创造与新的元素。

为何而创业?

有很多人回答说是为了赚钱发财,突破阶级,没错很现实,但很多人都没有发现更深一层的意义在于创业的最吸引人的地方是放大自己的价值观,把自己认为正确的事情传播出去并不断放大它,而变现是一种对创业者价值观的认同方式。放的越大,传播的越远,就越会有所收获。

所以创业注定不会人人都能成功,但是人人都有机会。如同彩票一样,肯定会有人中奖,但是不见得是你。

没有不败的神话,只有不磨灭的意志

创业是一场生死战,殊死搏斗。胆识,目标,运气一个都不能少,其实不论成功和失败都是暂时的,暂时的成功让你不断去超越成功,有句话我觉得说得特别好:你只有拼命跑,你才有可能停留在原地。暂时失败是会让你迅速的成长,高管走了可以招,钱没了可以融,但是创业者心不在了就一切都没了,没有不败的神话,只有不磨灭的意志。创业本身就是一件无比艰难的事情,但是换个角度看,人从出生开始几乎没有什么事情是可以轻而易举得到的,比如我们每个人刚出生的时候学走路,克服了多少困难,历经多少失败才能直立行走,只不过创业是要求掌握的技能要多一些,面对的困难与不确定性也多一些,一个需要万事俱备才行动的人不是真正的创业者,在我看来这是一种将人进行划分的一种很微妙的方式,人与人之间如果不存在差异性,就不存在伟大,成功就是从众多中脱颖而出,而失败就是差一点脱颖而出。

能承受多大痛苦,就能获得多大成功

创业的苦与乐,只有每个创业者能体会,此时可以征服全世界,彼时全世界都在与你作对,这种复杂心情交错的背后是两种价值观在相互做斗争,坚持还是放弃。能承受多大痛苦,就能获得多大成功,这个是绝对真理,当我们的内心已千疮百孔,满心伤痕而外表还是一脸笑容时,幸运应该很块就降临了。我特别喜欢引导与推荐别人去创业,因为我认为创业是一种不可多得的人生经历,它能让人快速成长,延长生命宽度,这种意义远大于成功与否,没有绝对的成功与失败,人都是赤手空拳来到人世间,总共不过三万天,创业不像故事中描述的那么容易,但也没有那么糟糕,取决我们如何去对待。当天堂的甘露如雨水般降落时,一些人撑起伞,而另一些人找来了大汤匙,做好准备,等待机遇。

祝所有的创业者都能有一个锦绣前程,风雨过后总会见到彩虹!

在Ubuntu上安装Chrome浏览器和ChromeDriver

一.安装Chrome浏览器

1.安装依赖

1
sudo apt-get install libxss1 libappindicator1 libindicator7

2.下载Chrome安装包

1
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

3.安装

1
2
sudo dpkg -i google-chrome*.deb
sudo apt-get install -f

二.安装ChromeDriver

1.安装xvfb以便我们可以无头奔跑地运行Chrome

1
sudo apt-get install xvfb

2.安装依赖

1
sudo apt-get install unzip

3.下载安装包

1
wget -N http://chromedriver.storage.googleapis.com/对应版本/chromedriver_linux64.zip

 
chromedriver与chrome的对应关系表:
各个版本的下载地址:淘宝镜像

chromedriver版本 支持的Chrome版本
v2.41 v67-69
v2.40 v66-68
v2.39 v66-68
v2.38 v65-67
v2.37 v64-66
v2.36 v63-65
v2.35 v62-64
v2.34 v61-63
v2.33 v60-62
v2.32 v59-61
v2.31 v58-60
v2.30 v58-60
v2.29 v56-58
v2.28 v55-57
v2.27 v54-56
v2.26 v53-55
v2.25 v53-55
v2.24 v52-54
v2.23 v51-53
v2.22 v49-52
v2.21 v46-50
v2.20 v43-48
v2.19 v43-47
v2.18 v43-46
v2.17 v42-43
v2.13 v42-45
v2.15 v40-43
v2.14 v39-42
v2.13 v38-41
v2.12 v36-40
v2.11 v36-40
v2.10 v33-36
v2.9 v31-34
v2.8 v30-33
v2.7 v30-33
v2.6 v29-32
v2.5 v29-32
v2.4 v29-32

4.解压缩+添加执行权限

1
unzip chromedriver_linux64.zip

5.移动

1
sudo mv -f chromedriver /usr/local/share/chromedriver

6.建立软连接

1
2
sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver

三.无头运行Chrome

1.安装Python依赖

1
2
pip3 install selenium
pip3 install pyvirtualdisplay

2.开整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from selenium import webdriver
from selenium.webdriver.chrome.options import Options 
chrome_options = Options()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get(url)
iframe=driver.find_elements_by_tag_name('iframe')
    if len(iframe)>0:
        iframe = iframe[0]        
        driver.switch_to.frame(iframe)        
        ibody = driver.find_elements_by_tag_name('body')        
        if len(ibody)>0:            
            ibody=ibody[0]            
            video =ibody.find_element_by_tag_name('video')            
            if video is not None:                
                src = video.get_attribute("src")                
                if src !"" and src is not None:                    
                    res = {'src':src}                    
                    return str(res)

 

Linux禁止root帐号直接登录

Linux的默认管理员名即是root,只需要知道ROOT密码即可直接登录SSH。禁止Root从SSH直接登录可以提高服务器安全性。经过以下操作后即可实现。

本文适用于CentOS、Debian等Linux系统。
一、新建帐户

1
useradd kwxgd

SSH执行以上命令,可以创建名为“kwxgd”的帐号,可以自定义。
二、设置帐户密码

1
passwd kwxgd

使用passwd命令即可给相应帐户设置或修改密码。
根据图示,设置或修改密码需要填写两次,第二次为效验密码,输入完毕后请回车确认。
三、不允许root直接登陆1、修改相关文件

1
vi /etc/ssh/sshd_config

SSH执行以上命令,修改sshd_config文件
2、禁止root登陆查找“#PermitRootLogin yes”,将前面的“#”去掉,短尾“Yes”改为“No”,并保存文件。

四、下次登陆
1、先使用新建账号“kwxgd”以普通用户登陆。
2、若要获得ROOT权限,在SSH中执行以下命令

1
su root

执行以上命令并输入root密码后即可获得root权限。

JavaScript中定时器的精度

之前写了一篇文章介绍JS中的高精度计时,那么,与高精度相对的,低精度又是什么呢?或者说我们常接触到的精度是在什么水平?

这篇文章主要探讨一下JS里常用的定时器,看看它们能达到什么精度。由于结论我也不知道,所以基本上这篇文章算边做实验边写的吧,有问题希望各位看官能帮忙指出。文中的实验覆盖范围很小,而且方法也极度不严谨,大家先且一看吧,也许有时间我会再重新做实验。

正传
setTimeout
曾几何时,有前辈教诲我们,JS里setTimeout是不精确的,因为它所做的事情只是把任务添加到事件队列当中。如果在这个任务执行之前有别的任务执行的比较慢(比如死循环、大规模DOM操作、fs.同步IO等),那么后面的任务就会被推迟执行了。

与此同时,setTimeout(func, 0)是我们常见的一种奇怪的技巧,它可以让任务推迟执行,而又不推迟很多。说直观一点,通过这种技巧可以模拟一个低优先级的任务,比如我们在操作DOM的同时又希望window.scrollTo(0, 0),也许我们就会把后者放在setTimeout 0当中。在没有研究清楚event loop前,这也许是心理安慰,但因地制宜地用这个技巧常常会发生一些老中医般的意想不到的神奇效果。

我们先看看在没有任何其他繁忙任务时,setTimeout 0能达到多少精度。

1
2
3
4
5
var start = hrt();
setTimeout(function(){
  var now = hrt();
  console.log(now - start);
}, 0);

配合使用上回的高精度计时函数使用,在OSX Chrome34中,我这大概是9~10ms,而在node.js里则可以达到1.2~2.6ms的样子。然后我们慢慢增大延迟值,试着探索一下setTimeout有多少精度吧。
粗略实验下,发现在Chrome中,setTimeout的时间下限基本上就是9~10ms,当延迟在10多20这个水平时候,也能达到,但波动相当大。延迟到30以上,基本上实际时间比设置值只会多到1~2ms的样子;而在node中,即使设置很小的延迟,也能达到,但实际时间也会比设置值多个1~2ms。

模拟一下setTimeout被推迟的情况

1
2
3
4
5
6
var start = hrt();
for (var i=0; i<1e8; ++i) ;
setTimeout(function(){
  var now = hrt();
  console.log(now - start);
}, 0);

明显就看到时间变长多了,所以必须谨记setTimeout并不靠谱。

setInterval
这是用来做周期触发的回调用的,首先我们也丧心病狂的试试setInterval 0吧。

1
2
3
4
5
6
7
8
var start = hrt(), last = start;
var id = setInterval(function(){
  var now = hrt();
  console.log(now - last);
  last = now;

  if (now - start > 2000) clearInterval(id);
}, 0);

在Chrome里平均稳定在4.6ms左右一次,当时间设置到6ms以上时,基本上能达到,但实际触发时间比设置要大1ms左右。node这边依然要好一些,几乎能达到任何设置的时间,但也会有大概1ms的延迟。毫无疑问setInterval也是会被负荷重的任务推迟,就不演示了。

setImmediate
这是node.js才有的函数,我这里它大概有不到1ms的延迟。在朴灵的《深入浅出node.js》一书中对这个函数有比较详尽的解释,这里我就不赘述了。

不得不说的是——setImmediate也会被同步的代码阻塞——yes, this is JavaScript。

小结
到这里,常用的setXXX系列手工产生异步的办法都看了一遍。不得不承认node与浏览器在这些核心函数上优化都是相当到位的。但是其他浏览器,包括windows上,尤其是某些老旧的IE,我对它们表示不乐观,还好我现在的工作很少和这些东西打交道,改天有时间我应该会再用手机做一次测试,以求更贴近我的工作环境。

番外篇
requestAnimationFrame
这个东西,我觉得基本上把它当做一个setTimeout 0来看待就行了,现在比较推崇用它来做动画,我们也看看它的精度吧。

1
2
3
4
5
6
7
8
9
var start = hrt(), last = start;
function loop(){
  var now = hrt();
  console.log(now - last);
  last = now;

  if (now - start < 2000) requestAnimationFrame(loop);
}
loop();

我本来满心期望它有很稳定的触发间隔,但我失望了,从15ms多到17ms都有,不是很稳定。但据说它给浏览器带来的符合是更小的,所以会有更好的性能?这个15~17ms很有讲究,因为这刚好就是60FPS,似乎我还真没见过什么浏览器是超过60FPS的。

setZeroTimeout
这是一个很有趣的黑科技(github),它通过postMessage来为浏览器模拟setImmediate,(在可能的时候)避免使用setTimeout 0,试了一下,用它的确是能做到0~1ms的触发时间,简直厉害……

值得一提的是,我们有时候会用setTimeout嵌套来达到与setInterval类似的效果,嵌套使用setTimeout 0还可以(我刚试了下,反复setTimeout 0能达到和setInterval 0一样的4~5ms精度),嵌套setZeroTimeout因为触发太频繁,不出一秒浏览器就直接卡死了……

JavaScript中的高精度计时

HRT(High Resolution Timing, 高精度计时)在一些场合有很大的作用,比如游戏开发中,需要精确的计算两帧之间的时间差。

在JS中常常用(new Date()).getTime()来获取毫秒级的时间戳,虽然是毫秒级,但事实上它的真实精度只能达到大概16ms的级别。例如

1
2
3
while (true){
  console.log((new Date()).getTime()); // 这样死循环浏览器会跪的,责任自负
}

会发现它事实上大概16ms才跳一次,也许是17ms、又或者15ms吧,反正实际精度是有限的——什么?你跟我说是1ms?我告诉你那是因为新的系统或者浏览器使用了更高精度——但这不影响这篇文章的内容……

这对于日常应用来说完全够用了,但是对于游戏这样的场合,高精度计时就有它不可取代的意义了。

故事从这里开始
上面的获得毫秒级时间戳的方式之所以精度有限,是因为它的实现方式,以及它“绝对时间”的定义。
以Windows为例,这一类时间戳所使用的系统调用,比如GetSystemTime()MSDN、GetTickCount()MSDN,其函数的取值并不是实时的,而是通过硬件的时钟中断被动刷新的,这里的刷新间隔“正好”就是上面那个16ms。以GetSystemTime()为例,它返回的是SYSTEMTIME结构体,这用来进行时间日期处理的,因为时间日期处理通常根本不需要也不应该用那么高的精度(甚至很多时候只需要秒级别的精度),所以(new Date()).getTime()通过它们实现的确是可以胜任的。

现在我们明白了,靠这个时间戳是不能实现高精度计时的。
在Windows上,常常有两种高精度计时的方式:
第一种是timeGetTime()MSDN,它能返回系统启动到现在所经过的毫秒数,精度是1ms,因为它是32位的,所以大概49.71天会溢出清零。
第二种QueryPerformanceCounter()配合QueryPerformanceFrequency()MSDN实现,能够实现微秒级别的计时精度,对于大多数场合而言都够了。
当然还有更先进的方法,是通过CPU中的硬件计数器,和CPU每个时钟周期的时间,计算出更精确的时间(通常是纳秒级别的),对精度要求极高的场合这是最精确的选择了。

通常在使用固定位数的情况下,精度越高意味着计时的范围越小,这就不罗嗦了。

回到JavaScript中来
上面那些乱七八糟系统调用其实更咱们都没什么太大关系,我们能干什么完全看运行环境乐意给什么。
在webkit中提供了performance.now()参考文献来获取一个毫秒级的浮点数时间戳,我没查到资料它的有效精度是多少,不过既然给了个浮点数那就这么用着吧,我们就当它是微秒级的了!
在node.js中,有process.hrtime()DOC,返回的是一个数组[seconds, nanoseconds],看起来它具有纳秒级别的精度?且信了吧。

综合一下,我写了下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exports.time = (function(){
  if (typeof window !== 'undefined'){
    // 浏览器
    if (typeof window.performance !== 'undefined' && typeof performance.now !== 'undefined'){
      // support hrt
      return function(){
        return performance.now();
      };
    }else{
      // oh no..
      return function(){
        return (new Date()).getTime();
      };
    }
  }else{
    // node.js
    return function(){
      var diff = process.hrtime();
      return (diff[0] * 1e9 + diff[1]) / 1e6; // nano second -> ms
    };
  }
})();

有了上面的代码(gist),我们就能写一个秒表神马的,在做性能测试的时候就用得上了。

最后还是要唠叨一句,HRT是用来计算时间差的,不是用来计算现实中时间(挂钟时间)的。

下一篇文章中,将会对JS中的时间精度进行进一步的讨论,对象自然就是setTimeout/setInterval了!

Linux简单性能测试命令

1.top
Top命令显示了实际CPU使用情况,默认情况下,它显示了服务器上占用CPU的任务信息并且每5秒钟刷新一次。你可以通过多种方式分类它们,包括PID、时间和内存使用情况。
第一行的load average即为系统负载,就是说整个VPS资源占用情况,如果正常建站,一般很少有超过5的时候;
第三行的,这个是CPU占用资源。还有后面的??%wa这个是硬盘状态,正常情况下CPU最好不要超过30%占用.wa指数长期30%以上,基本上硬盘就是不给力状态。
第四行是内存,总内存,已使用内存,空闲内存。我这里是W2的VPS,内存为1GB,大家可以参考下。

2.查看CPU,硬盘和内存信息

1
2
3
cat /proc/cpuinfo(CPU信息)
cat /proc/meminfo(内存信息)
df –lh(查看硬盘信息)

3.下载测试

1
wget http://cachefly.cachefly.net/100mb.test

4.磁盘I/O测试

1
dd if=/dev/zero of=test bs=64k count=16k oflag=dsync

这个命令,是测试磁盘I/O性能的,图中有磁盘写入速率,可以作为参考。
或者使用此命令:

1
dd if=/dev/zero of=test bs=64k count=4k oflag=dsync

SSD磁盘用这个命令:

1
hdparm -t /dev/xvda

经过上面两步测试,磁盘多出了2个文件:100mb.test,test,我们用命令删除它们。

1
2
rm 100mb.test
rm test

5.UBI跑分综合性能测试

1
wget http://www.CTOHome.com/linux-vps-pack/unixbench.sh;sh ./unixbench.sh;

一般高于400分就算正常水准,如果高于1000的话,就是非常给力。

6.其他测试命令

1
2
3
iostat  (磁盘和内存使用率)
Vmstat  (进程、内存、页面I/O块和CPU等信息的监控)
wget -qO- bench.sh | bash

初学数据挖掘-相似性度量

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
84
85
86
87
88
89
90
91
92
93
94
# -*- coding:utf-8 -*-
critics = {'Lisa Rose'{'Lady in the Water'2.5, 'Snakes on a Plane'3.5, 'Just My Luck'3.0, 'Superman Returns'3.5, 'You, Me and Dupree'2.5,'The Night Listener'3.0},
                'Gene Seymour'{'Lady in the Water'3.0, 'Snakes on a Plane'3.5, 'Just My Luck'1.5, 'Superman Returns'5.0, 'The Night Listener'3.0, 'You, Me and Dupree'3.5},
                'Michael Phillips'{'Lady in the Water'2.5, 'Snakes on a Plane'3.0, 'Superman Returns'3.5, 'The Night Listener'4.0},
                'Claudia Puig'{'Snakes on a Plane'3.5, 'Just My Luck'3.0, 'The Night Listener'4.5, 'Superman Returns'4.0, 'You, Me and Dupree'2.5},
                'Mick LaSalle'{'Lady in the Water'3.0, 'Snakes on a Plane'4.0, 'Just My Luck'2.0, 'Superman Returns'3.0, 'The Night Listener'3.0, 'You, Me and Dupree'2.0},
                'Jack Matthews'{'Lady in the Water'3.0, 'Snakes on a Plane'4.0, 'The Night Listener'3.0, 'Superman Returns'5.0, 'You, Me and Dupree'3.5},
                'Toby'{'Snakes on a Plane'4.5, 'You, Me and Dupree'1.0, 'Superman Returns'4.0},
                'Yu':{'Lady in the Water'2.5, 'Snakes on a Plane'3.5, 'Just My Luck'3.0, 'Superman Returns'3.5, 'You, Me and Dupree'2.5,'The Night Listener'3.0}}

from math import sqrt
print u"距离与相关系数:它们之间是相反的,若距离越短(距离的数值越小),则相似度越大(相似度的数值越大)"
# 欧几里得距离
def sim_distance(prefs, person1, person2):
    # 得到两者同时评价过的电影的列表
    si = { }
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item] = 1
    # 若不存在同时评价过的电影则返回0
    if len(si) == 0 :   return 0

    # 计算所有差值的平方和
    sum_of_squares = sum([pow(prefs[person1][item] - prefs[person2][item], 2)
                                        for item in prefs[person1] if item in prefs[person2]])     # sum()函数中的参数是一个list,sum([item for item in a if item in b])

    return 1 / (1+sqrt(sum_of_squares))
print u"欧几里得距离(最后给出的数值,实际上是给出了相似度评价):"
print(sim_distance(critics, 'Lisa Rose', 'Gene Seymour'))

# 皮尔逊相关系数
def sim_pearson(prefs, p1, p2):
    si = { }
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item] = 1
    n = len(si)
    if n == 0:
        return 1    #如果两者不存在同时评论过的电影时,返回1

    #对所有偏好求和
    sum1 = sum([prefs[p1][it] for it in si])
    sum2 = sum([prefs[p2][it] for it in si])
    #求平方和
    sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
    sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
    #求乘积之和
    pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])

    #计算皮尔逊评价值
    num = pSum - (sum1 * sum2 / n)
    den = sqrt((sum1Sq-pow(sum1, 2)/n) * (sum2Sq-pow(sum2, 2)/n))

    if den == 0return 0
    r =  num/den

    return r

print u"皮尔逊相关系数:"
print (sim_pearson(critics, 'Lisa Rose', 'Gene Seymour'))

# Jaccard相似度(狭义)——只能用于判断两者之间是否一致,而不能根据其评分来判定相似度
def sim_jaccard(prefs, per1, per2):
    si_union = { }  #并集
    si_inter = { }  #交集
    si_union = dict(prefs[per1], **prefs[per2])

    for item in  prefs[per1]:
        if item in prefs[per2]:
            si_inter[item] = min(prefs[per1][item], prefs[per2][item])

    sum1 = len(si_inter)
    sum2 = len(si_union)

    if (sum2 == 0)return 0

    r = float(sum1) / sum2
    return r

print u"Jaccard相似度(狭义)——只能用于判断两者之间是否一致,而不能根据其评分来判定相似度:"
print sim_jaccard(critics, 'Lisa Rose', 'Gene Seymour')

#曼哈顿距离(城市街区距离  )
def sim_manhattan(prefs, p1, p2):
    si = { }
    for item in p1:
        if item in p2: si[item] = 1
    if len(item) == 0return 1

    sum_of_minus = sum([abs(prefs[p1][item] - prefs[p2][item]) 
                                        for item in prefs[p1] if item in prefs[p2]])
    return 1 / (sum_of_minus+1)
print u"曼哈顿距离(最后得到的数值也是相似度):"
print sim_manhattan(critics, 'Lisa Rose', 'Gene Seymour')