作者归档:Jacob Nie

教育与读书

一直没有人教过我要认清这两者有什么区别,而我也一直认为上学接受教育就是读书,而读所谓“课外书”就是不务正业,要读自己自己专业内的书籍。

从始至终没有人说这是一种错误的做法,因为我们所关心的就是成绩,成绩和相应的学分;只有这些东西学好了,才能够进入更好的学校,获得更大的奖励;这造就了以成绩为目标的学习氛围;我承认只读专业课对我的专业知识有很大的帮助,但同时又使的知识面极为局限,虽然深度有了(其实也并不很深入)但广度却丢了。而且让我损失最大的就是忘记了自觉的态度,自觉的态度是从教育中(至少是目前的教育)学不来的

为什么教学的过程中没人告诉你,其实人一生除了在学校学习以外,世界上更多的可能性,更多可以提升自己的机会,可能不被社会所认可,可能不是主流的上升渠道,可能会被埋没,但那也是一种上升渠道,是可能激发你自己潜能的一种上升渠道,可能是发挥你天才的一种上升渠道,可能是……这些无数的可能都被统一的“中国式教育模式”所淹没,何其可悲!

每个人都应该有自己的兴趣所在,每个人都应该从事自己所喜欢的事业,社会上不需要消极怠工,而需要积极探索,不需要荒废度日,而需要积极向上;每个人不需要做自己不喜欢的事情;而这一切,你都可能从书中得到答案,但绝不会从当今中国式教育中得到答案

读书吧,少年(每个人)

更换yum源

由于“距离”的原因,CentOS默认源更新会非常的慢,修改yum源的方法,执行以下命令就可以了:

  • cd /etc/yum.repos.d
  • mv CentOS-Base.repo CentOS-Base.repo.bak
  • wget http://mirrors.163.com/.help/CentOS6-Base-163.repo或wget http://mirrors.sohu.com/help/CentOS-Base-sohu.repo
  • 运行yum makecache生成缓存

小时代3:赤金时代

郭敬明的女性化思维

郭敬明应该有gay倾向,完全是臆测,没有完整读过他的小说,除了今天外没有完整看过他拍的爆红电影小时代系列,按照道理应该没有发言权,但是不幸的是今天却完整看了小时代3。四个女人一台戏,一桌麻将。男生都是“男神”系列?其实应该叫“郭敬明”系列,整部电影很难看到一个男人!富于心计的宫先生应该算一个。好戏就从四位女主角的学生时代开始了,有hold姐的出现还算是女生向中性化迈进了一部。

整部电影你很难搞清楚谁跟谁是一对,除了非常明确的杨幂与“亡夫”之间的戏份外。完全自恋式的出场,自恋式的罗马之行,自恋式的勇追抢包贼,nm这样的情节也太狗血了吧!一瞬间吧我们带回了蜘蛛侠的场景,而且是女飞侠!

整部电影里面的男人不男人,女人不女人的感觉,像极了小四

乏味的故事情节

故事情节比较拖沓,开始20分钟还不知道发生了什么,就开始了高潮一样的镜头了。女人做为主角固然可以,但是这里变成了女人的天国,连男人也变的女人起来,实在受不了。20多分钟过去了,竟然还让我有时间掏出手机看看新闻发发微博而不错过任何情节!

郭敬明大概以为自己在拍歌剧,也或者是受到了冰雪奇缘的影响,拍摄手法向迪士尼靠拢,也打造几曲能够一夜爆红的曲子,没想到却跟自己的剧情格格不入,让人觉得有严重拖戏的成分

总体故事也找不到主干,要说公司是主干,为毛四个人和好就结束了?如果四人是主干,那么剧情可以归纳外俗套的和分和的关系了

做作的表演

以前没有看过杨幂的表演,今天看来真是一般,各种哭泣的演的好假。想法郭采洁的小s式的表演倒给人留下了深刻的印象

