mysql命令行神器mycli

为什么使用它 受够了mysql原生client后,你会爱上mycli的自动补全和高亮。对于我这种常常记不住表结构的人来说,自动补全真是爽得不行。 ps:sql新手谨慎使用,建议多裸写sql后再来使用该软件 安装 Mac brew install mycli CentOS # 请尽量先将pip升级到最新版本 pip install --upgrade pip yum install python-devel yum install libffi-devel easy_install mycli 使用方法 和mysql原生命令行一样: mycli -uname

2018-04-22 · 1 分钟 · 27 字

下载知乎的视频(M3U8)

总结:知乎的视频播放基于M3U8文件,找一种支持通过该类文件下载目标文件的工具即可,例如FFmpeg 某个慵懒的周末上午刷着知乎,一位知友po了自己用鼓(还是啥?)敲击的旅行青蛙音乐的视频,评论区有小伙伴想要该视频的音频文件下载,想着举手之劳,顺便看看知乎的视频播放用的啥技术。 打开开发者工具,刷新网页并播放,观察网络请求并没有media文件的下载,倒是看到很多.ts文件不断下载中。看来是将视频切割为多个片段了,Google后了解到知乎使用的是M3U8文件,再从该文件下载片段。 什么是M3U8?这是一种utf8格式的M3U(MP3 URL的缩写)文件,最先由Fraunhofer协会(研究出MP3算法的那个)设计并用于Winplay3软件。最初只是应用于MP3等音频文件,现在广泛应用于在线流媒体和视频播放。说白了,它就是一个资源文件的播放列表索引文件,该文件记录了目标资源片段的url链接。具体请看维基百科 打开知乎视频,观察网络请求,你会发现请求了一个m3u8的资源。看看它返回的是什么: foam@foamdeMacBook-Pro: ~ » curl "https://vdn.vzuu.com/Act-ss-m3u8-hd/c338e5b09ab2431080a58ed4d1bb6e17/5a996be2-17da-11e8-b60a-0242ac112a05None.m3u8?auth_key=1521964082-0-0-4d282a5ef6e479a492e6182f044384f5&expiration=1521964082&disable_local_cache=0" #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:2 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:2.000000, 5a996be2-17da-11e8-b60a-0242ac112a05None-00001.ts?auth_key=1521964082-0-0-c0110f185ac09713b4d717e1f2ec30ca #EXTINF:2.000000, 5a996be2-17da-11e8-b60a-0242ac112a05None-00002.ts?auth_key=1521964082-0-0-26ad0014261d1e1f94b1273d91e9a1ec #EXTINF:2.000000, 5a996be2-17da-11e8-b60a-0242ac112a05None-00003.ts?auth_key=1521964082-0-0-ed71bc54e68662748af8eb5228525b84 #EXTINF:2.000000, 5a996be2-17da-11e8-b60a-0242ac112a05None-00004.ts?auth_key=1521964082-0-0-7ef99c02438c16e8d0eabc4955cf3f84 # 有点长,省略若干行... ... #EXT-X-ENDLIST 可以看到返回了一个列表,每个片段2秒钟,包含了链接。 这里使用FFmpeg下载M3U8的资源。FFmpeg是一种处理音视频的强大的开源工具(向开源大佬们致敬),强大到令我泪流满面。该工具有win/linux/mac版本,请自行到官网或包管理器下载。 贴出命令: 根据M3U8下载资源文件: ffmpeg -i "https://vdn.vzuu.com/Act-ss-m3u8-hd/c338e5b09ab2431080a58ed4d1bb6e17/5a996be2-17da-11e8-b60a-0242ac112a05None.m3u8?auth_key=1521964082-0-0-4d282a5ef6e479a492e6182f044384f5&expiration=1521964082&disable_local_cache=0" -c copy 1.mp4 将MP4转换为MP3 ffmpeg -i 1.mp4 -f mp3 -vn 1.mp3 感谢科技的美好~

2018-03-25 · 1 分钟 · 46 字

NodeJs中将TinyInt转换为Boolean

