烟花易冷创作背景

《烟花易冷》,又名《伽蓝雨》(qie,二声)-流行天王周杰伦的代表作之一。2010年发布。发布之时,也没有觉得这首歌有多么起眼。也是最近几年听了才觉得有味道。

1
2
3
4
5
6
7
雨纷纷 旧故里草木深
我听闻 你始终一个人
斑驳的城门 盘踞着老树根
石板上的回荡是 再等...
缘份落地生根是 我们
伽蓝寺听雨声盼 永恒
-- 节选自《烟花易冷》

歌词优美。这绝不像是凭空臆造的诗情画意。这词的意境大有来头,且听我娓娓道来。

东汉末年分三国,后来司马家族苦心经营,历经三代,由司马懿之孙司马炎于公元280年灭亡东吴,至此三国归晋,可惜好景不长。公元290年,司马炎中风病逝,把天下留给了”傻儿子”司马衷-是为晋惠帝,外戚专权、八王之乱、西晋王朝风雨飘摇,316年晋王朝被匈奴人刘曜所灭。为维持统治,晋朝宗室司马睿南迁建康,重建晋王朝,史称东晋。南方政局相对稳定。而北方中原大地则伴随晋王朝的风雨飘摇,进入历史上最黑暗的”五胡十六国”时期。

这期间北方中原地区以匈奴、鲜卑、羯、羝、羌为主,建立了大大小小的割据政权,远远不止五胡,十六国,各个政权相互厮杀,引来民族混战、大量无辜平民被屠杀,学者普遍认为这段时期汉民族频临灭族、汉文化濒临灭绝。

北方汉人为避战乱,保全性命,大量南渡,史称”衣冠南渡”。偏安一隅的东晋朝廷为了安抚侨民及侨姓世族,设置了侨州郡县。等到安定后使其州郡领有实地,户籍和赋役与一般州郡县相同。北方流亡的汉人才得以保全并安定下来。

而北方直到公元439年,北魏拓跋焘统一北方才结束了这长达一百多年的战乱。

可以说南方的东晋政权和北魏的一统北方对延续汉民族、中华文明起到了决定性作用。虽然北魏统治者是鲜卑人,但鲜卑人统治中原之后极力融入汉民族,缓和民族矛盾。尤其北魏孝文帝-拓跋宏大刀阔斧的进行汉化改革,为了更好的统治中原,公元496年从平城(今山西大同)迁都洛阳,在位期间采取一系列措施促使北方社会经济有了明显发展,加速了北方各少数民族的封建化进程,对北魏社会政治生活乃至整个中国历史产生了深远的影响。最主要的影响是促进了民族的交流和融合,为日后的隋文帝杨坚结束魏晋南北朝以来长期分裂局面,重新走向国家统一奠定了坚实的基础。

好,说了这么多,跟烟花易冷的歌词并没有扯上关系。且耐心看下去。

话说北魏自386年拓跋珪建立,至439年拓跋焘统一北方,再到拓跋宏496年迁都洛阳,北方从战火中回归太平、经济得到很大的恢复与发展,洛阳也重现了往日的繁华。公元534年北魏分裂为东魏西魏。

东魏定都邺城,西魏定都长安,而北魏原都城洛阳陷于兵燹(xian,三声),繁华之地,成为废墟。公元547年(东魏武定五年),一个叫杨炫之的人,因公务路过洛阳,面对繁华名都在现实中却是”城郭崩毁,宫室倾覆,寺观灰烬,庙塔丘墟”的凄凉景象,感慨伤怀,遂因作一传世之作 –《洛阳伽蓝记》。

《洛阳伽蓝记》故事里所描述的是那个盛极繁华后倾塌颓圮的千年古都洛阳城中,一名皇家将领与其所倾慕之女子间的爱情故事。