各个gay们的表演都没有太多亮点,唯一能引起大家笑点的就是gay的关系吧

在大家都发现相互欺骗的时候,我们女主角的表现都非常的不符合情理和做作,不符合情理是作者的问题,而表演的做作就是演员的问题了。郭敬明应该觉得这样更能够博取眼泪和同情,结果却相反

上海的冬天有那么多雪吗?原来是小四要突出女主角的貂而特意安排的。但事实是上海没有那么冷,没有那么爱下雪

一两处的闪光点

很好利用了反差的效果:偷文件的情节还是让人大笑不止

总结

这片影评如果算的话完全主管态度写出来的,不代表任何人,甚至不代表未来的自己。

锤子手机问题分析

老罗应该是遇到困难了,生产线良品率低,生产速度蛮已经成了严重制约老罗的现实问题…

老罗有很多热情粉丝

老罗宣布了一个决定,说是预定不再需要预付300块的现金了。做这个决定老罗也有自己的想法,首先预定数,老罗说有20万,但据我估计不超过15万,加上最近风波退款,可能已经接近10万的安全线了。发布这个决定也是迫不得已,有以下好处

  • 可以部分保留现在向退款的用户;如果没有任何策略的话,现在每天的高退款率将成为现实,但是如果在退款的时候让用户可以选择退款而保留位置,相信大部分人都会保留位置的,要不要他们发货的时候再说,反正现在也不要钱
  • 增加300快商城补贴让曾经觉得锤子不划算的人心里有点安慰
  • 可以吸引原来观望的人来预定
  • 宣示出自己的坦诚,将问题暴露给大众,让大众了解机器生产的进度

老罗还有粉丝的优势,从微博的评论中可以看出,相当多的粉丝还是支持老罗的。老罗应该感到骄傲

锤子手机的缺陷

尽管有大量罗粉支持,但问题还是要指出来,锤子和老罗目前有以下问题需要解决

  1. 手机性价比不高。
  2. 不支持4G是最大缺陷。
  3. 出货太慢。
  4. 老罗先前把话说的太满了。
  5. 老罗应该做好自己的东西,少贬低别人的东西才能受到行业的尊重。
  6. 市场经济不能全靠个人粉丝而更应该靠产品粉丝

锤子科技的走向

基于以上的分析,还是不看好老罗以后的路,即使这次度过生产这一关,后面用户的忠实度还有待检验

DNS备份与恢复

有时候需要更换DNS服务器,做好备份与恢复工作显得比较重要,总结最近两次基于Windows DNS的备份与恢复过程,备忘

DNS备份

  1. win + r -> dnsmgmt.msc /s -> 右击机器名 -> 所有任务 -> 停止
  2. win + r -> regedit -> 查找HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\DNS,右击,导出,命名为dns1.reg。
  3. win + r -> regedit -> 查找HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DNS Server,右击,导出,命名为dns2.reg。
  4. win + r -> system32 -> 拷贝dns目录下.dns结尾的文件并保存

DNS的恢复

  1. win + r -> dnsmgmt.msc /s -> 右击机器名 -> 所有任务 -> 停止
  2. 把所有后缀为.dns的文件复制到这台机器的%system32%\dns文件夹下。
  3. 将dns1.reg和dns2.reg的文件。双击它们,一次一个,并且确认自己想把它们安装到注册表中。
  4. 重新启动DNS服务。

舍本逐末–markdown探索

困扰原因

我要的是多看书,多写,但是现在给我的困扰是因为工具而工具。Windows当然没的说,sublimetext还是很给力,但是移动到手机上各种问题就来了,究竟应该怎样连我自己也说不清楚

软件对比

如果论软件的美观程度。iA Writer还是非常小清新的,当然还有另外一个叫md的软件做格式化会非常的不错,但具体到怎么发表就有很大的分歧。还有几款软件有点喧宾夺主的感觉,涉及很好的head list等选项,其结果还是成了一个文本编辑器,背离了markdown设置的初衷

