竹磬网-邵珠庆の日记 生命只有一次,你可以用它来做些更多伟大的事情–Make the world a little better and easier


265月/170

Nginx使用的php-fpm的两种进程管理方式及优化

发布在 邵珠庆

背景
最近将Wordpress迁移至阿里云。由于自己的服务器是云服务器,硬盘和内存都比较小,所以内存经常不够使,通过Linux命令查看后,发现启动php-fpm进程数有20多个,占用了将近1G的内存,整个服务器才1.5G的内存,最后通过对php-fpm进程数优化解决了此问题,服务器多节省出600M的内存,将php-fpm的优化方法和大家分享下。
备注:目前根据nginx、fpm-php进行了内存优化,详情见相关资料
php-fpm优化

1、php-fpm优化参数介绍
他们分别是:pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。

pm:表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。
在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。

下面4个参数的意思分别为:
pm.max_children:静态方式下开启的php-fpm进程数量
pm.start_servers:动态方式下的起始php-fpm进程数量
pm.min_spare_servers:动态方式下的最小php-fpm进程数
pm.max_spare_servers:动态方式下的最大php-fpm进程数量

区别:
如果dm设置为 static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。
系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数

2、服务器具体配置
对于我们的服务器,选择哪种执行方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。
这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。
对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。
因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,
那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。
这样可以保证php-fpm只获取够用的内存,将不多的内存分配给其他应用去使用,会使系统的运行更加畅通。
对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩溃就应该很正常了。
因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者使用动态方式,
因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。
比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比如服务器上只是部署php环境的话,比较合适的值在5~10之间。

本服务器配置

1、服务器基本信息:
硬盘:数据盘30G、系统盘20G
内存:1.5G
CPU:双核
系统:CentOS 6.3 64位
带宽:独享2M
2、部署的应用
Git、SVN、Apache、Tomcat、PHP、Nginx、Mysql、JDK
3、优化后的参数
pm = dynamic
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8

 

max_children=40 , 每个children平均占用20M-30M内存,children越多,可以同时接受的并发数量越多,一般children的值是网站最高并发数+浮动值,这值再×内存占用,就是你需要用到的内存。
max_requests = N 是指当每个children接受了N次请求以后,就会把自己杀死,然后重新建立一个children。
PV / max_children = 每一个children接受的request次数
比如上面的值是1000,而你定义的是10240,那么fpm要超过10天才能杀死children并重建,这样如果存在内存泄露的话,就会导致进程占用过多的内存而无法释放,从而使fpm的处理能力降低,还会产生一些莫名其妙的错误。
但是如果你把这个值设置的过小,fpm频繁的杀死children并重建,也会导致额外的开销。
最好的优化当然是根据你网站的运行情况,去不断的调试,找到一个平衡点。

205月/170

whistle-全新的跨平台web调试工具

发布在 邵珠庆

whistle是基于Node实现的跨平台web调试代理工具,类似的工具有Windows平台上的Fiddler+Willow,基于Java实现的Charles,及公司同事基于Node实现的Livepool等等;whistle与所有的web调试代理工具一样,主要功能也是用于查看、修改HTTP、HTTPS、Websockt的请求响应或者作为HTTP代理服务器,但不同于Fildder+Willow、Charles和Livepool通过断点的方式修改请求响应,whistle采用的是类似配置Hosts方式,通过配置修改请求响应,且提供规则分组功能及通过域名、路径、正则三种匹配方式(系统的hosts配置只支持域名匹配),特别针对终端调试提供了weinre,log等功能,并支持通过Node模块进行扩展。

基本功能

Github地址

安装启动

安装启动whistle,需要以下四个步骤: 安装node、安装whistle、启动whistle、配置代理。

  1. 安装Node(建议安装最新版本,LTS版本或当前版本都可以,如果已安装可以忽略此步骤): https://nodejs.org/
    安装tnpm():

    npm install @tencent/tnpm -g --registry=http://r.tnpm.oa.com --no-proxy
    
    # Mac、Linux用户可能需要加sudo
    sudo npm install @tencent/tnpm -g --registry=http://r.tnpm.oa.com --no-proxy
    
  2. 安装whistle及在公司网络访问外网需要用到的插件txpac插件:
    tnpm install -g whistle @tencent/whistle.txpac
    
    # Mac、Linux用户可能需要加sudo
    sudo tnpm install -g whistle @tencent/whistle.txpac
    
  3. 启动whistle
    w2 start
    whistle默认端口为8899,如果要修改端口号,可以这么启动:
    w2 start -p 8888
    重启whistle:
    w2 restart
    关闭whistle:
    w2 stop
    更多内容请查看命令行帮助:
    w2 help
  4. 配置代理
    whistle需要手动配置浏览器代理或者系统代理(代理的ip为whistle所在机器的ip,如果是本机就填127.0.0.1;端口号为启动时设置的端口号,默认为8899):

    • 配置浏览器代理(推荐使用):
      安装chrome代理插件: whistle-for-chrome插件 或者 Proxy SwitchySharp
      安装firefox代理插件: Proxy Selector

使用方法

安装node、安装whistle、启动whistle、配置代理后可以开始使用whistle,用Chrome浏览器打开whistle配置管理页面

界面相关操作参见界面功能;

配置模式

传统hosts的配置模式:

# 单个host
ip hostname

# 组合host
ip hostname1 hostname2 ... hostnameN

# 例如
127.0.0.1 www.example.com
127.0.0.1 a.example.com b.example.com c.example.com

whistle的配置模式:

# 单个操作
pattern operator-uri
# 如果pattern和operator-uri不同时为域名或路径的一种组合,位置可以调换
operator-uri pattern

# 组合模式
pattern operator-uri1 operator-uri2 ... operator-uriN
# pattern1和operator-uri不同时为域名或路径的一种组合,可以如下配置
operator-uri pattern1 pattern2 ... patternN