该名将领因缘邂逅女子后,俩人一见钟情并且私定终身,此时将领却被朝廷征调至边境征战,在连年的兵荒马乱中,帝都洛阳已沦为废墟,残破不堪,最后女子苦守城门等待将领。而将领则委身于伽蓝寺中,待战事平息将领出伽蓝古寺,她却早已过世。将领只有听伽蓝古寺外,雨纷纷落下,回想起羡煞旁人的当年,叹人事,不过如烟花般,易冷,易分……

方文山写的由周杰伦演唱的这首《烟花易冷》就是以这本《洛阳伽蓝记》为背景而创作的歌曲。

《洛阳伽蓝记》有不少传说典故,蕴涵着的文学笔触,将朝代历史地理人文融入其中,独特的近似纪录片的镜头,与郦道元的《水经注》并称”北朝文学双璧”。另外《洛阳伽蓝记》与《水经注》、《齐民要术》合称北魏三大奇书。

烟花易冷的创作背景,你了解了吗?

正则表达式总结

正则表达式创建一个正则表达式

你可以通过下面两种方法创建一个正则表达式:

使用一个正则表达式字面量,如下所示:

1
var re = /ab+c/;

正则表达式字面量在脚本加载后编译。若你的正则表达式是常量,使用这种方式可以获得更好的性能。

调用RegExp对象的构造函数,如下所示:

1
var re = new RegExp("ab+c");

使用构造函数,提供了对正则表达式运行时的编译。当你知道正则表达式的模式会发生改变,或者你事先并不了解它的模式或者是从其他地方(比如用户的输入),得到的代码这时比较适合用构造函数的方式。

正则表达式支持的字符转义

字符或序列 描述
除以下字符外的所有字符:。 $ ^ { [ ( \ ) * + ? \ “字符或序列”列中未包含的字符在正则表达式中没有特殊含义;此类字符与自身匹配。”字符或序列”列中包括的字符均为特殊的正则表达式语言元素。若要在正则表达式中匹配这些字符,必须将其转义或纳入 positive 字符组。例如,正则表达式 \$\d+ 或 [$]\d+ 匹配”$1200”。
\a 匹配响铃(警报)字符,\u0007。
\b 在 [character_group] 字符类中,匹配退格,\u0008。(请参阅字符类)。)在字符类之外,\b 是匹配字边界的定位点。(请参阅定位点)。
\t 匹配制表符,\u0009。
\r 匹配回车,\u000D。请注意,\r 不等同于换行符,\n。
\v 匹配垂直制表符,\u000B。
\f 匹配换页,\u000C。
\n 匹配换行,\u000A。
\e 匹配转义,\u001B。
\ nnn 匹配 ASCII 字符,其中 nnn 包含表示八进制字符代码的两位数或三位数。例如,\040 表示空格字符。如果此构造仅包含一个数字(如 \2)或者它对应捕获组的编号,则将它解释为向后引用。(请参阅反向引用构造)。)
\x nn 匹配 ASCII 字符,其中 nn 是两位数的十六进制字符代码。
\c X 匹配 ASCII 控制字符,其中 X 是控制字符的字母。例如,\cC 为 CTRL-C。
\u nnnn 匹配的 UTF-16 代码单元,单元值是 nnnn 十六进制。
\ 后接字符未识别为转义字符时,将匹配此字符。例如,\* 匹配星号 (*) 并等同于 \x2A。

RegExp对象方法

  • exec
  • test

String内置构造函数方法

  • match
  • search
  • replace
  • split

列举日常使用的正则表达式匹配

匹配url参数:key需要传入

1
/[?&]"+ key +"=([^&]*)/

匹配邮箱:

1
/^[a-zA-Z0-9][a-zA-Z0-9._-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/

身份证:

1
/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X|x)$/

html标签:

1
2
3
/<[^>]+>/ 
// 或
/<[a-z|/|A-Z]+>/

浏览器从输入URL到显示总结

一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?(流程说的越详细越好)