如何发表

首先,图片的问题很难办,md的最大弱势就是无法很好处理图片文件,我想是否开一个ftp,使用手机的ftp管理软件来上传图片,但又涉及到图片的处理问题,所以很难办。后来又想到Wordpress客户端可以直接上传图片,于是想将iA Writer的内容分享到Wordpress,然后再Wordpress做图片插入和发布的操作,但是现在问题又来了,Wordpress现在是不可用的状态,App Store里面评价一颗星作者竟然置之不理,实在令人无语。现在能想到的妥协办法就是使用手机web版发表纯文字的信息,遇到图片的时候只好到pc上处理一下,我想如果能遇到图片的时候也是基本上不会再手机上写作的文字

手机markdown app设想

其实我们要的非常简单,将markdown 常用的字符放到常用的地方,什么预览分享都可以不要,另外还需要大文本管理的能力,不能在写小说的时候经常crash,那样会令人崩溃的

总结

现在markdown还基本流行于开发人员,所以大家可以和Github结合起来使用,可以不追求手机的通用性,如果markdown要推广,势必还是要做一些多设备适配

[转]Chrome 远程调试协议分析与实战

背景

某一天,A 君想获取 Chrome 页面中的性能数据,诸如时间、白屏和首屏等,因为需要和竞品进行对比分析,无法注入代码,该怎么办?

此时,你也许能想到开发者工具(DevTools),也许知道Timeline(包含浏览器完整的行为数据),该怎么自动获取到 Timeline 数据呢?

开发者工具

开发者工具(DevTools)是一个独立的 Web 应用程序(HTML+CSS+Javascript),被集成在浏览器中,通过远程调试协议(remote debugging protocol)和浏览器内核进行交互,直接使用 Ctrl+Shift+I 呼出。

devtools

可以在当前的浏览器页面直接打开 DevTools 调试,也可以在浏览器之外进行调试,本文的实战内容基于 PC 平台浏览器之外的远程调试。

远程调试协议

远程调试协议基于 WebSocket,利用 WebSocket 建立连接 DevTools 和浏览器内核的快速数据通道。DevTools 中的源代码(Main.js:220)如下:

var ws;
if ("ws" in WebInspector.queryParamsObject)
    ws = "ws://" + WebInspector.queryParamsObject.ws;
else if ("page" in WebInspector.queryParamsObject) {
    var page = WebInspector.queryParamsObject.page;
    var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
    ws = "ws://" + host + "/devtools/page/" + page;
}

该协议把操作划分为不同的域(domain),比如 DOM、Debugger、Network、Console 和 Timeline 等,可以理解为 DevTools 中的不同功能模块。

每个域(domain)定义了它所支持的 command 和它所产生的 event。

每个 command 包含 request 和 response 两部分,request 部分指定所要进行的操作以及操作说要的参数,response 部分表明操作状态,成功或失败。

command 和 event 中可能涉及到非基本数据类型,在 domain 中被归为 Type,比如:’frameId’: <FrameId>,其中 FrameId 为非基本数据类型

至此,不难理解:

domain = command + event + type

远程调试协议应用场景

  • 针对移动端的远程调试,因为移动平台一般都不会提供足够大的区域来显示 DevTools,必须要在手机浏览器之外进行远程调试,具体配置请参看这篇文章

  • 获取 JS 的Runtime数据,常用的如window.performancewindow.chrome.loadTimes()

  • 获取NetworkTimeline数据,进行自动性能分析

  • 与强大的phantomjs合体,phantomjs 暂时只支持基于 remote debugging protocol 的调试,希望能支持 Network 及 Timeline 数据的获取,phantomjs 的最新技术请点击进入

远程调试协议结构

以 Page domain 为例

command 结构如下:

Page.navigate
request: {
    "id": <number>,
    "method": "Page.navigate",
    "params": {
        "url": <string>
    }
}
response: {
    "id": <number>,
    "error": <object>
}