Mysql的基本数据类型中并没有布尔型,之所以建表和数据操作中能够使用BOOLEAN是因为mysql将其作为了tinyint(1)的别名。用0表示false,1表示true。 但开发过程中,既然我们给某一字段定义为布尔型,那么在我们获取数据后,期望得到的必然是布尔值而不是0或1。因此我们可以在得到返回值后转换一下。 这里我使用的是mysql模块,该模块允许给typeCase属性设置一个回调函数。详见官网说明 connection.query({ sql: '...', typeCast: function (field, next) { if (field.type == 'TINY' && field.length == 1) { return (field.string() == '1'); // 1 = true, 0 = false } return next(); } }); 但这也意味着使用该方法的项目不能使用tinyInt(1)类型了,自行取舍吧~

2018-01-14 · 1 分钟 · 37 字

【歌单】那些柔情的外文歌

平时用网易云音乐。要找我这里哦 偶尔也喜欢听一些外文歌,日语、韩语还有一些英文歌~

2017-12-10 · 1 分钟 · 2 字

【歌单】我喜欢的

平时用网易云音乐。要找我这里哦 读书时候已经积累听过好多好多歌了,周杰伦,林俊杰,梁静茹等大神的作品默认就已经被标记为我喜欢。因此歌单里不会将这些大神的作品列入其中了。歌单里一般是近期感觉还可以的歌。 希望大家喜欢。

2017-12-10 · 1 分钟 · 3 字

Squid使用SSLBump正向代理

背景:最近需要使用nodeJs访问一个历史久远的网站,那个网站的服务器证书是错误的,且使用的协议是TLSv1.0。浏览器上不得不使用IE并关闭各种安全设置和设置为兼容模式才能正常访问。Nodejs的新版本已经不支持这种不安全的协议,所以需要搭建一个代理服务进行访问。刚开始使用的是mitmproxy ,当时的最新版本对于SSL错误会报错,所以将源码中校验部分去掉就可以正常使用了。但部署到生产环境,会出现cpu占用过高的情况。所以后面换了Squid。 部署Squid参考了一篇文章,原文:here,下面是简单翻译。 Squid是个很强大的Web代理,它可以应用于无线认证、重定向、用户身份验证、日志记录等。但其在SSL方面一直存在局限性。在3.2版本之前,Squid的策略只是简单地传递SSL加密流量,因为它无法校验受信任的SSL链接。对于每个SSL连接也无法给用户做预警。但3.5版本后允许更多的控制,但要注意仍然无法校验受信任的SSL链接。 这里不会过多地介绍使用SSL Bump配置Squid以外的知识,对于编译和配置squid的细节你最好看下官方文档。 如果通过代理自动监测,通知浏览器连接到代理服务器,这样是挺简单的。但有些用户可能会试图规避这一点,并尝试直接连接。 在这种情况下,我们需要强制这些用户通过截取流量来使用代理。SSL Bumping的前提是中间人攻击,但由于这是在您的用户清楚所有流量都是检查过的环境中完成的,因此这并不是真正的攻击,这只是一种策略。Squid用于执行SSL Bumping有一些新方法,但是我会总结出最具实战性的方法:Squid收到一个https请求,然后为用户建立安全连接。 远程连接建立后,Squid会重新加密所有流量; 这时候的加密使用的是本地私钥,以及本地证书颁发机构即时创建出来的证书。 所以我们首先要确保的是你已经安装了3.5或更高版本的Squid。尽管3.2,3.3以及3.4版本也能实现,但3.5版本后SSL Bump的指令有了些显著变化。另外,编译Squid时需要带上‘–with-openssl’参数。 在CentOS我使用以下参数来编译Squid(foam:我带上–enable-ipf-transparent参数会报错,所以我是去掉再编译的) ./configure \ --prefix=/usr \ --exec-prefix=/usr \ --includedir=/usr/include \ --datadir=/usr/share \ --libdir=/usr/lib64 \ --libexecdir=/usr/lib64/squid \ --localstatedir=/var \ --sysconfdir=/etc/squid \ --sharedstatedir=/var/lib \ --with-logdir=/var/log/squid \ --with-pidfile=/var/run/squid.pid \ --with-default-user=squid \ --enable-silent-rules \ --enable-dependency-tracking \ --with-openssl \ --enable-icmp \ --enable-delay-pools \ --enable-useragent-log \ --enable-esi \ --enable-follow-x-forwarded-for \ --enable-ipf-transparent \ --enable-auth 接下来我们需要生成本地的SSL证书,这里我使用的是简单的命令,没有在意怎么去加密。 # Generate Private Key openssl genrsa -out example.com.private 2048 然后是创建Certificate Signing Request(CSR),即证书注册请求。 ...

2017-09-23 · 3 分钟 · 630 字

git clean

一句话描述 git clean的作用是: 删除工作目录中尚未添加到git版本控制的文件或目录。 使用场景 未添加到版本控制,且不在.gitignore中的,都是Untracked的状态。 有时候我们在项目中添加了些自己的临时文件、目录或临时脚本,用完成后想把它们删了。 有时候则是执行回滚后,有些文件或目录回滚到了Untracked状态,我们需要把它们删掉。 这时候就可以使用git clean。 用法 常用:git clean -df 路径[可选] usage: git clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>... -q, --quiet be quiet(静默删除,只会告诉你出错信息。如果是成功删除了文件或目录则保持沉默) -n, --dry-run dry run(告诉你会被删除的文件或目录有哪些,删除文件毕竟是一件严肃的事,在执行该命令前请务必加上该参数先确定下) -f, --force force(强制删除,clean.requireForce默认的值是true。这种情况下只有加上该参数才能删除) -d remove whole directories(删除的范围是整个目录) -x remove ignored files, too(即使是被添加进gitignore的文件或目录也删掉。这里有坑,下面说~) -X remove only ignored files(只删除被添加进gitignore的文件或目录) 预演:在执行该命令前,务必先加上-n以检查一遍要删除的文件清单。否则删除后要找回来也是挺麻烦的事~ 有坑 正常情况下,不加x参数,git clean是不会将ignore的文件或目录删除的。但是~!!如果你在.gitignore文件中对目录的描述是 dir/* 那么很抱歉,这个目录及里面的文件也会被清除掉。即使该目录的确是被git所忽略的。 所以,在.gitignore中对目录的描述最好是 dir1/ dir2 最后吐槽网上很多关于git clean的介绍(中文的)中,对-f参数的描述是file。但其实是force~

2016-08-05 · 1 分钟 · 63 字

设计模式之职责链

什么是职责链 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 例子一:支付宝的花呗自动还款扣款顺序 余额->借记卡快捷->余额宝 首先会从余额扣款,若余额不足或扣款失败则将扣款这一动作往后传递~ 例子二:备胎 母亲:闺女,你们也不小了。赶紧给我找个女婿,具体怎么找,你们自己决定。 大女儿:妈,别急,我正在找呢,我要求不高,对我好就行了。 小女儿:妈,我要求也不高,对我好也就可以啦~ 女生说要求不高,往往要求很高~ 哼.jpg。但女生说自己懒,往往就是真的懒。这不,找上我这个程序员了。 大小女儿:foam,你是学计算机的,除了修电脑,帮忙找备胎也是会的哈~ foam:说吧,什么要求 大女儿:我要求不高,只要对我好就可以了。但,有钱很重要~ 小女儿:我和姐姐一样,找个对我好的就行。但,长得帅很重要~ 大小女儿:还有其他不是要求的要求嘛,长得高的不能太瘦,比较矮的又不能太胖;理科生的话最好会点音乐,文科生则需要懂点修电脑 foam:(转身吐血)你们还会改需求吗~ 大小女儿:不会的 我知道,女生说不会,就是会! 于是我放弃了if…else的写法。 首先将备胎对象化是必须的。重要的是,给这些备胎串成一条链。每个节点,只要满足基本条件就返回给客户,否则往下传递,直到找到符合条件的备胎为止。 但,备胎的排序也是有条件的。大女儿说,最好有钱,那先将备胎们按身家排序,最有钱的排在链头,最穷的在链尾。小女儿的颜值要求也如法炮制。 用php简单实现的职责链demo <?php abstract class Handler { private $successor = null; final public function append(Handler $handler) { if (is_null($this->successor)) { $this->successor = $handler; } else { $this->successor->append($handler); } } final public function handle() { $processed = $this->processing(); if (!$processed) { if (!is_null($this->successor)) { $processed = $this->successor->handle(); } } return $processed; } abstract protected function processing(); } class AHandler extends Handler { public function processing() { echo 'A processing '; if (满足要求) { return true; } return false; } } class BHandler extends Handler { public function processing() { echo 'B processing '; if (满足要求) { return true; } return false; } } class CHandler extends Handler { public function processing() { echo 'C processing '; if (满足要求) { return true; } return false; } } class Client { private $_chain; public function init() { //例子一(花呗扣款): $this->_chain = new AHandler(); $this->_chain->append(new BHandler); $this->_chain->append(new CHandler); //例子二(备胎): $hanlerList = getManOrderByRich(); $this->_chain = new $handlerList[0]; for ($i=1;$i<count($handlerList),++$i) { $this->_chain->append(new $handlerList[$i]); } } public function doIt() { $this->_chain->handle(); } } $client = new Client; $client->init(); $client->doIt(); 对了,后来过了几天,大女儿来找我了。 大女儿:foam,我觉得钱不是最重要的,身高才是 foam:我知道了,你等我几分钟 …… 于是我这么改了下代码 ...

2016-06-10 · 2 分钟 · 218 字

App用户身份验证

安全问题 现在的移动互联网应用,大多是通过客户端带上数据请求不同动作的api来实现不同业务要求的。即是说,通过抓包就可以获取到请求的api和发送、接收到的数据。如果没有一定的安全防范意识,很容易被攻击。 这里推荐一款叫fiddler的抓包工具,使用方法自行搜索。下面是对车来了App的抓包截图: 没有使用https,所以数据完全暴露出来了。可以看到我经常坐的19路其中一辆公交还有12分钟到站。 用户身份验证 Web应用可以使用session来保存用户会话,App可没有这东西。 下面是一个很致命的设计: 只要带上userId,服务端就会为该用户执行操作。就是说任何人都可以假冒123这个用户执行一些操作。 嗯,打死都不承认上面这种设计我曾经写过。 其实参考session的实现原理就可以解决这个问题。大多数情况,Session都是结合客户端的Cookie来实现的。 Web中Session的实现: 1.用户的登录名、密码校验正确后,我们通常会将用户的一些信息存入到Session中。 2.此时服务端会生成一个全局唯一标识SessionID来标记这个用户生成的Session,并将该SessionID通过Set-Cookie回应给浏览器。 3.So,浏览器访问该网站的其他页面时只要带上了这个SessionID,服务端就知道它面对的用户存储在了哪个Session中,程序便可取出来用。 如何实现 那么移动端App怎么玩?与Web的Session是一样的,只不过我们要自己实现了。 简单实现 1.用户名密码校验无误后,生成UUID,存储到该用户记录中对应的字段中 2.将该UUID返回给前端(Android、iOS等) 3.App请求其他需要用户登录的接口时,带上该字段 4.服务端校验无误后方可继续执行业务 进一步完善以便实现其他需求的话,可以在生成UUID的同时,记录下用户ip、设备ID、过期时间等~ 如:发现设备ID与登录时的不同,要求其重新登录~ 当然,校验技术不可能是完美的,Hacker们有太多的方法骗过服务端。作为开发者,能做的是尽可能地提高验证水平和Hacker的破解成本;而作为用户,不要总想着蹭网啦,免费或虚假Wifi的后面可能有人正抓着包…

2016-03-13 · 1 分钟 · 24 字

memcache入门

写在前面 简介 memcache是一款开源软件,由LiveJournal的Brad Fitzpatrick开发,以BSD license授权发布。 是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个巨大的hash表,将数据(包括图像、视频、文件以及数据库检索的结果等)调用到内存中,然后从内存中读取,从而大大提高读取速度。 特性 非持久性存储 定位于分布式存储,不适用于单机系统 不支持List、Array等复杂的数据 Memcache和Memcached 这款开源软件的项目名叫Memcache,Memcached (Memcached-Daemon的简称) 是软件的主程序名。 在php中,有两个为memcache开发的扩展(客户端):Memcache扩展和memcached扩展。后者比前者要新,功能也比较多。推荐安装后者。 部署环境 安装memcache服务端 sudo apt-get install memcached #for Ubuntu yum install memcached #for CentOS 安装php扩展(客户端) 这里以安装memcached扩展为例,从官网下载最新版本,解压并cd到目录 wget http://pecl.php.net/get/memcached-2.2.0.tgz tar -zxvf memcached-2.2.0.tgz cd memcached-2.2.0 编译安装 phpize #生成configure配置文件。若找不到命令请用绝对路径 /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config #配置 make #编译 make install #安装。需要root权限 安装完后会提示安装的目录: Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/ 编辑php.ini文件 #找到extension_dir,如果没有设置扩展的路径,则把上面memcached.so所在的路径粘贴进去 extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/" #找到;extension=php_XXX.dll的地方,在最下面添加上 extension=memcached.so 最后,重启web服务器和php-fpm 看看phpinfo()是否将memcached添加成功。我这里为了做测试编译了两个扩展,实际编译后者就可以。 简单使用 这里只介绍php中memcached类的使用。更多请参考手册 <?php $md = new memcached; //向服务器池添加服务器,也可以使用addServers方法一次添加多个 //public bool Memcached::addServer ( string $host , int $port [, int $weight = 0 ] ) $md->addServer('127.0.0.1',11211); //$expiration默认为0,永不超时。但即使为0,当内存不够用的时候,memcache也会将不常使用的数据删掉 //expiration不能超过60×60×24×30(30天时间的秒数);如果大于这个值,服务端会将其作为一个真实的Unix时间戳来处理而不是 自当前时间的偏移 //public bool Memcached::add ( string $key , mixed $value [, int $expiration ] ) $md->add('addItem','this is content one by add'); $md->add('addItem','this is content two by add');//false.若使用add方法添加已经存在的key,无法添加成功 //public mixed Memcached::get ( string $key [, callback $cache_cb [, float &$cas_token ]] ) echo $md->get('addItem');//after add:this is content one by add //public bool Memcached::delete ( string $key [, int $time = 0 ] ) $md->delete('addItem'); echo $md->get('addItem');//空 //使用set方法重复添加同样的key是合法的,且后面的数据会覆盖前面的数据 //public bool Memcached::set ( string $key , mixed $value [, int $expiration ] ) $md->set('tip','hello');//tip='hello' $md->set('tip','world');//tip='world' //若使用追加方法,必须将OPT_COMPRESSION(压缩)设置为false $md->setOption(Memcached::OPT_COMPRESSION,false); $md->set('tip','hello');//tip='hello' //向指定元素后面追加一个字符串 //public bool Memcached::append ( string $key , string $value ) $md->append('tip',' world');//tip='hello world' $arr = [ 'name' => 'foam', 'age' => '22', ]; //同时存储多个数据 //public bool Memcached::setMulti ( array $items [, int $expiration ] ) $md->setMulti($arr); echo $md->get('name');//foam echo $md->get('age');//22 $md->set('count','-99');//count=-99 //自增 //public int Memcached::increment ( string $key [, int $offset = 1 ] ) $md->increment('count');//false.对于负数和非整数是无法自增的 $md->set('count',0); $md->increment('count');//count=1 $md->increment('count',100);//count=101 //自减 //public int Memcached::decrement ( string $key [, int $offset = 1 ] ) $md->decrement('count');//count=100 $md->decrement('count',50);//count=50 $md->decrement('count',60);//count=0.最小只能减到0 //清空所有数据 //public bool Memcached::flush ([ int $delay = 0 ] ) $md->flush(); $md->get('tip');//false $md->get('count');//false 其他 Memcache的分布式缓存 Memcache尽管说是分布式缓存服务器,但其分布式却是由客户端实现的。 保存数据时,客户端会根据数据的键使用特定的算法(不同的客户端,算法不同)选择要保存的服务器,将其存入其中。获取数据时也是使用相同的算法在所在的服务器获取。这些客户端算法一般在Hash的基础上进行改良,保证其数据的分散性。 具体策略就不展开说明了。 ...

2016-01-20 · 2 分钟 · 416 字