注:这题胜在区分度高,知识点覆盖广,再不懂的人,也能答出几句,而高手可以根据自己擅长的领域自由发挥,从URL规范、HTTP协议、DNS、CDN、数据库查询、到浏览器流式解析、CSS规则构建、layout、paint、onload/domready、JS执行、JS API绑定等等;

详细版:

  1. 浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;
  2. 调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;
  3. 通过DNS解析获取网址的IP地址,设置 UA 等信息发出第二个GET请求;
  4. 进行HTTP协议会话,客户端发送报头(请求报头);
  5. 进入到web服务器上的 Web Server,如 Apache、Tomcat、Node.JS 等服务器;
  6. 进入部署好的后端应用,如 PHP、Java、JavaScript、Python 等,找到对应的请求处理;
  7. 处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回304;
  8. 浏览器开始下载html文档(响应报头,状态码200),同时使用缓存;
  9. 文档树建立,根据标记请求所需指定MIME类型的文件(比如css、js),同时设置了cookie;
  10. 页面开始渲染DOM,JS根据DOM API操作DOM,执行事件绑定等,页面显示完成。

简洁版:

浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;
服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
载入解析到的资源文件,渲染页面,完成。

tmux handle

tmux 操作基本操作:

  • ? 列出所有快捷键;按q返回
  • d 脱离当前会话,可暂时返回Shell界面,输入tmux attach能够重新进入之前会话
  • s 选择并切换会话;在同时开启了多个会话时使用
  • D 选择要脱离的会话;在同时开启了多个会话时使用
  • : 进入命令行模式;此时可输入支持的命令,例如kill-server所有tmux会话
  • [ 复制模式,光标移动到复制内容位置,空格键开始,方向键选择复制,回车确认,q/Esc退出
  • ] 进入粘贴模式,粘贴之前复制的内容,按q/Esc退出
  • ~ 列出提示信息缓存;其中包含了之前tmux返回的各种提示信息
  • t 显示当前的时间
  • Ctrl+z 挂起当前会话

窗口操作:

  • c 创建新窗口
  • & 关闭当前窗口
  • 数字键 切换到指定窗口
  • p 切换至上一窗口
  • n 切换至下一窗口
  • l 前后窗口间互相切换
  • w 通过窗口列表切换窗口
  • , 重命名当前窗口,便于识别
  • . 修改当前窗口编号,相当于重新排序
  • f 在所有窗口中查找关键词,便于窗口多了切换

面板操作:

  • " 将当前面板上下分屏
  • % 将当前面板左右分屏
  • x 关闭当前分屏
  • ! 将当前面板置于新窗口,即新建一个窗口,其中仅包含当前面板
  • Ctrl+方向键 以1个单元格为单位移动边缘以调整当前面板大小
  • Alt+方向键 以5个单元格为单位移动边缘以调整当前面板大小
  • 空格键 可以在默认面板布局中切换,试试就知道了
  • q 显示面板编号
  • o 选择当前窗口中下一个面板
  • 方向键 移动光标选择对应面板
  • { 向前置换当前面板
  • } 向后置换当前面板
  • Alt+o 逆时针旋转当前窗口的面板
  • Ctrl+o 顺时针旋转当前窗口的面板
  • z

卸磨杀驴-换了vscode吐槽atom

前一段时间一直夸赞atom多么好用,并亲切的称之为’阿童木’。还是逃不过喜新厌旧的历史规律(什么狗屁历史规律)

atom足够优秀,但是插件数量达到一定数量后打字都会卡。而且在我体验atom的4个月的时间里。也发现了一些小问题。

我之前特别抵触vscode,可能是微软产品的缘故吧。。。机缘巧合,17年大年初二走完亲戚后浏览掘金稀土发现了一片软文《为什么我从 Sublime Text 跳槽 Visual Studio Code?》才让我放下对微软的成见并意识到我该换个IDE使使了。

新年上班第一天,各位新年快乐啊。吐槽atom、属予作文以记之。由此进入正文。