其中,pattern可以为:

  1. 域名:www.test.com(所有该域名下的请求都会匹配operator-uri)
  2. 路径:http://www.test.com/xxx(http://www.test.com/xxx 及其子路径的请求都会匹配operator-uri),或不加协议protocol://www.test.com/xxx,protocol可以为http、https、ws、wss(http://www.test.com/xxx及其子路径的请求都会匹配operator-uri)
  3. 正则:/^https?:\/\/([^\/]+)\/xxx/(http(s)://host:port/xxx及其子路径的请求都会匹配operator-uri,且在operator-uri中可以通过$1, $2, ..., $9获取url里面的子匹配)

operator-uri由上述基本功能抽象成的形如protocol://ruleValue的URI,whistle会根据匹配的operator-uri的protocol及ruleValue修改请求或响应,protocol和ruleValue的详细内容参见whistle帮助文档协议列表

例如:

# 修改www.example.com的响应cors
www.example.com resCors://*
# 或
resCors://* www.example.com

# 同时修改多个自定域名或路径
resCors://* /example\.com/ a.test.com b.test.com
# 修改www.test.com的带端口host、referer和响应的cors
www.test.com 127.0.0.1:8080 referer://http://www.example.com resCors://*

一些例子

  1. 拦截HTTPS

    不开启拦截HTTPS,无法在whistle看到HTTPS和Websockt请求响应的明文,且只能通过whistle对HTTPS和Websockt设置host、代理等有限的操作,要通过whistle完全操作HTTPS、Websocket请求响应,需要开启HTTPS拦截及在系统或浏览器安装whistle的根证书,具体参见:https://avwo.github.io/whistle/webui/https.html

  2. 配置host
    # 传统hosts配置
    127.0.0.1 www.example.com # 等价于: www.example.com  127.0.0.1
    127.0.0.1 a.example.com b.example.com c.example.com
    
    # 支持带端口
    127.0.0.1:8080 www.example.com # 等价于: www.example.com  127.0.0.1:8080
    127.0.0.1:8080 a.example.com b.example.com c.example.com
    
    # 支持通过域名获取host
    host://www.qq.com:8080 www.example.com # 等价于: www.example.com  host://www.qq.com:8080
    host://www.qq.com:8080 a.example.com b.example.com c.example.com
    
    # 支持通过正则表达式匹配
    127.0.0.1:8080 /example\.com/i # 等价于: /example\.com/i  127.0.0.1:8080
    127.0.0.1:8080 /example\.com/ /test\.com/
    
    # 支持路径匹配
    127.0.0.1:8080 example.com/test # 等价于: example.com/test 127.0.0.1:8080
    127.0.0.1:8080 http://example.com/index.html https://www.test.com/test
    

    完整功能参见协议列表

  3. 修改请求

    以下功能都支持通过域名、路径、正则匹配方式,为方便只以域名匹配方式为例,其它同理:

    # 修改url参数
    www.qq.com urlParams://E:\test\params.json        
    
    # 请求方法
    www.qq.com method://post
    
    # 添加请求头
    www.qq.com reqHeaders://(x-a=1&x-b=a%20b)
    
    # 修改referer(修改referer快捷方法)
    www.qq.com referer://http://ke.qq.com/
    
    # 修改cookie(修改请求cookie快捷方法)
    www.qq.com reqCookie://{reqCookie.json}
    
    # 修改请求表单
    www.qq.com params://{form.json}
    

    JSON对象可以存在本地文件,或存在界面的Values,也可以内联到Rules配置里面,具体参见实现原理数据格式
    完整功能参见协议列表

  4. 修改响应

    以下功能都支持通过域名、路径、正则匹配方式,为方便只以域名匹配方式为例,其它同理:

    # 修改响应状态码
    www.qq.com statusCode://500 # 请求不会发送到后台服务器,可以用来模拟4xx、5xx请求
    www.qq.com replaceStatus://404 # 请求返回后再修改statusCode
    
    # 添加响应头
    www.qq.com resHeaders://(x-res-a=1&x-res-b=a%20b)
    
    # 修改响应类型(修改响应类型的快捷方法)
    www.qq.com resType://text/plain # 或者: www.qq.com resType://text
    
    # 请求替换
    www.qq.com https://www.baidu.com
    
    # 本地替换(windows中目录分割符可以用`\`,也可以用`/`)
    www.qq.com file://E:\xxx # 等价于: file://E:/xxx www.qq.com
    # Mac或Linux
    www.qq.com file:///User/xxx/test
    # 如果要让本地没有对应文件的请求继续请求线上,可以采用
    www.qq.com xfile://E:\xxx
    
    # 本地替换jsonp
    www.qq.com tpl://E:\xxx.json # xxx.json: {callback}({"ec": 0})
    www.qq.com xtpl://E:\xxx.json # xxx.json: {callback}({"ec": 0})
    
    # 注入html、css、js(whistle会自动根据响应类型封装后注入)
    www.qq.com html://htmlFile
    www.qq.com css://cssFile
    www.qq.com js://jsFile
    

    JSON对象或注入的文本可以存在本地文件,或存在界面的Values,也可以内联到Rules配置里面,

  5. 设置代理

    以下功能都支持通过域名、路径、正则匹配方式,为方便只以域名匹配方式为例,其它同理:

    # http代理
    www.qq.com proxy://127.0.0.1:8888 # 等价于: proxy://127.0.0.1:8888 www.qq.com
    # 同时设置多个
    proxy://127.0.0.1:8888 www.qq.com /google/ /facebook/
    
    # socks代理
    www.qq.com scoks://127.0.0.1:1008 # 等价于: socks://127.0.0.1:8888 www.qq.com
    # 同时设置多个
    socks://127.0.0.1:1008 www.qq.com /google/ /facebook/
    
    # pac脚本
    # 设置办公网pac脚本(如果安装了whistle.txpac,则无需设置)
    /./ pac://http://txp-01.tencent.com/proxy.pac
    # 设置办公网pac脚本(如果安装了whistle.txpac,则无需设置)
    /./ pac://http://txp-01.tencent.com/proxy_devnet.pac
    

    完整功能参见协议列表

  6. 移动端调试

    打开whistle配置界面右上角的Online按钮获取当前whistle的ip和端口,移动设备根据相应的ip和端口配置代理(确保移动设备和PC要在同一网段);配置完后如果还是无法访问,可能需要关闭防火墙或者设置白名单

    # weinre(调试网页DOM结构)
    www.qq.com weinre://test
    
    # log(输出网页console打印的日志)
    www.qq.com log://{test.js}
    

    具体参见:weinrelog

    完整功能参见协议列表

  7. 其它功能

    以下功能都支持通过域名、路径、正则匹配方式,为方便只以域名匹配方式为例,其它同理:

    # 禁用缓存
    www.qq.com disable://cache
    
    # 忽略规则
    www.qq.com filter://rule|host|https
    

    完整功能参见协议列表

插件扩展及应用

whistle支持通过Node模块的方式扩展功能,具体参见:插件开发

插件的一些应用:

  1. HTTP代理服务器功能:imweb本地代理imwebproxy(里面的Pb和CMEM的功能分别对应两个whistle插件whistle.imwebproxywhistle.cmem)
  2. 扩展协议功能:imweb前端本地调试环境whistle.imwebenv
  3. 扩展界面功能:whistle.websocket

用户反馈

有问题可以先查whistle帮助文档;

如果还是无法解决或者有建议、贡献代码等可以使用下面任一种方式:

最后,如果whistle对你有帮助,给项目加个Star: https://github.com/avwo/whistle

205月/170

手机无须ROOT和修改hosts在本地测试安卓和H5应用

发布在 邵珠庆

开发手机APP和 H5 应用经常需要在本地和线上环境分开测试,一般想到的操作都是修改hosts,我也一直这么干的,但手机上修改hosts是需要 ROOT权限的,这样太过麻烦,还有变砖头的风险,而且有些手机根本不能ROOT的。

忙和了一下午,总算完全达到预期,有点收获,下面说说重点,主要是两个:

  1. 本地 DNS 服务
  2. 网络代理

做个本地的 DNS 服务,有点像DNS劫持的感觉,这个是一劳永逸的办法
首先,你需要一个Linux 虚拟机或一台服务器
我下面的配置使用的 Centos7.0 系统,不通版本可能有些差别的。

一、安装 DNSMasq

# 安装
yum install dnsmasq -y 
service dnsmasq start

# 编辑配置参数
vi /etc/dnsmasq.conf

# 查找 resolv-file 去掉注释符,添加文件路径
# 表示 dnsmasq 会从这个指定的文件中寻找上游dns服务器
resolv-file=/etc/resolv.conf

# 查找 no-hosts , 确保前面有 # 井号的(表示被注释掉的),否则 hosts 配置不起作用
# 监听的IP
listen-address=127.0.0.1,192.168.0.103
strict-order
addn-hosts=/etc/hosts
cache-size=32768

# 配置到网卡参数,centos7 和 6 的网卡名是不同的,用ifconfig 查看替换下
# centos 7 以前
vi /etc/sysconfig/network-scripts/ifcfg-eth0
# centos7 不一定相同
vi /etc/sysconfig/network-scripts/ifcfg-enp3s0

#  最多只能写3个,注意原配置中若存在则需要调整
DNS1=127.0.0.1
DNS2=192.168.0.103
DNS3=202.101.172.35
#DNS3=202.101.172.47

# 保存后, resolv.conf 文件内容会自动更新的
cat /etc/resolv.conf

# 查看DNS是否已添加进去

# 注册服务
chkconfig dnsmasq on

# 重启
/etc/init.d/dnsmasq restart

# centos7 下使用的命令
systemctl restart dnsmasq

# 检查是否安装成功
netstat -tunlp|grep 53
yum install bind-utils

# 测试是否启用 DNS 配置
dig m.ai9475.com

# 编辑 hosts 文件,配置本地 DNS 劫持域名 IP 的映射关系
vi /etc/hosts
192.168.0.105 m.ai9475.com


这样服务端的 DNS 劫持就基本配置好了
下一步还需要在手机上设置 DNS 对应的 IP,

打开 网络设置 -> wifi连接 -> 修改网络 -> 高级 -> 静态IP方式 -> 修改第一个NSIP即可,第二个可用正常的公网DNS

如下图:

Android手机DNS配置

最后注意:修改 hosts 之后,需要重启 dnsmasq 还有 network 最好也重启

二、使用本地网络代理

这个方法比较有局限性,对 H5 网页应用还可以,对部分原生 APP 可能无效哦,但有个好处是配合一些软件可以做前端的抓包查看,对测试接口之类的查看数据很有用

我用到过两个软件,
1. Fiddler
这个软件使用很方便,网上有很多介绍,这里就不说了,但据说仅支持 windows 平台
2. Whistle
这个是开源的项目,跨平台,我目前用的是这个,配置也很简单
下面简单说下如何安装使用

依赖 Nodejs,所以先安装 nodejs
我这里图方便,就用 yum 的方式安装了

curl --silent --location https://rpm.nodesource.com/setup_4.x | bash -
yum install -y nodejs

下载速度可能有些忙,10KB/s 下载了好半天才下完,耐心等吧

npm install cnpm -g --registry=https://registry.npm.taobao.org
cnpm install -g whistle
w2 start

这样就完成了。。。

查看代理请求数据,就是抓包数据

http://127.0.0.1:8900
http://127.0.0.1:8899

:8899 是代理的端口,但也可以查看抓包数据

两个端口都可以看,下图看看效果先(图片可以直接拖拽查看大图)

手机无须ROOT不用修改hosts即可在本地测试安卓、苹果APP和H5应用

其他的就直接看官方说明文档吧,中文的,很清晰明了
https://avwo.github.io/whistle/install.html

后面就是手机上操作和上面的 DNS 设置是同一个地方

打开 网络设置 -> wifi连接 -> 修改网络 -> 高级 -> 代理(手动配置) -> 填写局域网中服务器的IP,如192.168.0.103,端口 8899 

如下图:

Android手机设置代理

最后就是修改服务器上的 hosts,参考上方 DNS 配置 hosts 的操作是一样的

差不多就这样设置好了。

最后需要注意的就是清除手机上的缓存,一定要关闭浏览器和应用,清理内存后再打开,否则手机上的 DNS 和网络设置可能没有切换过来的。

以上配置我都是在 Android 设备上测试的, iOS 没有应用可测试,不过按理说应该是一样的效果的。
虽然代理的方法对有些APP 不一定有用,但建议还是 DNS 和 代理一起上吧。。。就这样了。

205月/170

百度文字转语音免费接口使用实例

发布在 邵珠庆

1、接口

http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=2&text=你要转换的文字

上述接口的url,在浏览器上直接打开,即可听到文字转换后的语音。

 

lan=zh:语言是中文,如果改为lan=en,则语言是英文。

ie=UTF-8:文字格式。

spd=2:语速,可以是1-9的数字,数字越大,语速越快。

text=**:这个就是你要转换的文字。

2、js调用

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>Document</title>
  6. </head>
  7. <body>
  8.     <form action="" method="post">
  9.         <table align="center">
  10.             <tr>
  11.                 <td><input type="text" id='val' placeholder='你要装换的文字'></td>
  12.                 <td><input type="button" value="提交" onclick="fun()"></td>
  13.             </tr>
  14.         </table>
  15.     </form>
  16. </body>
  17. </html>
  18. <script type="text/javascript">
  19. function fun()
  20. {
  21.     var val=document.getElementById("val").value;
  22.     var zhText = val;
  23.     zhText = encodeURI(zhText);
  24.     document.write("<audio autoplay=\"autoplay\">");
  25.     document.write("<source src=\"http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=2&text="+ zhText +"\" type=\"audio/mpeg\">");
  26.     document.write("<embed height=\"0\" width=\"0\" src=\"http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&spd=2&text="+ zhText +"\">");
  27.     document.write("</audio>");
  28. }
  29. </script>

 

185月/170

优雅的使用 phpStorm 开发工具

发布在 邵珠庆

按照惯例依然是从百科上复制一条简介: PhpStorm 是 JetBrains 公司开发的一款商业的 PHP 集成开发工具。PhpStorm可随时帮助用户对其编码进行调整,运行单元测试或者提供可视化debug功能和智能HTML/CSS/JavaScript/PHP编辑、代码质量分析、版本控制集成(SVN、GIT)、调试和测试等功能。另外,它还是跨平台。在Windows和MacOS下都可以使用。PhpStorm-让开发更智能,而不是更困难。

听说phpStorm 10支持php7呃

优点

  1. 跨平台。
  2. 对PHP支持refactor功能。
  3. 自动生成phpdoc的注释,非常方便进行大型编程。
  4. 内置支持Zencode。
  5. 生成类的继承关系图,如果有一个类,多次继承之后,可以通过这个功能查看他所有的父级关系。
  6. 支持代码重构,方便修改代码。
  7. 拥有本地历史记录功能(local history功能)。
  8. 方便的部署,可以直接将代码直接upload到服务器。

总之它很牛逼就是了,什么都能干

快捷键

phpStorm有非常非常多并且好用的的快捷键,我下面就举一些经常用的的快捷键演示,还有一些不常用的就不举例了,绝对能提高你开发的效力率...

(Windows与Mac类似,只要把 command 键换成 ctrl )

查询相关

  • command + f 查找当前文件
  • command + r 查找替换
  • command + e 打开最近的文件
  • command + shift + o 快速查询文件
  • command + shift + f 关键字查找,更强大的查询器(机器不好的,最好还是先确定一下目录)
  • command + shift + r 高级替换
  • command + alt + b 找到当剪类的所有子类
  • alt + shift + c 查找最近修改的文件
  • alt + f7 直接查询选中的字符
  • ctrl + f7 文件中查询选中字符
  • command + 鼠标点击 跳到类或方法或变量等声明处
  • command + shift + tab 切换tab页文件
  • command + shift + +,- 展开或缩起
  • command + . 折叠或展开选中的代码

自动代码

  • alt + 回车 导入包,自动修正
  • command + n 快事为每个成员属性生成 getter 及 setter 方法
  • ctrl + i 快速生成插入魔术方法
  • ctrol + o 复写父类方法
  • command + alt + l 对当前文件进行格式化排版
  • command + d 复制当剪行
  • command + / // 注释
  • command + shift + / / / 注释

command + n 举个例子

我创建了一个 Person 类在 /Entity/ 目录下,然后我设置一些私有的属性如下代码:

namespace Entity;

class Person
{
    private $sign = '';

    private $name = '';

    private $age  = 0;

    private $work = '';

    private $sex  = '女';
}

然后咱们使用 command + n 在弹出来的窗口选择"PHPDoc Blocks..." 如下图:

再再弹出的窗口选择所有属性再点"OK":

namespace Entity;

/**
 * Class Person
 * @package Entity
 */
class Person
{
    /**
     * @var string
     */
    private $sign = '';

    /**
     * @var string
     */
    private $name = '';

    /**
     * @var int
     */
    private $age  = 0;

    /**
     * @var string
     */
    private $work = '';

    /**
     * @var string
     */
    private $sex  = '女';
}

然后它就对刚刚所选择属性加上了注释...... 是不是灰常神奇。

ok,咱们继续,再次使用 command + n 键选择 Contructor... 弹出需要进行传参赋值的属性:

    /**
     * Person constructor.
     * @param string $sign
     */
    public function __construct($sign)
    {
        $this->sign = $sign;
    }

如果不选择的话将不需要对成员属性进行设置。

然后咱们再来看看其他功能,比如"Implement Methods..."这个是快速生成魔术方法。

通常咱们设置、获取一个成员属性时最好不要直接使用 $person->name = $name 这种方式进行设置参数或取得参数值, 建议是对每个属性都开放一个 gettersetter 方法,这样可以很方便得对传进或传出去的值进行处理,这就是上面我为什么要把成员属性设置置为私有的原因之一

同样的 command + n 选择"Getters and Stetters" 然后选择所有属性,它就会把所有的属性设置 gettersetter 方法,这里要注意的是 Personsign 是唯一的,不可进行修改,所以咱们要把设置 sign 的方法去掉。注意: 最好 setter 方法设置完后返回当剪对象,这样的话咱们就可以连写了并且phpStorm的提示还相当友好 下面有例子:

    /**
     * @return string
     */
    public function getSign()
    {
        return $this->sign;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     * @return $this
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @return int
     */
    public function getAge()
    {
        return $this->age;
    }

    /**
     * @param int $age
     * @return $this
     */
    public function setAge($age)
    {
        $this->age = $age;

        return $this;
    }

    /**
     * @return string
     */
    public function getWork()
    {
        return $this->work;
    }

    /**
     * @param string $work
     * @return $this
     */
    public function setWork($work)
    {
        $this->work = $work;

        return $this;
    }

    /**
     * @var string
     */
    private $sex  = '女';

    /**
     * @return string
     */
    public function getSex()
    {
        return $this->sex;
    }

    /**
     * @param string $sex
     * @return $this
     */
    public function setSex($sex)
    {
        $this->sex = $sex;

        return $this;
    }

连写的例子:

use Entity\Person;
$person = new Person();
$person->setName("蛋蛋")
    ->setAge(17)
    ->setWork('student');

最后再演示一个快速复写被继承类的功能。咱们新建一个 Man 类,然后继承 Person 类,上面的Person类缺省是女性别,所以我们需要重写它并且加上"中国男人"。同样的使用 command + n 打开快捷窗口选择 "Override Methods..." 弹出来可被复写的方法:

然后咱们选择 getSexsetSex 方法,然后确定,在 Man 方法下生成以下方法。

namespace Entity;

/**
 * Class Man
 * @package Entity
 */
class Man extends Person
{
    /**
     * @return string
     */
    public function getSex()
    {
        return parent::getSex(); // TODO: Change the autogenerated stub
    }

    /**
     * @param int $sex
     * @return $this
     */
    public function setSex($sex)
    {
        return parent::setSex($sex); // TODO: Change the autogenerated stub
    }
}

咱们把 return parent::getSex()return parent::setSex( $age ) 删除掉,不需要这样,然后改成如下模式。

    /**
     * @return string
     */
    public function getSex()
    {
        if ( ! mb_strpos(parent::getSex(), "中国") )
            return "中国".parent::getSex();
        return parent::getSex();
    }

    /**
     * @param int $sex
     * @return $this
     */
    public function setSex($sex)
    {
        if( ! mb_strpos($sex, "中国") )
            $sex = "中国".$sex;
        return parent::setSex($sex);
    }

碉堡了有木有。

工具类等

看起来好多的样纸,我懒,不想讲可不可以?我就挑几个好不好?

  • 连拉ssh 照着配就行了,很简单

  • composer 这个也很明了吧,不多说了,平时咱们都是通过命令行来实现的
  • vagrant 这个phpstorm 10集成了vagrant,介于咱们自己已经搭建好了自己的vagrant环境,就不使用phpstorm所集成的啦

参考: 《使用Virtual Box和Vagrant搭建开发环境》

Database 工具

phpStorm所集成的database工具十分强大,当然它还有单独的database工具叫做: DataGrip,当然需要独立购买,咱们phpStorm有集成,就使用它好啦哈哈....(咱们的PhpStorm可是花钱买的,请支持正版)

Database工具一般在右侧栏,如果没有的话搜一下就好了,多简单的事儿呀...

开始创建一个数据库连接吧...

选择如上图的那个"+"号,然后选择 Data Source 数据来源,再选择数据库类型,一般咱们都是使用mysql吧,这次咱们试试新的,比如 SQLite

选择 sqlite 数据文件的地址,然后选择驱动,如果没有的话得先下载安装sqlite的驱动插件,这个很简单,在Driver下有提示,照做就是了...

咱们先看一下mysql的配制吧...

mysql的也非常简单,如果需要ssh/ssl连接的话,需要在SSH/SSL选项卡上配配地址入连接密码或sshkey...

配制好了,打开选择的数据库:

上图是连接的数据库的表及表字段信息... 来演示一下查询... 点击那"QL"样的dos窗口图标会弹出一个tab页,咱们可以在这里写sql语句。

咱们查询 User 表下的所有数据,可以看到会有相当提示,这是相当的好使啊...查询完成后在下面的 Database Console 上会有显示表数据,可对它进行修改,等等操作增加数据也可以。

快捷键 command + alt + l 不但对代码进行格式化,也sql语句也是非常有效的,如上图。

在"Database Console"栏上点"Output"选项卡可以查看sql语句执行的情况、记录及所消耗的时间等等信息...

  • command + 回车 执行sql语句或执行选中的sql语句

关于database工具的用法还有很多很多,我就不一一讲解了,大家可以自己慢慢去研究,真的非常好用

CVS 和 Git

  • command + k
  • command + shift + k

关于FTP的配制,由于我不推荐使用,所以这里就不多说啦!

都到这了,那咱们就说说在phpStorm上如何使用git工具吧

算了,还是举一个例子吧,配辣么多太累了,一会我看下有没有已经配好的,如果有的话一会拉出来截个图看看就行吧,反正现在svn用得也比较少了,还是git用得爽,分布式嘛,离线嘛,多好...关于 svn -> git 可以参考我之前写的一篇文章

《将代码库从Svn迁移Git》

从git服务器上把代码抓到本地

选择 CVS -> Checkout from Version Control -> Git

在弹出的窗口输入自己的git仓库信息:

注意 conle 的时间如果没有设置你的github账号的话可能会提示你输入账号信息,咱们输入就行了。如果需要修改的话则在设置里面进行修改,咱们可以使用 command + , 打开"Preferences" 然后找到"Version Control"选项目的"GitHub"进行设置,还有"Git"路径。

从mster创建分支

创建分支以通过命令行进行创建,咱们可以通过phpstrom的窗口进行创建,如下:

这个东西在右下角,"Git:master" 然后弹出上面窗口选择"New Branch" 然后输入新分支的名称就好了,它会自动切换到新分支下。

是不是超级简单呀...

提交代码至远程分支

当咱们修改完代码后,咱们需要把代码提交到远程分支上,使用快捷键 command + k 提交相当修改后的代码,双击文件可以进行对比。在"Commit Message"写上修改的东西然后点提交,这时就把代码提交到本地分支上了。

不使用快捷键的话,可以使用"CVS -> Commit Changes"提交,也会弹出下面窗口...

提交到本地分支后,咱们需要把代码推到远程分支上,所以需要使用快捷键: command + shif + k 提交远程分支...

也可以使用"CVS -> Git -> Push"进行提交...效果是一样的

注意svn木有 command + shift + k 这一步

合并分支

分并非常简单,只要选择需要合并的分支,然后merge就行了,如下图:

这样就合并完成,当然,如果有冲突的话会提交有冲突,并让你解决,如果没有的话就直接合并成功了...然后就可以push了......

Compare 是对合并的分支进行对比...

使用svn...

灰常抱歉,我电脑上木有找到相关Svn项目的代码,就不多说了...

安装插件

这里讲一个javascript 的安装,使用快捷键 cmd + , 打开 Preferances

安装 JavaScript 插件

Languages & Frameworks -> Javascript -> Libraries

选择add需要的框架

安装symfony2插件,搜索插件,然后点install

然后重启phpStorm 就完事了....

注意

  • 灰色+波浪线: 变量未使用
  • 黄色波浪线: 变量未名单词拼写问题
  • 红色波浪线: 变量未定义
  • 还有好多我就不一一举例了,可能是因为我代码写得太好,出错的东西比较少吧...

右边栏出现红色,这点是必须要杜绝的,好的代码不应该出现红色的任何提示...一旦出现一定要马上解决,好的代码不应该出现一个黄、红色的提示。

TODO 表示待办事件,当提交到vcs、svn或git的时候,会提示是还有未处理的事件,需要确认提交。

165月/170

架构师的能力模型(图)

发布在 邵珠庆

这四幅图不见得能阐述架构师能力的全部,但我尽量给出范围和有用的建议,希望能对大家有所启发和裨益。

 

图一:本能力模型的基本角度。与爱立信人力模型做了一个对比,请注意没有涉及到与“个人内在素质”相关的任何部分。所以类似于诚信、坚韧、耐心等等这类素质不在讨论的范围之内。

图二:个人特性

 

图三:技术技能

 

图四:对“技术技能”中“学会平衡设计”的补充

115月/170

Worktile v5.2.0 更强大的角色管理,权限控制及角色审批

发布在 邵珠庆

Worktile v5.2.0迎来一系列重大更新。本次更新主要包含以下三点:

1.新增角色管理:自定义系统角色、权限和数据范围;
2.更精细的权限控制,自定义项目、日历、网盘操作权限;
3.新增角色审批,分条件审批流程,让企业审批流程更可控。

一、新增角色管理 :自定义系统角色、权限和数据范围

什么是角色?

在各行各业的不同企业中,面对不同的职能、岗位和业务线的要求,需要配置不同的角色、权限,以及数据范围。

一般情况下,企业成员的操作权限、查看数据范围是通过角色来控制的,例如企业所有者具备最高的功能权限,可以查看公司全部资源,而普通成员只能操作被限定范围内的功能权限和数据。

在Worktile中,系统预定义了企业所有者、管理员、部门主管、成员4个默认角色,同时还根据职务预置了财务、出纳、客服、采购、人事、行政、HR等角色。在角色管理模块中,企业可根据公司实际职能、岗位、业务线需求设置相应的角色,并为其配置相应的角色成员、权限和数据范围。

如何进行角色管理? 

 1. 新建角色组、角色,并添加角色成员

点击“新建角色组”创建新的角色组,然后在角色组下添加相应的角色。设置好后,添加角色成员。企业成员可以被赋予多个角色,若一个成员归属于多个角色,则此成员的权限为所属角色具有的权限合集。

为了更好地帮助企业进行角色权限配置,系统预定义了企业所有者、管理员、部门主管、成员4个默认角色,同时还根据职务预置了财务、出纳、客服、采购、人事、行政、HR等角色。除了默认角色中的“所有者”的权限和数据范围默认为全部且不可修改,以及部门主管仅显示角色成员外,其余角色权限皆可修改。

默认的角色:所有者、管理员、部门主管和成员,具体说明如下:

  • 企业所有者:仅限1人,具有企业最高的功能权限和最全的数据可见范围;
  • 管理员:可设置多名员工,可设置其对应的功能权限,默认情况下具有大部分功能操作权限和本人相关的数据范围,可按企业所需自行编辑修改;
  • 部门主管:仅显示出企业组织架构中已设置的“部门主管”。如需添加“部门主管”,请到【成员管理】页面,在【编辑部门】中设置“部门主管”,设置完成后信息自动同步;
  • 成员:系统默认角色,设置除了所有者、管理员、主管外的企业成员应有的基础功能权限和数据可见范围。

系统按照常见的“职务”预置了部分角色,如财务、出纳、客服、采购、人事、行政等,按照“区域”预置了东区、西区、南区、北区、华中区,企业可增删改此类角色,并根据自身所需,配置相应的角色成员、功能权限和数据可见范围。

Tips:

1. 若一个成员归属于多个角色,则此成员的权限为所属角色具有的权限合集;

2. 系统默认角色“企业所有者”仅有1人,如需更换企业所有者,需要在企业后台【企业设置】页面中通过【转让企业】来更换。

2. 设置不同角色的功能权限范围

添加完角色成员后,可继续配置角色对应的功能权限。此处的功能权限包含系统所有的基础功能权限、应用管理权限以及其他后台模块的管理权限,勾选权限并保存即可设置成功。

Tips:

1. 角色功能权限的详细说明,请戳链接:角色管理

2. 在功能权限中配置了审批、考勤、销售、简报的操作权限后,同时应配置一下此角色可操作的数据范围。

3. 设置数据的查看、管理范围

在设置了角色的成员、权限后,还可以针对审批、考勤、简报、销售等OA应用来设置该角色的查看、管理数据范围。

通常,企业数据面对不同职务的员工需要有不同的数据查看、管理范围,如销售总监可以查看全部销售、客户、合同的统计,但是销售组长只能查看本组成员的数据,而普通的销售人员仅能查看与本人相关的数据。

通过设置角色的数据查看、管理范围,可以有效地解决这类问题。常见的查看数据范围主要分为:本人相关、本部门、本部门及下属部门、全部。除了企业所有者外,其他所有角色默认的数据范围均为本人相关,可根据不同角色自行调整修改。

设置范围后,在产品中查看简报、销售、审批、考勤数据时,不同的角色仅能查看、管理所设定范围内的数据。

  • 本人相关:仅限于本人创建、参与的数据;
  • 本部门:本角色可查看用户所属部门数据;
  • 本部门及下级部门:本角色可查看用户所属部门,及其子部门数据;
  • 全部:本角色可查看全公司的数据。

二、更精细的权限控制,自定义项目、日历、网盘操作权限

一个进行中的项目,不同的成员常常需要具备不同的操作权限,比如项目管理员需要具备项目最高权限,而有些成员需要具备任务相关的操作权限,另外一些成员只需要能查看即可;在企业网盘中,通常不同的成员需要具备不同的管理、编辑、上传、下载、只读权限。

不同行业不同企业有各自的需求,在本次产品升级中,Worktile 支持了更精细化的权限控制,支持自定义项目、日历、网盘权限,根据需要添加权限,然后在项目、日历、私有文件夹成员中配置成员相应的权限。

下面我们将以【自定义项目权限】为例,展现本次更新后Worktile 所具备的更加精细化的权限控制。

自定义项目权限

1. 如何自定义项目权限?

进入后台任务应用设置,点击“权限设置”,在此,企业可新建、编辑、删除项目权限。在【新建权限】页面勾选对应可操作的权限,企业即可根据业务需要配置项目成员所需的权限。

在项目权限列表中,系统预置了管理、编辑、只读的权限,“管理”权限为项目最高权限,包括项目的删除、归档、成员增删等;“编辑”仅限于对任务的操作权限;“只读”仅限于查看、评论任务。

其中“编辑”权限默认为成员初始加入私有项目时的权限,管理者可自行调整“编辑”所应具备的操作权限。

2. 如何在项目中配置成员不同权限?

在项目中,打开【项目设置】,在【成员管理】页面对每个成员配置相应的权限,如下图所示。配置完成后,项目成员仅能进行各自权限限定范围内的任务操作。

同理,【自定义日历权限】、【自定义网盘权限】同【自定义项目权限】,可在后台自定义权限,可在日历、文件夹设置的【成员管理】中给成员配置相应操作权限。

三、新增角色审批,分条件审批流程,让企业审批流程更可控

分条件审批流

进入企业,选择【应用管理-审批】,点击【模板管理-审批人设置】。审批流程分为自由流程、固定流程、分条件审批。

  • 自由流程:企业成员可自行添加相应的审批人;
  • 固定流程:企业成员需按照规定好的审批人流程进行审批;比如企业固定报销流程为“张三—李四”,设定固定流程后,企业成员填写审批单时,审批人已默认设置为“张三—李四”,且成员自己不能修改;
  • 分条件审批:当表单包含以下类型字段时才可以使用分条件审批:「数字字段」、「下拉选项」;申请人提交的表单会根据相应字段进入对应的审批流程。

Tips:

1. 若审批环节中某角色有多个成员,则到此角色审批环节时,会审批单会通知对角色中所有人。当角色中的任意一人同意或拒绝,则此审批环节完成;

2. 部门主管为特殊角色,多次点击时会按层级叠加显示。1级主管=申请人所在部门主管,2级部门主管=申请人所在部门的父部门的部门主管,以此类推。

若审批环节中某部门有多个主管,则到此审批环节时,此审批单会通知该级“部门主管”中的所有人。当任意一个主管同意或拒绝后,此审批环节完成。

角色审批

角色可以帮助企业规范审批流程,提高流程处理速度,减轻管理员后台配置的负担。预置好审批角色后,工作流程可在审批流程中固定下来,人员离职变动等,流程也无需再单独修改。同事,因为审批流程已设置好,并且清晰直观,即使新人不熟悉流程,也可直接提交审批。

预置知会人及通知方式

在本次升级中,还新增了预置审批知会人,可选择具体员工或者角色为知会人,如某些与财务相关的流程必须知会 法务[角色]或 财务[角色]。

设置后,申请人提交此表单时,表单中会默认添加好后台预置的知会人,无需申请者手动添加。这样,即使相关流程知会人的职务发生变化时,流程也无需再维护修改。

此外,知会的通知方式分为三种:仅全部同意后通知,仅发起时通知,发起时和全部同意后均通知,企业可根据需要自行设置调整。

Worktile Web v5.2.0 其他更新内容如下:

1. 审批同意或拒绝时可附加审批意见;

2. 审批新增审批汇总功能;

3. 全局项目分组,设置后可同步至所有企业成员。

115月/170

worktile角色管理

发布在 邵珠庆

什么是角色?

在各行各业的不同企业中,面对不同的职能、岗位和业务线的要求,需要配置不同的角色、权限,以及数据范围。一般情况,企业成员的操作权限、查看数据范围是通过角色来控制的,例如企业所有者具备最全的功能权限以及查看公司全部资源,而普通成员只能操作被限定范围内的功能权限和数据。在Worktile中,系统预定义了企业所有者、管理员、部门主管、成员4个默认角色,同时还根据职务预置了财务、出纳、客服、采购、人事、行政、HR等角色。在角色管理模块中,企业可根据公司实际职能、岗位、业务线需求设置相应的角色,并为其配置相应的角色成员、权限和数据范围。

如何进行角色管理?

(1)新建角色组、角色,并添加角色成员

点击“新建角色组”创建新的角色组,然后在角色组下添加相应的角色。设置好后,添加角色成员。企业成员可以被赋予多个角色,若一个成员归属于多个角色,则此成员的权限为所在角色具有的权限合集。为了更好的帮助企业进行角色权限配置,系统预定义了企业所有者、管理员、部门主管、成员4个默认角色,同时还根据职务预置了财务、出纳、客服、采购、人事、行政、HR等角色。除了默认角色中的“所有者”的权限和数据范围默认为全部且不可修改,以及部门主管仅显示角色成员外,其余角色权限皆可修改。

默认的角色:所有者、管理员、部门主管和成员,具体说明如下图:

角色说明.jpg

  • 企业所有者:仅限1人,具有企业最高的功能权限和最全的数据可见范围;
  • 管理员:可设置多名员工,可设置其对应的功能权限,默认情况下具有大部分功能操作权限和本人相关的数据范围,可按企业所需自行编辑修改;
  • 部门主管:仅显示出企业组织架构中已设置的“部门主管”。如需添加“部门主管”,请到【成员管理】页面,在【编辑部门】中设置“部门主管”,设置完成后信息自动同步;
  • 成员:系统默认角色,设置除了所有者、管理员、主管外的企业成员应有的基础功能权限和数据可见范围。

系统按照常见的“职务”预置了部分角色,如财务、出纳、客户、采购、人事、行政、HR,按照“区域”预置了东区、西区、南区、北区、华中区,企业可增删改此类角色,可根据所需配置相应的角色成员、功能权限和数据可见范围。

角色成员.png

Tips:
(1)若一个成员归属于多个角色,则此成员的权限为所在角色具有的权限合集;
(2)系统默认角色“企业所有者”默认仅有1人,如需更换企业所有者,需要在系统后台【企业设置】页面中通过”转让企业“来更换企业所有者;

(2)设置不同角色的功能权限范围

添加完角色成员后,可继续配置角色对应的功能权限。此处的功能权限包含系统所有的基础功能权限、应用管理权限以及后台模块的管理权限配置,勾选权限并保存即可设置成功。

功能权限.png

Tips:
(1)角色功能权限的详细说明,请戳链接:
(2)在功能权限中配置了审批、考勤、销售、简报的操作权限后,同时应配置一下此角色的可操作的数据范围。
(3)功能权限的具体说明描述如下图:

全局权限.jpg

(3)设置数据的查看、管理范围

在设置了角色的成员、权限后,还可以针对审批、考勤、简报、销售等OA应用来设置该角色的查看、管理数据范围。通常,企业的数据面对不同职务的员工需要有不同的查看、管理数据范围,如销售总监可以查看全部销售、客户、合同的统计,但是销售组长只能查看本组成员范围数据,而普通的销售人员仅能查看与本人相关的数据。通过设置角色的数据查看、管理范围,可以有效的解决这类问题。常见的查看数据范围主要分为:本人相关、本部门、本部门及下属部门、全部。除了企业所有者外,其他所有角色默认的数据范围为本人相关,可根据不同角色自行调整修改。设置范围后,在产品中查看考勤、简报、客户、销售、合同统计时,不同的角色仅能查看、管理对应所设定的查看、管理范围内数据。

  • 本人相关:仅限于本人创建、参与的数据;
  • 本部门:本角色可查看用户所属部门数据;
  • 本部门及下级部门:本角色可查看用户所属部门,及其子部门数据;
  • 全部:本角色可查看全公司的数据。

数据范围.png

115月/170

Markdown语法介绍

发布在 邵珠庆

什么是Markdown语法?

Markdown 是一种轻量级标记语言,目标是实现「易读易写」。Coding.net的许多版块都采用了Markdown语法,比如冒泡,讨论,Pull Request等。

标题

在Markdown中,你只需要在文本前面加上# 即可,同理、你还可以增加二级标题、三级标题、四级标题、五级标题和六级标题,总共六级,只需要增加# 即可,标题字号相应降低。例如:

# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

点击预览可以看到效果:

在这里输入图片描述

锚点

Coding 会针对每个标题,在解析时都会添加锚点id,如

# 锚点

会被解析成:

<h1 id="user-content-锚点">锚点</h1>

注意我们添加了一个user-content-的前缀所以如果要自己添加跳转链接要使用markdown的形式,且链接要加一个’user-content-‘前缀,如:

[问内链接](#user-content-锚点);

###引用 Markdown 标记区块引用是使用类似 email 中用 > 的引用方式,只需要在整个段落的第一行最前面加上 > :

> Coding.net 为软件开发者提供基于云计算技术的软件开发平台,包括项目管理,代码托管,运行空间和质量控制等等。

效果图如下:

在这里输入图片描述

区块引用可以嵌套,只要根据层次加上不同数量的 > :

> 这是第一级引用。
>
> > 这是第二级引用。
>
> 现在回到第一级引用。

效果图如下:

在这里输入图片描述

引用的区块内也可以使用其他的 Markdown 语法,包括标题、列表、代码区块等:

> ## 这是一个标题。
>
> 1. 这是第一行列表项。
> 2. 这是第二行列表项。
>
> 给出一些例子代码:
>
> return shell_exec("echo $input | $markdown_script");

效果图如下:

在这里输入图片描述

###列表 列表项目标记通常放在最左边,项目标记后面要接一个字符的空格。 无序列表:使用星号、加号或是减号作为列表标记

- Red
- Green
- Blue

效果图如下:

在这里输入图片描述

有序列表:使用数字接着一个英文句点

1. Red
2. Green
3. Blue

效果图如下:

在这里输入图片描述

如果要在列表项目内放进引用,那 > 就需要缩进:

*  Coding.net有以下主要功能:
    > 代码托管平台
    > 在线运行环境    
    > 代码质量监控    
    > 项目管理平台

效果图如下:

在这里输入图片描述

代办列表: 表示列表是否勾选状态

- [ ] 不勾选
- [x] 勾选

效果图如下:图片

代码

只要把你的代码块包裹在 ``` 之间,你就不需要通过无休止的缩进来标记代码块了。 在围栏式代码块中,你可以指定一个可选的语言标识符,然后我们就可以为它启用语法着色了。 举个例子,这样可以为一段 Ruby 代码着色:

```ruby
require 'redcarpet'
markdown = Redcarpet.new("Hello World!")
puts markdown.to_html
```

效果图如下:

在这里输入图片描述

强调

在Markdown中,可以使用 * 和 _ 来表示斜体和加粗。

斜体:

*Coding,让开发更简单*
_Coding,让开发更简单_

效果图如下:

在这里输入图片描述

加粗:

**Coding,让开发更简单**
__Coding,让开发更简单__

效果图如下:

在这里输入图片描述

自动链接

方括号显示说明,圆括号内显示网址, Markdown 会自动把它转成链接,例如:

[超强大的云开发平台Coding](http://coding.net)

效果图如下:

在这里输入图片描述

或者也可以直接用< >,将网址或者邮箱地址放在中间,也能将地址直接转成链接:

<support@coding.net>

效果图如下:

在这里输入图片描述

表格

在 Markdown 中,可以制作表格,例如:

```

First Header | Second Header | Third Header
------------ | ------------- | ------------
Content Cell | Content Cell  | Content Cell
Content Cell | Content Cell  | Content Cell

```

效果图如下:

在这里输入图片描述

或者也可以让表格两边内容对齐,中间内容居中,例如:

```

First Header | Second Header | Third Header
:----------- | :-----------: | -----------:
Left         | Center        | Right
Left         | Center        | Right

```

效果图如下:

在这里输入图片描述

分割线

在 Markdown 中,可以制作分割线,例如:

---

效果图如下:

在这里输入图片描述

上下标

\^表示上标, _表示下标。如果上下标的内容多于一个字符,要用{}把这些内容括起来当成一个整体。上下标是可以嵌套的,也可以同时使用。 例如:

x^{y^z}=(1+{\rm e}^x)^{-2xy^w}

效果图如下:

在这里输入图片描述

图片

Markdown 使用了类似链接的语法来插入图片, 包含两种形式: 内联 和 引用.

内联图片语法如下:

![Alt text](/path/to/img.jpg)

![Alt text](/path/to/img.jpg "Optional title")

也就是:

一个感叹号: ! ; 紧跟一对方括号, 包含了可选填的图片 alt 属性; 紧跟一对圆括号, 包含了图片的 URL 或者路径, 以及一个可选的用单引号或双引号包裹的 title 属性.

引用图片语法如下:

![Alt text][id]

“id” 是图片引用的名称. 图片引用使用链接定义的相同语法:

[id]: url/to/image "Optional title attribute"

95月/170

大总结-JS-挖 “掘” 淘 “金” 之 前端闯关历险记学习资料汇总

发布在 邵珠庆

世间万物,为我所用。

掘金不仅是一个很好的在线同性交友平台,也是一个学习交流和分享技术场所,更是程序猿和程序媛获取养料的精神家园。

分享是一个杂乱无章的环节,这无可厚非,因为在这里人人平等,每个人都可以分享自己看到的精品文章,也可以创作记录分享自己的成果,这是平台带给大家的优势,同时,面对零零散散的文章,对于我们来说,很困惑,我到底该学什么,从入门到精通的过程是怎样的?我该如何系统的学习这门语言?

汪洋大海,我该如何探寻所需的宝藏?
学习路途,我该如何寻找最佳的曲线?

去年开始看掘金,收藏了很多文章,也收获了很多知识,但是对于上面的疑问一直也在摸索当中,这里先感谢掘金这个平台,让我能学习到很多新的未知的东西,但在用掘金的这段时间内,也发现看的东西虽然很多,但是很杂,没有系统化的去深入了解一个东西,于是诞生了把自己看到过的,错过的,还有将要发表的,一起做一个整理和集合。

看见好的文章就收藏,后来发现收藏了几百篇,很多都是重复的,也不够系统化,资源如浩瀚大海,找起来也麻烦,无疑给自己增加了负担,在此,为了方便大家系统的学习前端这门课程,找准自己的定位,我利用空余时间,把掘金有以来分享的前端文章做了一个归类,方便掘金的朋友学习和收藏,喜欢的朋友可以收藏一下,这篇文章会持续更新,也欢迎关注【我的GitHub博客】获取最新动态。

贵有恒何必三更眠五更起,最无益只怕一日曝十日寒。 一天更新一点,每天看一点,坚持就是胜利,如果只整理和收藏不花时间看,一切都是徒劳。✌️

一、推荐规则

  • 推荐内容全部来自广大码农朋友的分享和专栏的原创,也就是掘金能搜索到的内容;
  • 每个分类原则上不多于3篇,除非这一分类优秀的文章特别多;
  • 每个文章我都有粗略阅读,排名按照收藏数和个人感觉关联度;
  • 文章日期全部来自2017-3月之前,会不定期更新,如果遗漏非常精彩的文章,可以及时联系我
  • 由于工程量大,推荐和排版难免出错,还望见谅,如果错误请底下及时评论反馈

二、代码规范篇

没有规矩,无以成方圆。

为什么把这个放在首位呢?好的代码规范不仅自己看起来赏心悦目,心情舒畅,我怎么就这么牛逼写出这么好看的代码(熏疼自己三秒钟,这往往只是错觉),别人看起来也直观一目了然,后来接手维护的人看了这种高逼格的代码也不会出现这种情况:这尼玛什么几把玩意,简直一坨翔,坑死劳资了(反正我走了也听不到?,你就骂吧)

2.1 前端开发规范总览

《前端开发规范手册》
《WEB 前端规范》
《Web 前端开发规范文档》

2.2 HTML规范

《HTML 最佳实践》
《前端编码规范(2)—— HTML 规范》
《Google HTML/CSS 编程规范》

2.3 CSS规范

《CSS 命名规范总结》
《Airbnb CSS / Sass 指南》
《CSS 代码格式规范》

2.4 JS规范

《JavaScript风格指南》
《JavaScript 代码整洁之道》
《Airbnb 的 JavaScript 编程规范》

2.5 ES6规范

《编程风格》

三、前言

国学大师王国维自己的著作《人间词话》中说:

古今之成大事业、大学问者,必经过三重境界:

第一境界:昨夜西风凋碧树,独上高楼,望尽天涯路。

第二境界:衣带渐宽终不悔,为伊消得人憔悴。

第三境界:众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

其实我觉得学习JavaScript也要经历类似的三种阶段:

第一境界:看山是山,看水是水。

第二境界:看山不是山,看水不是水。

第三境界:看山还是山,看水还是水。

国学大师王国维精妙地以三句词道破人生之路:起初的迷惘,继而的执着和最终的顿悟。
我以瞎几把乱扯三句词道破学习JavaScript之路:起初的表象,继而的本质和最终的本质回归到现象。

四、JavaScript基础篇

看是是山,看水是水。

万丈高楼平地起,胸有丘壑宏图画。

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。任何事情都要从基础做起,打好基础,不浮躁,才能做好一件事,学习一门语言也是一样,从“Hello World!"开始,踏踏实实,夯实基础,基础知识是整个学习体系的根本,没有牢固的基础知识作为根基,我们的学习和努力必将事倍功半,学习提纲是巩固基础知识的一种有效手段.

《思维导图来学习Javascript基础知识》
《多年 JavaScript 学习笔记整理》
《javascript 基础小结篇》
《前端开发基础 - JavaScript》
《你不知道的 Javascript》

五、JavaScript进阶篇

看山不是山,看水不是水。

其实地上本没有坑,踩的人多了,于是就有了。

JS是一门玄学,是一门很灵活的语言,当然里面有很多不好懂的概念,尤其是学完基础之后,对执行环境this类型转换作用域链闭包原型链继承evalJS左值与引用浅复制与深复制IIFE模块化函数式编程等等都有着这样或那样的不解之惑,想要成为JS大神这些门槛和坑不得不踩。

5.1 内存空间

因为JavaScript具有自动垃圾回收机制,所以对于前端开发来说,内存空间并不是一个经常被提及的概念,很容易被大家忽视。特别是很多不是计算机专业的朋友在进入到前端之后,会对内存空间,内存管理,内存释放的认知比较模糊,甚至有些人干脆就是一无所知。

《前端基础进阶:详细图解 JavaScript 内存空间》
《JavaScript 内存管理》
《JavaScript 中的内存释放》

 

5.2 执行上下文与作用域

首先来说说js中的执行环境,所谓执行环境(也称执行上下文–execution context)它是JavaScript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据 ,决定了它们各自的行为。而每个执行环境都有一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象中。

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链包含了执行环境栈中的每个执行环境对应的变量对象.通过作用域链,可以决定变量的访问和标识符的解析。

《前端基础进阶:详细图解 JavaScript 执行上下文》
《深入探讨 JavaScript 的执行环境和栈》
《图解 JS 上下文与作用域》

 

5.3 变量对象

深入理解执行上下文中的变量对象,从原理上解释变量提升,为接下来理解作用域链,闭包,原型打下坚实的理论基础,值得基础知识不牢固的盆友一阅。

《前端基础进阶:变量对象详解,教你如何高逼格地解释变量提升》
《《JavaScript 闯关记》之变量和数据类型》

 

5.4 作用域链与闭包

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链包含了执行环境栈中的每个执行环境对应的变量对象.通过作用域链,可以决定变量的访问和标识符的解析。

关于闭包的概念,是婆说婆有理。因而,我就翻阅了**红皮书(p178)**上对于闭包的陈述:
闭包是指有权访问另外一个函数作用域中的变量的函数
这概念有点绕,拆分一下。从概念上说,闭包有两个特点:

  • 1、函数
  • 2、能访问另外一个函数作用域中的变量

在ES 6之前,Javascript只有函数作用域的概念,没有块级作用域(但catch捕获的异常 只能在catch块中访问)的概念(IIFE可以创建局部作用域)。每个函数作用域都是封闭的,即外部是访问不到函数作用域中的变量。

《前端基础进阶:详细图解,彻底搞懂闭包与作用域链》
《JavaScript 闯关记之作用域和闭包》
《你想知道的关于 JavaScript 作用域的一切 (译)》
《弄懂 JavaScript 的作用域和闭包》

 

5.5 this

This,传说中的天使还是魔鬼?对于新手来说,this的指向一直是很头疼的地方,用的好就是天使,用的差就是魔鬼了,人人都想成为代码中的天使,为了避免成为魔鬼,我们必须好好深入学习一下this的作用机理和一些常见的坑。

《前端基础进阶:全方位解读 this》
《JavaScript 中的 this 陷阱的最全收集 -- 没有之一》
《Javascript 深入浅出 this》
《从 ECMA 规范深入理解 js 中的 this》

 

5.6 原型链

在JS里,万物皆对象。方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对 象共有的特点。 即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例 能够访问在构造函数原型中定义的属性和方法。

《JavaScript原型详解》
《三张图搞懂JavaScript的原型对象与原型链》
《JavaScript 原型中的哲学思想》
《一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系》

 

5.7 继承

Javascript 这门语言对于习惯了众多传统 OOP 语言 (c++,Java 等) 的 coder 来说其实是一门很奇怪的语言, 因为 Javascript 的 OOP 方式是基于原型的, 而非传统的类继承,主要有原型链继承,借用构造函数继承,组合继承,寄生式继承,寄生组合继承。

《js 原型链继承,借用构造函数继承, 组合继承,寄生式继承,寄生组合继承》
《Javascript 三招两式之对象继承 (上)》
《JavaScript 三招两式之对象继承 (下)》
《征服 JavaScript 面试系列:类继承和原型继承的区别》
《谈一谈 JavaScript 继承》

 

5.8 arguments

每个函数都会有一个 Arguments 对象实例 arguments,它引用着函数的实参,可以用数组下标的方式”[]” 引用 arguments 的元素。arguments.length 为函数实参个数,arguments.callee 引用函数自身。

《Arguments 对象深入了解》
《javascript arguments(callee、caller) 详解》
《Javascript 中的 arguments 对象》

 

5.9 类型转换

如果把通过函数或方法调用,明确的将某种类型转换成另一种类型称为显示转换 ,相反则称为隐式类型转换 。google和维基百科中没有找到“显示类型转换”,“隐式类型转换”的字眼。暂且这么称呼。 JavaScript的数据类型是非常弱的(不然不会叫它做弱类型语言了)!在使用算术运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可和数字相加。之所以不同的数据类型之间可以做运算,是因为JavaScript引擎在运算之前会悄悄的把他们进行了隐式类型转换的,如下是数值类型和布尔类型的相加:

3 + true; // 4
结果是一个数值型!如果是在C或者Java环境的话,上面的运算肯定会因为运算符两边的数据类型不一致而导致报错的!但
是,在JavaScript中,只有少数情况下,错误类型才会导致出错,比如调用非函数,或者读取null或者undefined的属
性时。

《从 []==![] 为 true 来剖析 JavaScript 各种蛋疼的类型转换》
《一篇文章搞定 JS 类型转换》
《聊一聊 JS 中的『隐式类型转换』》

 

5.10 IIFE

全拼Imdiately Invoked Function Expression,立即执行的函数表达式。立即执行函数在模块化中也大有用处。用立即执行函数处理模块化可以减少全局变量造成的空间污染,构造更多的私有变量。

立即执行函数写法大全:

// 最常用的两种写法
(function(){ /* code */ }()); // 老道推荐写法
(function(){ /* code */ })(); // 当然这种也可以

// 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
// 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
// 但是两者交换则会报错
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }();

// 如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

// 你也可以这样
new function(){ /* code */ }
new function(){ /* code */ }() // 带参数

《javascript模块化编程-详解立即执行函数表达式IIFE》
《Javascript 的匿名函数与自执行》
《js 匿名自执行函数中闭包的高级使用(前端必看)》
这一篇掘金没有推荐过,不过我认为真的写的很全很详细,这里也推荐一下:
《详解javascript立即执行函数表达式(IIFE)》

 

5.11 setTimeout

平时的工作中,也许你会经常用到setTimeout这个方法,可是你真的了解setTimeout吗?本系列想通过总结setTimeout的用法,顺便来探索javascript里面的事件执行机制。在一个基础阶段,理解JavaScript定时器的工作原理的是非常重要的。通常它们看起来不那么直观,因为它们处于单线程中。

《[译] JavaScript 中的定时器是如何工作的?》
《关于 JavaScript 定时器我的一些小理解》
《JavaScript 定时器及相关面试题》
《【原】以 setTimeout 来聊聊 Event Loop》

 

5.12 Object.defineProperty()函数

该方法允许精确添加或修改对象的属性。一般情况下,我们为对象添加属性是通过赋值来创建并显示在属性枚举中(for...in 或 Object.keys 方法), 但这种方式添加的属性值可以被改变,也可以被删除。而使用 Object.defineProperty() 则允许改变这些额外细节的默认设置。例如,默认情况下,使用 Object.defineProperty() 增加的属性值是不可改变的。 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。描述符必须是两种形式之一;不能同时是两者。

《理解 JavaScript 的 Object.defineProperty() 函数》
《解析神奇的 Object.defineProperty》
《双向绑定的简单实现 - 基于 ES5 对象的 getter/setter 机制》

 

5.13 call、apply、bind

今天看博客时,看到了这样的一段js代码: var bind = Function.prototype.call.bind(Function.prototype.bind); 上面那段代码涉及到了call、bind,所以我想先区别一下call、apply、bind的用法。这三个方法的用法非常相似,将函数绑定到上下文中,即用来改变函数中this的指向。这个系列就是让大家深入理解其中的差异。

《JS 中 call、apply、bind 那些事》
《JavaScript 中的 call、apply、bind 深入理解》
《回味JS基础:call apply 与 bind》
《深入浅出妙用 Javascript 中 apply、call、bind》

 

5.14 深拷贝与浅拷贝

eg:有A、B两个对象,且都有子对象

深拷贝:将B对象拷贝到A对象中,包括B里面的子对象;

浅拷贝:将B对象拷贝到A对象中,但不包括B里面的子对象;

首先深复制和浅复制只针对像 Object, Array 这样的复杂对象的。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

《JavaScript 深拷贝》
《javaScript 中的浅拷贝和深拷贝》
《深入剖析 JavaScript 的深复制》

 

5.15 正则表达式

还记得被称为正则小王子的jQuery作者吗?但正则表达式对于我来说一直像黑暗魔法一样的存在。手机正则去网上搜,邮箱正则去网上搜,复杂点的看看文档拼凑一下,再复杂只能厚着脸皮让其他同事给写一个。从来没有系统的学习过,搞完这个系列是不是准备拿下它。

《正则表达式 - 理论基础篇》
《正则表达式学习笔记》
《正则表达式实践篇》
《常见的正则表达式可视化描述》
《最全面的常用正则表达式大全》

直接来个膜法小编 的收藏集:

《正则表达式合集》)

 

5.16 事件

JavaScript 程序采用了异步事件驱动编程(Event-driven programming)模型,维基百科对它的解释是:

事件驱动程序设计(英语:Event-driven programming)是一种电脑程序设计模型。这种模型的程序运行流程是由用户的动作(如鼠标的按键,键盘的按键动作)或者是由其他程序的消息来决定的。相对于批处理程序设计(batch programming)而言,程序运行的流程是由程序员来决定。批量的程序设计在初级程序设计教学课程上是一种方式。然而,事件驱动程序设计这种设计模型是在交互程序(Interactive program)的情况下孕育而生的

《JavaScript 浏览器事件解析》
《深入理解 - 事件委托》
《我也来说说 JS 的事件机制》
《DOM 事件深入浅出(一)》
《DOM 事件深入浅出(二)》
《JS 中的事件绑定、事件监听、事件委托是什么?》

 

5.17 其他混淆点

其他一些容易混淆的难点就不单独开一个类型,这里就统一做一个系列说明,也是平时经常遇到的一些痛点和难点吧,主要是区分一些概念,知道彼此之间的异同,以下简称一张图系列。

《一张图看懂JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some》
《一张图看懂encodeURI、encodeURIComponent、decodeURI、decodeURIComponent的区别》
《一张图彻底掌握 scrollTop, offsetTop, scrollLeft, offsetLeft......》
《一张图看懂 Function 和 Object 的关系及简述 instanceof 运算符》

六、JavaScript高手篇

看山还是山,看水还是水。

如果学习JavaScript不是为了成为高手,那将毫无意义。

其实,高手有一颗寂寞的心,因为高手的造就本就是用寂寞堆积而成。

6.1 JavaScript数据结构与算法篇

程序设计=数据结构+算法

6.1.1 数组去重

《也谈 JavaScript 数组去重》
《数组去重 -- 这几种方法够不?》
《js 对数组去重的完整版》

 

6.1.2 排序

《十大经典排序算法总结(JavaScript描述)》
《JS 家的排序算法》
《JS 中常见排序算法详解》

 

6.1.3 查找

《查找算法之顺序、二分、二叉搜索树、红黑树 详细比较总结》

 

6.1.4 数据结构

《学习JavaScript数据结构(一)——栈和队列》
《学习 JavaScript 数据结构(二)——链表》
《学习 JavaScript 数据结构(三)——集合》
《学习 javascript 数据结构 (四)——树》
《javaScript的数据结构与算法(五)——字典和散列表》

 

6.1.5 其它

《前端面试中常见的算法问题读后整理》
《常见数据结构 (一)- 栈, 队列, 堆, 哈希表》
《常见数据结构 (二)- 树 (二叉树,红黑树,B 树)》
《算法学习笔记》
《javascript array js 缓存算法、数组随机抽取、字母串转数字,数字转字符串》
《JavaScript 算法练习》

 

6.2 JavaScript跨域

** 由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。具体可以查看下表(来源)**

《前端跨域问题及解决方案》
《直白的话告诉你在 javascript 中如何用 jsonp 实现跨域请求》
《前端 Ajax 跨域请求方案沙里淘金》
《你所不知道的跨域资源共享(CORS)》
《带你一步一步的理解前端跨域的原理及实践》
《HTML5 跨域通信 API - window.postMessage》
《前端跨域整理》
《跨域问题,解决之道》

 

6.3 JavaScript设计模式

为什么要学习设计模式? 做事情之前问个为什么总是好的。关于设计模式的好坏,我在知乎上也看过一些讨论,有知友对其提出过一些疑问,里面有一些关于设计模式的观点:

  • 设计模式有何不妥,所谓的荼毒体现在哪?
  • 设计模式是不是有点太玄了?

任何事物的出现都有其道理,任何语言都有其不足之处,设计模式是对语言不足的补充(Peter Norvig)。设计模式也是编程经验的总结,我想学习它对像我这样的前端新手的能力会有很大的提升。

细说说它的好处:

  1. 设计模式能让你用更少的词汇做更充分的沟通;
  2. 谈话在模式层次时,不会被压低到对象和类这种琐碎的事情上;
  3. 懂设计模式的团队,彼此之间对于设计的看法不容易产生误解;
  4. 共享词汇能帮助初级人员快速成长。

《学习设计模式前需要知道的事情》
《常用的 JavaScript 设计模式》
《JavaScript 设计模式》读后感觉很复杂
《JavaScript 设计模式》
《听飞狐聊 JavaScript 设计模式系列 13》

 

6.4 JavaScript函数式编程

什么是函数式编程?

  • 与面向对象编程(Object-oriented programming)和过程式编程(Procedural programming)并列的编程范式。
  • 最主要的特征是,函数是第一等公民。
  • 强调将计算过程分解成可复用的函数,典型例子就是map方法和reduce方法组合而成 MapReduce 算法。
  • 只有纯的、没有副作用的函数,才是合格的函数。

《函数式编程入门教程》
《想学函数式编程?》
《给 JavaScript 开发者讲讲函数式编程》
《前端基础进阶(七):函数与函数式编程》
《『翻译』JavaScript 函数式编程》
《JavaScript 函数式编程》

 

6.5 JavaScript高阶函数

具体来说,在 JavaScript 中,我们可以将一个函数 A 作为参数传给另一个函数 B,或者,在函数 B 中将函数 A 作为返回值返回。那么这里的函数 B 就是上面所说的高阶函数。 在《javascript设计模式和开发实践》中是这样定义的。 函数可以作为参数被传递; 函数可以作为返回值输出。

《javascript 高阶函数介绍》
《程序媛学 JS 小记一笔——高阶函数》
《高阶函数对系统的 “提纯”》
《JavaScript 之闭包与高阶函数(一)》

 

6.6 JavaScript性能优化

天下武功,无坚不摧,唯快不破。

Javascript是一门非常灵活的语言,我们可以随心所欲的书写各种风格的代码,不同风格的代码也必然也会导致执行效率的差异,作用域链、闭包、原型继承、eval等特性,在提供各种神奇功能的同时也带来了各种效率问题,用之不慎就会导致执行效率低下,开发过程中零零散散地接触到许多提高代码性能的方法,整理一下平时比较常见并且容易规避的问题。

《吹毛求疵的追求优雅高性能JavaScript》
《天生就慢的 DOM 如何优化?》
《Javascript 高性能动画与页面渲染》
《一个关于 js 线程和性能优化的文档,有例子哦!》
《合理使用 IIFE 优化 JS 引擎的性能》
《高性能 JavaScript》读书笔记

 

6.7 JavaScript 柯里化

就像最早听到斐波拉切数列一样,第一次听到柯里化我也是懵逼的

柯里化又称部分求值,字面意思就是不会立刻求值,而是到了需要的时候再去求值。如果看的懵逼,没事,看完整篇文章再回过头来看这里你就会豁然开朗。 反柯里化的作用是,当我们调用某个方法,不用考虑这个对象在被设计时,是否拥有这个方法,只要这个方法适用于它,我们就可以对这个对象使用它。

《前端高手必备:详解 JavaScript 柯里化》
《简单理解JavaScript中的柯里化和反柯里化》
《浅谈函数式编程柯里化的魔法》
《从一道面试题谈谈函数柯里化 (Currying)》
《掌握 JavaScript 函数的柯里化》

 

6.8 JavaScript调试

如今 Chrome 浏览器无疑是最受前端青睐的工具,原因除了界面简洁、大量的应用插件,良好的代码规范支持、强大的 V8 解释器之外,还因为 Chrome 开发者工具提供了大量的便捷功能,方便我们前端调试代码,我们在日常开发中是越来越离不开 Chrome,是否熟练掌握 Chrome 调试技巧恐怕也会成为考量前端技术水平的标杆。 介绍 Chrome 调试技巧的文章很多,本文结合我自己的开发经验,希望从实际运用的角度为大家再一次谈一谈这些功能,也希望对大家都有所帮助和启发。 在chrome的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察JavaScript的执行过程,直观感知函数调用栈,作用域链,变量对象,闭包,this等关键信息的变化。因此,断点调试对于快速定位代码错误,快速了解代码的执行过程有着非常重要的作用,这也是我们前端开发者必不可少的一个高级技能。

《前端高手必备技能:如何在 chrome 开发者工具中观察函数调用栈、作用域链与闭包》
《比 console.log 更多-chrome 调试命令》
《JavaScript30 中文指南 - 09 Console 调试技巧指南》
《聊一聊移动端调试那些事》
《前端 chrome 浏览器调试总结》
《我的职业是前端工程师【五】: 前端工程师必会的六个调试技能》
《九个 Console 命令,让 js 调试更简单》
《再谈 Chrome 实用调试技巧》
《调试 CSS 的方法》
《前端调试效率低?试试这 10 个 Chrome 开发者工具 使用技巧》
《前端开发中的 JS 调试技巧》

 

6.9 前端安全

天下武功,唯快不破。算法越快,越容易破。

《如何让前端更安全?——XSS 攻击和防御详解》
《HTTPS 互联网世界的安全基础》
《关于 Web 安全,99% 的网站都忽略了这些》
《Web 前端慢加密》

 

6.10 技巧和效率

技巧恰似黑魔法,效率堪比加速器,都是开发过程中不可或缺的一部分,善用技巧,提高效率。

高手之所以高,很大一部分在于技巧巧妙,效率高,让人自愧不如,所以成了我们眼中的高手,其实高手也是从菜鸟过来的,由于长期的学习和经验的积累,再加上善于总结,自然一步步成长成为高手,为了加速自己成为高手,我们可以向高手取经,学习他们分享的一些技巧和解决问题思维方式。


《34 个实用的 webAPP 开发技巧分享,值得收藏》
《不造个轮子,你还真以为你会写代码了? | 掘金技术征文》
《【译】帮助你更快学习 JavaScript 的六个思维技巧》
《提升效率黑科技》
《【译】六个漂亮的 ES6 技巧》
《【译】45种 Javascript 技巧大全》
《程序员应该掌握的 10 个搜索技巧》
《你必须『收藏』的Github技巧》
《老司机教你更好的进行 CSS 编程 70 个技巧》
《聊一聊这些常见而且实用的 css 技巧》

 

七、JavaScript框架篇

青,取之于蓝而青于蓝;冰水为之而寒于水。

jQuery:一年没写链式JQ了,在这个人手一个MVVM框架的年代,JQuery就不做推荐,想要了解可以自行学习。

vue.js react.js,angularjs···此处省略一万篇文章和略干文字。

关于框架的学习,最好多看看官方文档,多多实践,我这里就不多做介绍了,框架太多,我用的也不多,这里也就不献丑推荐什么的,自己对框架也一知半解,没有深入去研究底层的实现,仅仅停留在够用就行没去深究的层面,大家想学什么框架可以自己去搜索相关资料和教程。

八、HTTP和HTTPS篇(待续,下一步学习中)

九、前端工程化篇

解放双手,成就你的梦想。

《webpack系列合集》
《构建工具合集》
《教你如何读webpack2中文文档》

 

十、全栈篇之Node.js(待续,正在学习中nodejs)

十一、面试篇

11.1 简历模板

简历好比人的一张脸,不能丑了别人,爽了自己。

对于开发者与设计师们,一封好的的简历会让自己的面试增色不少。本次分享的简历简介精致,而且样式多种多样。包含 INDD、IDML、PDF、PSD、DOCX 等格式,方便自由修改和学习。

《Talk is cheap, show me the code - 用 github 数据辅助你完善简历》
《27 款优质简洁的个人简历打包下载》
《10+ 优秀简洁的个人简历下载(五)》
《15 款优质实用简洁的个人简历模板打包下载 (一)》
《5 款精致简洁求职简历》

 

11.2 面试题

任凭风吹雨打,胜似闲庭信步。

首先我希望表达的一点,就是面试的评判跟学校里的考试完全是两回事,太多的人把面试当做考试而把注意力放在题目上。 事实上面试中未必是所有题目全都回答"正确"就一定会通过或者较高评价。面试是面试官和面试者双方"挖掘与展示才能"的过程,参考前面提到的面试过程,全部回答正确的情况很可能是因为面试官不感兴趣懒得追问。 对于面试官而言,基本评判原则就是"我要不要这个人做我的同事?",多数情况下,这个答案会非常清楚。一些题目是充分的,也就是"回答对了说明这个人具有可以依靠的才能",一些题目则是必要的,也就是"回答错了说明这个人无法胜任我们的工作"。

《最近遇到的前端面试题》
《大厂前端面试题汇总》
《前端面试集合》
《前端面试题精选》
《一道 JS 面试题所引发的 "血案",透过现象寻本质,再从本质看现象》

 

11.3 面试技巧、经验与感悟

他山之石,可以攻玉。

经验犹如一所大学校,它能使你认识到自己是个什么样的傻瓜。

人生就是不断的推销自己,不停的面试,狭义的面试我们认为就是工作上的面试,而广义的面试就是做人的面试,到处就是展示推销自己。看看别人面试心得,取经一下,避免别人已经犯过的错误,也是一种进步。

《面试感悟:一名 3 年工作经验的程序员应该具备的技能》
《我的 web 前端面试经历 - 百度》
《1月前端面试记》
《关于前端面试》
《迟来的面试总结》

十二、资源汇总

积土成山,风雨兴焉;积水成渊,蛟龙生焉。

善于积累,善于总结,也是学习的一门功课,积累是一个循序渐进的过程,搜集总结同时也是一个费时费力的过程,看看别人的积累和总结,不禁感叹于别人的知识面和认真的态度,自己会觉得有压力从而产生动力,此时的自己会不会蠢蠢欲动,给自己所学所看来一个强势的总结呢?

《也许是史上最全的前端资源大汇总》
《JavaScript 开发者必备的资源合集》
《前端知识点大百科全书》
《100+ 超全的 web 开发工具和资源整理》
《Web 前端从入门菜鸟到实践老司机所需要的资料与指南合集》
《GitHub 上最全的前端入门资源汇总 快速入门前端》
《前端教程 & 开发模块化 / 规范化 / 工程化 / 优化 & 工具 / 调试 & 值得关注的博客 / Git & 面试 - 资源汇总》
《送给前端的你,推荐几篇前端汇总文章。 - 学习编程 - 知乎专栏》
《前端学习资源汇总——前端收藏夹》
《最全前端资源汇集》

十三、插件

插件是我们开发时候的左膀右臂。

平时自己写插件主要有下面几个问题:

(1)开发插件需要时间,可能拖延项目工期,如果工期紧急不建议选用这种方式

(2)自己造的轮子未必有现有轮子的好用,要考虑到队友是否适用

(3)需要比较高的开发水平

这里搜集一些常用的插件供大家参考使用。

《前端常用插件汇总》
《寻找前端插件,一步到位》
《前端插件资源整理》

十四、工具篇

工欲善其事,必先利其器。

张三和李四都要上山砍柴,但他们的斧头都有点钝了,张三没有理会,拿着斧头就上山了,因为他的斧头不利,砍的都是比较细的树柴……李四就不同了,他拿来磨刀石,用劲地把斧头先磨好,虽然他比张三慢了起步,但是他的准备工夫做到家了,砍柴砍得很快。到太阳下山了,张三只背了小小的一捆柴下来,但是李四,背着一大捆的柴下来…… 由此可见,准备工夫做好了,可以事半功倍!

《超全面 + 最流行的「前端速查表」高清版大全》
《成为专业程序员路上用到的各种优秀资料、神器及框架》
《前端切图神器 avocode》
《2015 年末必备前端工具集》
《【译】2016 年我最喜欢的前端工》
《前端新手可以浏览的网站》
《收集非常好用的 Mac 应用程序、软件以及工具,主要面向开发者和设计师。》
《工具武装的前端开发工程师》
《一个前端程序猿的 Sublime Text3 的自我修养》
《前端工程师的工具包》

十五、鸣谢

  • 感谢党和国家
  • 感谢美利坚创造了互联网
  • 感谢掘金这个在线同性交友的场所
  • 感谢掘金CEO以及工作人员创造了这个平台
  • 感谢创作和分享的广大同行码农提供了本文原始素材
  • 感谢各位大神愿意含辛茹苦的花时间观看鄙人这篇随便拼凑的文章
  • 最后也厚颜无耻的感谢自己能静下心整理一篇文章和大家一起分享交流进步

十六、广告

本文分享首发【掘金】,同时收录在【我的GitHub博客】,觉得本文写的不算烂的,可以点击【我的GitHub博客】顺便登录一下账号给个星星✨鼓励一下,关注最新更新动态,大家一起多交流学习,欢迎随意转载交流,不要钱,文末有福利哦?,你懂的?。

登高自卑,与君共勉。

十七、福利

文武之道,一张一弛,要劳逸结合,是不是?
老司机镇楼,投币上车。骚年,看了这么多这么累,是不是该撸一发呢?,我好想射点什么,先撸一盘LOL去了,哈哈,大家别想歪了。
待续的今后继续更新完善。

   下一页