执行 Page.navigate 操作,需要参数 url,id 可以随意指定,不过要确认全局的唯一性,因为需要通过 id 关联 request 和 response。

event 结构如下:

Page.loadEventFired
{
    "method": "Page.loadEventFired",
    "params": {
    "timestamp": <number>
    }
}

Page domain 派发 loadEventFired 事件结构数据(通过 WebSocket 的 onmessage 获取),并包含参数 timestamp

type 结构如下:

Frame: object
    id ( string )
        Frame unique identifier.
    loaderId ( Network.LoaderId )
        Identifier of the loader associated with this frame.
    mimeType ( string )
        Frame document's mimeType as determined by the browser.
    name ( optional string )
        Frame's name as specified in the tag.
    parentId ( optional string )
        Parent frame identifier.
    securityOrigin ( string )
        Frame document's security origin.
    url ( string )
        Frame document's URL.

Frame type 为包含 id,loaderId,mimeType,name,parentId,securityOrigin 和 url 字段的 Object 数据类型,其中 loaderId 为另外一个定义在 Network domain 中的 type

更多协议内容请猛戳这里

远程调试协议实战

此协议用于 server 端和 client 端的通讯,所以需要先建立 server 端,然后 client 端通过协议连接到 server 端

开启 server 服务

打开浏览器的远程调试支持,并指定端口号:

./chrome --remote-debugging-port=9222

./chrome 为已安装的 Chrome 可执行程序

获取 server 地址

在浏览器中直接输入:

http://localhost:9222/json

获取所有的 tabs 信息,数据格式如下:

[
    {},
    {},
    {}
]

每个 {} 的内容如下:

{
    description: "",
    devtoolsFrontendUrl: "/devtools/devtools.html?ws=localhost:9222/devtools/page/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F",
    faviconUrl: "http://www.baidu.com/favicon.ico",
    id: "A12A4B08-E5AF-4A84-A86A-A1C86E731D7F",
    thumbnailUrl: "/thumb/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F",
    title: "百度一下,你就知道",
    type: "page",
    url: "http://www.baidu.com/",
    webSocketDebuggerUrl: "ws://localhost:9222/devtools/page/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F"
}

websocket server 端地址:

webSocketDebuggerUrl: "ws://localhost:9222/devtools/page/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F"

建立连接

在任意地址栏中输入 http://localhost:9222 + devtoolsFrontendUrl 值即可(等同于在当前页面直接打开 DevTools):

http://localhost:9222/devtools/devtools.html?ws=localhost:9222/devtools/page/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F"

或直接使用 WebSocket 连接,使用 webSocketDebuggerUrl 值连接:

var ws = new WebSocket('ws://localhost:9222/devtools/page/A12A4B08-E5AF-4A84-A86A-A1C86E731D7F"');

注意:每次只能进行一次 WebSocket 连接,之后的连接都会失败

调用 Command

WebSocket 通道建立完成之后,通过如下方式进行调用:

打开指定页面,并进行事件监听(以 Page.loadEventFired 为例):

ws.onmessage = function(event) {
    console.log(event.data);
};
ws.send('{"id": 1, "method": "Page.navigate", "params": {"url": "http://www.baidu.com"}}')

获取到的 loadEventFired 事件数据如下:

{"method": "Page.loadEventFired", "params": {"timestamp": 1402317772.874949}}

更多连接方式

nodejs ws

非常轻量级的 WebSocket 库,支持 client 端和 server 端,使用方式基本同 HTML5 的标准 WebSocket 库

client 示例:

var WebSocket = require('ws');
var ws = new WebSocket('ws://www.host.com/path');
ws.on('open', function() {
    ws.send('something');
});
ws.on('message', function(data, flags) {
    // flags.binary will be set if a binary data is received
    // flags.masked will be set if the data was masked
});

server 示例:

var WebSocketServer = require('ws').Server
      , wss = new WebSocketServer({port: 8080});
    wss.on('connection', function(ws) {
        ws.on('message', function(message) {
            console.log('received: %s', message);
        });
        ws.send('something');
    });

请移步:官方 ws 库

nodejs chrome-remote-interface

一个实现了 remote debugging protocol 的 nodejs 库,其中 WebSocket 使用的是 ws 库,使用方便,推荐使用

示例代码:

var Chrome = require('chrome-remote-interface');
Chrome(function (chrome) {
    with (chrome) {
        on('Page.loadEventFired', function(time) {
            send('Runtime.evaluate',{'expression': 'chrome.loadTimes()', returnByValue: true}, function(err, result) {
                //console.log(err, result );
            });
        });
        Page.enable();
        Page.navigate({'url': 'http://www.baidu.com'});
    }
});

请移步:官方 chrome-remote-interface

nodejs socket.io

功能强大,支持集成 WebSocket 服务器端和 Express3 框架与一身,使用简单,有兴趣者请移步:官方 socket.io

WebSocket

协议

它是 HTML5 一种新的协议,实现了浏览器与服务器全双工通信,只需要一个握手动作,浏览器和服务器之间就形成了一个快速通道,然后进行数据互传。

优点:

1、交互时的 header 只有约 2Bytes
2、服务端可以主动推送数据给客户端

header 格式(握手时):

request:

Cache-Control:no-cache
Connection:Upgrade
Host:localhost:9222
Origin:http://family.baidu.com
Pragma:no-cache
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
Sec-WebSocket-Key:TKSQVug6zSIH4uzIyTYBcg==
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1914.0 Safari/537.36

response:

Connection:Upgrade
Sec-WebSocket-Accept:HyjfMUpyYgWgkYLn/vDDf6rZLuk=
Upgrade:WebSocket

header 格式(交互时):

request:

User-Agent: Fiddler
Content-Type: application/json; charset=utf-8
Host: fakewebsocket
Content-Length: 211

response:

FiddlerTemplate: True
Date: Fri, 25 Jan 2013 16:49:29 GMT
Content-Length: 51

查看 WebSocket 连接

DevTools

直接使用 DevTools,在控制台建立 WebSocket 连接并交互,在 Network 面板中直接显示

fiddler

fiddler

自定义 fiddler 的规则,根据 WebSocket 特征提取信息并伪造 WebSocket 结构数据

因为伪造时,host 为 fakewebsocket,无法识别,所以通过 AutoResponder 伪造 respose 数据

请移步:Debug / Inspect WebSocket traffic with Fiddler

优化方向 优化手段
请求数量 合并脚本和样式表,CSS Sprites,拆分初始化负载,划分主域
请求带宽 开启 GZip,精简 JavaScript,移除重复脚本,图像优化
缓存利用 使用 CDN,使用外部 JavaScript 和 CSS,添加 Expires 头,减少 DNS 查找,配置 ETag,使 AjaX 可缓存
页面结构 将样式表放在顶部,将脚本放在底部,尽早刷新文档的输出
代码校验 避免 CSS 表达式,避免重定向

更多参考

原文

救不活的Blogger

本来还想使用Blogger+Gmail的方式来更新博客,因为实在太喜欢Gmail的写作方式了,但试了一下,基本不可行;Bolgger里面有太多Google CDN的引用,删除删掉了很多不可以打开的元素,但像基本的脚本和Bolgger统计的脚本实在没办法删掉,然后在一台没做任何设置的国内环境IE浏览器上查看,惨不忍睹!

速度慢,资源加载不过来,搜索框不可用,这些都没有更好的办法解决,相反,倒很喜欢Fex的代码博客风格,可以不用管样式,不用管图片,不用管任何显示方面的东西,使用MarkDown,简洁,快速;最终显示的页面也是我乐于看见的;但也有他自己的问题,不喜欢他的首页,除了使用搜索引擎来做检索外没有什么太好的方式来检索;不喜欢首页的显示方式,不喜欢列表页的翻页方式,不喜欢导航栏;