react-native学习日记

前端领域发展之迅速,令人瞠目结舌。

如果你心目中的前端就是html css jquery这些东西的话,在我心中,那是上个世代的前端。但我不骗你,这样的前端目前仍然是主流需求。

很多朋友跟我说html+css+js很简单啊,我上学的时候就学过。是啊,你给我讲讲浏览器渲染dom的过程吧。你应该很精通了吧。如果你说,这个过程是这样滴:

  1. 计算CSS样式
  2. 构建Render Tree
  3. Layout – 定位坐标和大小,是否换行,各种position, overflow, z-index属性 ……
  4. paint 开始画

好的,你还不错嘛,来来来,再来聊聊 Reflow 和 Repaint吧?越详细越好、说重点、不得少于800字,呵呵呵。

dom的东西太多,创建一个dom属性和方法一共228个(嗯?一个div是这样的吧)聊太多我怕把你聊哭。

你说dom太小儿科,来点稍微高大上的东西吧。聊聊 Cascading Style Sheets?嗯。讲一下css优先级?水平三栏布局写三种实现?不许用table、inline-block!!!聊聊 block formatting context?写css的人怎么能没用过sass和less,哦在sass里写个函数,定义几个变量真的可以让共用的css调用起来更加方便,最近貌似一个叫PostCSS的家伙挺火,因为vue-loader?

与时俱进,前端逐渐从pc端转换到移动端

移动端适配是个大问题。不知道REM适配你能算个前端?稍微有点逼格的公司的UI出图的时候都会给前端3倍dpr和2倍dpr的图各一张。移动端用户体验节省流量同样重要,你来做下适配?你不知道什么是dpr?物理像素和设备独立像素知道?等一下,设计师过来告诉你说1px怎么这么宽,你来适配一下?卧槽?1px?我这就是写的1px啊!!!适配个屌啊?怎么适配?嗯,google上适配Retina屏1px线的文章一抓一大片哦。

一些基础css东西我不会又有什么关系呢?我照样可以干活,嗯。我一个小小样式冲突就可以让你盯着屏幕瞅一天。

嗯。该聊聊js了,哦不,应该叫ES6,是啊。现在还有几个人不用ES6啊。但是大多数浏览器对ES6支持不是很完善,chrome也是如此,你需要用babel转一下,babel5和babel6是不一样的哦。你需要配置前端自动化工具,gulp、webpack、grunt你值得拥有。结合jquery/zepto用起来更流弊?写个ajax回调分分钟进入回调地狱,啥?用window.fetch结合promise,再牛逼的你可以用generator啊。浏览器不支持咋办?用polyfill啊。人家说都2017年了,你还用jquery/zepto?没用过vue+vuex/react+redux你好意思说你是做前端的?你们还跟我聊MVC架构?我日,前端都分MVVM啦。

你所谓的前端html+css+js就上面这些?嗯。恭喜你,你可以进入一家公司实习了。

经过这么多年发展,js已经可以运行到几乎所有平台了,嗯!!!之前的报道JavaScript 统治的世界,烤面包机将能运行 JS 了,这并不是噱头。js要统治世界了JavaScript 就要统治世界了?,话虽然说的比较绝对,毕竟近几年的的js发展势头喜人。

在我看来,成为一个合格的初中级前端工程师,要集 知识广度&&代码能力&&艺术美感 于一体,为了达成这个目的,你至少还要具备如下技能:

作为一个前端,你怎么能不会切图?基础的ps操作?
npm玩的6吗?nrm是个啥?nvm/n呢?
yarn有什么优势?yarn.lock 对比 npm-shrinkwrap.json 有什么进步?
怎么优化dom加载?react/vue的 virtual dom 怎么实现的,jsx是什么?
如何提高用户访问网站的响应速度?CDN是什么?
说说http请求?http和https的区别?
http缓存是怎么回事?
webapp的登陆状态如何与客户端保持一致?
webapp如何与客户端native通信?
cookie与localStorage/sessionStorage有什么异同?
说说window.history对象吧。history.pushState和history.replaceState有什么区别
听说过hjax吗?pjax呢?
webapp单页面应用如何解决seo问题?
hybrid开发模式优缺点?
phoneGap和React Native有什么本质区别?
React Native相对于纯native app有什么优缺点?
会写动画吗?能用canvas写一个愤怒的小鸟吗?熟悉svg吗?
RESTful接口前端渲染界面 VS server端渲染界面 的优点。
让一个网站同时支持pc端&手机端,你有几种方案?
linux shell基本操作会吧?chmod 571 file.js 是什么意思?
用过express吧?怎么把你的个人网站部署到服务器?
如果让你做自己的个人网站,如何进行用户权限管理?
了解mongoDB吗?什么是关系型数据库?
用过mysql吗?如何做msyql的io方面优化?
如果要做一个商品的秒杀功能,为避免客户端重复下单(前一段时间的阿里月饼事件),你会怎么限制?你如何去跟服务端沟通?
写过爬虫吗?分析一下爬虫的原理。为什么要爬虫?
node & python 爬虫的优缺点。
什么是跨域?前端跨域的几种方式。
jsonp跨域的实现原理。有什么缺点?
XSS攻击的原理?如何防御?什么是CSRF攻击?怎么防御?
iframe还有应用场景吗?
用过zsh?zsh对比bash有哪些优点?
用过atom吗?atom是怎么用什么语言开发的?
git&svn的使用经历?对比一下各自的优缺点?
用过那些好用的git&svn的图形化工具?
fiddler&charles&wireshark都用过吗?怎么抓包https?
开发webapp如何在设备上调试
喜欢写markdown吗,用过哪些好用的书写markdown的工具?
有没有做过微信开发?说一下微信开发的认证流程。

暂时就想到这么多,随着阅历增加,会不断补充。这不,写这么多就是个引子,就是为了说明,前端工程师能做的事情还是很多的,不要妄自菲薄。作为一个涉事不深的前端工程师,应该有足够的自学动力、没有这股动力去探索未知的领域,凭什么去涨薪拿什么去买房子?(认真脸)土豪请忽略。

最近一直琢磨如何用webapp跟native进行交互,我寻思要想深刻理解,不仅要在项目中推敲,有条件的话还是自己写native模拟一下,嗯。如果RN足够熟练了,可以放弃RN直接上手swift。祝好~

开始我的RN踩坑之旅~

RN学习第一弹 -react-native 入坑之 hello world demo

使用python爬虫小记

奉上python爬取糗事百科用户头像源码github地址

代码实现的比较简单,通过此次爬虫学习,毕竟粗略的看了一部分python语法,深深的感受到了python语法的魅力。因为在上家公司时用过coffee script,那时候就对coffee简介的语法喜欢的一发不可收拾,得知 coffee就是借鉴了python的语法。如今亲手写python爬虫,更是有种似曾相识的感觉。连python的基本用法都没有掌握全的我,就在心里种下了 python是世界上最好的语言想法,哈哈,就是这么快就把我大js给出卖了~~

解决高度塌陷

如上图,给父元素设置边框不能把两个浮动的子元素包裹起来,俗称高度塌陷。解决高度塌陷最常用的方式就是-清除浮动

使用清除浮动解决高度塌陷有这么几种方案:

我们可以在box2后面再加一个box3,并把box3的clear属性设置为both;代码如下:

1
2
3
4
5
<div>
<div style="float:left;"></div>
<div style="float:left;"></div>
<div style="clear:both;"></div>
</div>

这种方式多加了一个div。我们也可以另一种方式去更优雅的实现它。

使用伪类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<style>
.clearfix{
*zoom:1;
}
.clearfix:after{
content:"";
display:block;
clear:both;
}
</style>
<div class="clearfix">
<div style="float:left;"></div>
<div style="float:left;"></div>
</div>

跟第一种方式原理一样,只不过是巧妙的利用了伪类。

需要注意的是:伪类里的display属性不可以写inline,因为inline撑不起父元素。然后,ie6、7、8不支持伪类:after,所以我们设置 *zoom:1 来触发 ie6、7 的 haslayout 属性.(haslayout是关于ie低版本浏览器排版的一个属性,类似高级浏览器的BFC属性.)

我们还可以使用另一种神秘的方式去解决高度塌陷。总结了一下,分为四小类:

设置父元素float不为none;

1
2
3
4
<div style="float:left;">
<div style="float:left;"></div>
<div style="float:left;"></div>
</div>

设置父元素position为fixed或absolute;

1
2
3
4
<div style="position:fixed;">
<div style="float:left;"></div>
<div style="float:left;"></div>
</div>

display为inline-block, table-cell, table-caption, flex, inline-flex;

1
2
3
4
<div style="display:inline-block;">
<div style="float:left;"></div>
<div style="float:left;"></div>
</div>

overflow不为visible;

1
2
3
4
<div style="overflow:hidden;">
<div style="float:left;"></div>
<div style="float:left;"></div>
</div>

其实自由最后一类对父元素的设置还算无毒无害,应用场景最多。

但是说了这么多,你知道为什么这四种方式可以解决父元素的高度塌陷吗?知道最好,如果不知道说明你已定不了 解BFC的概念,BFC(Block formatting context)直译为”块级格式化上下文”。它是一个只有Block-level box参与独立的渲染区域。

BFC一个很重要的特性就是:计算BFC的高度时,浮动元素也参与计算。

利用这条特性,我们只要将父元素触发为 BFC就可以了。触发条件当然就是上述四条。

javascript实现数组铺平

首先解释一下”铺平”,比如一个数组:[1,[7,3],4],他的第二个元素还是一个数组,我们需要把它提取出来,最后应该是这样[1,7,3,4],这就是铺平。

思路很简单,遍历数组,每个元素判断是否为数组元素,不是的话就push到一个新数组,是的话就遍历当前数组元素,不是数组元素的继续push… 这样周而复始的递归调用。听糊涂了吧。直接上代码吧。

一个待铺平的数组

1
var arr = [1,[[2,3],3],4];

定义一个空数组存放处理结果:

1
var newArr = [];

判断是否为数组的jQueryAPI :isArray,然后写一个处理数组的function:

1
2
3
4
5
6
var dealArr = function(arr){
for (var i = 0;i<arr.length;i++){
$.isArray(arr[i]) ? dealArr(arr[i]) : newArr.push(arr[i]);
}
return newArr;
};

这样一个处理数组铺平的函数就写好了。其实我们还可以拓展一下。我们发现自己没做多少工作,很多工作都是让jQuery的那个api-isArray给帮忙做了。我们知道js的六大数据类型: mumber string boolean null undefined object 这之中并没有array类型,想想就知道jQuery肯定是在isArray判断了数组类型,那么它到底怎么判断的,我们需要探究一下,jQuery源码,如果不想读源码,就直接百度或者google。网上一堆结果。你会发现这样一句话:

1
Object.prototype.toString.call(obj)

没错,这就是原生js判断数据类型的方法:可以参考 如何判断js中的数据类型

我们给数组对象添加一个铺平数组的api:panelArr

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.panelArr = function(){
var newArr = [];
var isArray = function(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
};
var dealArr = function(arr){
for (var i = 0;i<arr.length;i++){
isArray(arr[i]) ? dealArr(arr[i]) : newArr.push(arr[i]);
}
};
dealArr(this);
return newArr;
};

可以验证一下,比如执行 [1,[[2,3],3],4].panelArr() 的结果就是 [1,2,3,3,4]

西泊浪人©blog.western-ranger.com