刚刚使用google-code-prettify重新高亮了相关语法,虽然比不上SyntaxHighlighter,也可以使用了,反正以后如果实在不行的话,就再换成SyntaxHighlighter;

现在wordpress安装了MarkDown的相关编辑器,可以部分实现使用MarkDown写博客的要求,已经是一大进步了;所以也就不再管Blogger了

恢复Mysql数据

今天由于误操作,需要更换操作系统,然而Mysql的数据并没有做定期的备份,只能拿到数据库原始的格式,需要恢复,大概需要以下几步:

  1. 找到Mysql的data目录
  2. 将wordpress目录(是你要恢复的目录)和ibdata1两个文件拷贝出来
  3. 安装跟原来数据相同版本的Mysql
  4. 将上述两个文件拷贝到新数据库的data目录下
  5. 删除新数据库的ib_logfile0和ib_logfile1两个文件
  6. 重启新数据库
  7. 使用客户端或mysqldump备份数据库成wordpress.sql

恢复有点麻烦,新装的数据也只是用来恢复,并不能正式使用,正式使用最好还是将备份出来的wordpress.sql恢复的一个新的数据库;所以还是要做好定时备份的工作,以防硬盘都坏掉的情况发生

备份方法

backup.bat

@echooff
set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%"  
c:\path\to\mysqldump wordpress > d:\path\to\dmp\wordpress_%Ymd%.sql  

my.ini设置

[mysqldump]  
user=root  
password=password  

Github Pages使用小记

很早就知道有这个东西了,以前也没在意,最近看到fex.baidu.com这么流逼的博客也是使用Github Pages来写的,就有了想使用的冲动,于是动后做了blog.keliusoft.com

但我觉得主要有以下几个不好使用的地方:

1、给的模板没办法分页
2、没办法检索
3、没办法使用Tag
4、还不知道怎么使用分类
5、只能在装有Git的电脑上使用,基本上限定了在自己的机器上使用

以上是目前遇到的问题,基于此,我想我不会这么快把自己的博客放到这上面的,不然要做出的改变太大了。在新建的博客中,还遇到了TortiseGit不能使用SSH更新的问题,我使用PuttySSH生成的KEY竟然不认,下面是解决的方法:

1、使用Puttygen(开始菜单->TortoiseGit目录下有)生成id_isa.pub和id_isa.ppk,保存在一个目录里面
2、将id_isa.put的数据拷贝到GITHUB
3、在项目目录里面打开TortoiseGit的Setting,选择Remote,把URL改成git@github.com:的形式,另外在Putty里面选择前面保存的id_isa.ppk

这时就不需要输入密码就可以直接提交代码了,以后博客更新起来也方便,相对而言还安全一些

做完了以下的记录,我觉得做一个博客最重要的还是要发表自己的思想,总结自己的看法,所以现在我写东西基本都在文本文件里面完成,把整个框架完成了以后,需要添加图片或者格式化的时候再统一完成,并不是边写边格式化出来的;这样做的效率不会比MarkDown差多少,所以我认为我们没有必要花太多时间去记一些MarkDown的语法;当然如果经常使用Github或者StackOverflow的话,基本的设置还是要会的;

Github Pages的几个优势:

1、服务托管到Github,不担心服务器压力
2、基本上都是生成的静态页面,不需要太多的开销
3、图片文件提交十分方便,直接丢在images目录里面,引用一下就OK了

这是一个见仁见智的过程,如果你觉得能接受全部的缺点或者找到相对合理的解决办法,你就使用,否则还是用自己的Wordpress吧;

其实刚开始的想法是使用zybuluo.com的超级棒的MarkDown编辑器为我服务的,但想了想自己这边工作量挺大的,另外如果zybuluo那边做了调整,我这边势必还要修改代码,比较麻烦