docs: 批量博文

This commit is contained in:
杭城小刘
2020-02-25 17:46:51 +08:00
parent 8e5d2c9e7f
commit 6e99436a9e
373 changed files with 18071 additions and 1116 deletions

148
Chapter7 - Geek Talk/7.1.md Normal file
View File

@@ -0,0 +1,148 @@
# 命令行文件查找
> 在日常中find的使用频率很高熟练掌握对提供工作效率很有帮助。
语法:
```
find(选项)(参数)
```
1、列出当前目录以及目录下的所有文件
```
find .
```
2、找到当前目录下名字为 11.png 的文件
```
find . -name "11.png"
```
3、找到当前目录下所有的 jpg 文件
```
find . -name "*.jpg"
```
4、找到当前目录下的 jpg 文件和 png 文件
```
find . -name "*.jpg" -o -name "*.png"
```
5、找到当前目录下不是以 png 结尾的文件
```
find . ! -nam "*.png"
```
6、根据正则表达式查找
比如:查找当前目录下,文件名都是数字的 png 文件
```
find . -regex "\./*[0-9]+\.png"
```
7、根据路径查找
找到当前目录下路径中包含 swj 的文件/路径
```
find . -path "*swj*"
```
8、根据文件类型查找
查找当前目录下,路径包含 swj 的文件
```
find . -type f -path "*swj*"
```
9、限制搜索深度
查找当前目录下所有的 png不包括字目录
```
find . -maxdepth 1 -name "*.png"
```
相应的, mindepth 也是选项
```
find . -mindepth 2 -name "*.png"
```
10、根据文件大小
通过 -size 来过滤文件大小,支持的单位如下
* b - 块512字节
* c - 字节
* w - 字 2字节
* k - 千字节
* M - 兆字节
* G - 吉字节
找出当前目录下文件大小超过 100M 的文件
```
find . -type f -size +100M
find ./ -size +100MB
```
11、根据访问/修改/变化时间
* 访问时间(-atime/天,-amin/分钟):用户最近一次访问时间
* 修改时间 -mtime/天, -mmin/分钟): 文件最后一次修改时间
* 变化时间 -ctime/天, -cmin/分钟):文件数据元(例如权限的过)最后一次修改时间
找出 1天内被修改过的文件
```
find . -type f -mtime -1
```
找出最近1周内被访问过的文件
```
find . -type f -atime -7
```
12、根据权限
通过 -perm 来实现
找出当前目录下权限为777的文件
```
find . -type f -perm 777
```
找出当前目录下权限不是644的php文件
```
find . -type f -name "*.php" ! -perm 644
```
13、根据文件拥有者
找出文件拥有者为 root 的文件
```
find . -type f -user root
```
找出文件所在群组为 root 的文件
```
find . -type f -group root
```

View File

@@ -0,0 +1,315 @@
# Mac 终端效率神技
## 增强各种预览的插件
- 预览查看图片分辨率&大小
- 代码语法高亮
- 快速预览zip压缩包内容
- 快速预览markdown格式内容
```powershell
brew cask install qlcolorcode betterzipql qlimagesize qlmarkdown
```
## iTerm2
具体的配置网上一大堆。贴一个本人亲身操刀操作过的[教程](https://www.jianshu.com/p/7de00c73a2bb)
程序员经常与终端操作打交道,所以很多命令便是做成了命令行模式,在自带的 Terminal 命令都保存在 `.bash_profile` 文件中,使用了 iterm2命令都保存在 `.zshrc` 中。
所以我们将很多命令保存且编辑。这里也是分享出我个人常用的配置。不断更新,喜欢的同学可以拿去直接使用
```Shell
# 输入自己常用的命令
# finder 相关指令
alias co='code ./'
alias fo='open ./'
# pod 和 xcode 工程相关指令
alias o='open *.xcodeproj'
alias po='open *.xcworkspace'
alias pru='pod repo update'
alias pi='pod install'
alias pu='pod update'
alias piu='pod install --repo-update'
alias repoanalysis='specbackwarddependency /Users/liubinpeng/.cocoapods/repos/51xianqu-xq_specs'
alias plint='pod lib lint --sources=git@git.caimi-inc.com:client/i-New-All-Specs.git,git@git.caimi-inc.com:client/CocoaPods-Specs.git --allow-warnings --verbose --use-libraries'
alias errorShow=' >1.log 2>&1'
# git 相关指令
alias gck='git checkout'
alias gm='git merge'
alias gb='git branch'
alias gbr='git branch -a'
alias gs='git status'
alias gc='git clone'
alias gl='git log'
alias ga='git add .'
alias gpull='git pull'
alias gpush='git push'
alias gcm='git commit -m'
alias glocalbranchPush='git push --set-upstream origin '
alias glg="git log --graph --pretty=format:'%Cred%h%Crest -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
# npm 相关指令
alias ns='npm start'
alias ni='npm install'
alias nb='npm run build'
alias nig='npm install -g '
alias nt='npm test'
# Vue 相关命令
alias vc='vue-init webpack' # (vue-init webpack test1)用法 vc test1
# React
alias rc='create-react-app' #(create-react-app todolist)用法 rc todolist
# React Native 命令
alias rnc='react-native init' #(react-native init todolist)用法 rnc todolist
# 终端打开应用程序
## 浏览器打开
alias OpenWithSafari='open -a "/Applications/Safari.app" '
alias OpenWithChrome='open -a "/Applications/Google Chrome.app" '
## 用 Typora 打开 markdown 文件预览写作效果。
alias OpenMDPreview='open -a "/Applications/Typora.app" '
## 用 DB Browser for SQLite 打开 db 文件
alias OpenDB='open -a "/Applications/DB Browser for SQLite.app" '
## 用 SourceTree 打开工程
alias openSourceTree='open -a "/Applications/Sourcetree.app/" '
# Flutter 环境变量
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH=/Users/liubinpeng/flutter/bin:$PATH
# Android SDK 路径
export ANDROID_HOME=~/Library/Android/sdk
export PATH=${PATH}:${ANDROID_HOME}/emulator
export PATH=${PATH}:${ANDROID_HOME}/tools
export PATH=${PATH}:${ANDROID_HOME}/platform-tools
# iOS 模拟器开启
alias iOSSimulator='open -a Simulator'
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# Node Version Manager
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
# Add RVM to PATH for scripting. Make sure this is the last PATH variable change.
export PATH="$PATH:$HOME/.rvm/bin"
export N_PREFIX=/usr/local/bin/node #根据你的安装路径而定
export PATH=$N_PREFIX/bin:$PATH
export PATH=/Users/liubinpeng/Desktop/Github/GitWorkflow/bin:$PATH
# chrome 源码探究
# export PATH=/Users/liubinpeng/Desktop/Tech-Research/iOS/depot_tools:$PATH
# 指定 pyhton 版本
# Setting PATH for Python 2.7
PATH="/System/Library/Frameworks/Python.framework/Versions/2.7/bin:${PATH}"
export PATH
# Setting PATH for Python 3.7.4
PATH="/usr/local/Cellar/python/3.7.4/bin:${PATH}"
alias python='/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7'
alias python3='/usr/local/Cellar/python/3.7.4/bin/python3'
# 禁止终端利用 homebrew 安装插件时候的自动更新
alias disableHomebrewUpdate="export HOMEBREW_NO_AUTO_UPDATE=true"
# 终端翻墙相关的设置(开关开启后稍微有点延迟)
function proxy_off(){
unset ALL_PROXY
echo -e "已关闭代理"
}
function proxy_on(){
export ALL_PROXY=socks5://127.0.0.1:1081
echo -e "已开启代理"
}
# PHP 包管理工具composer
export PATH="~/.composer/vendor/bin:$PATH"
# python 版本切换工具,全局生效
export PYENV_ROOT=~/.pyenv
export PATH=$PYENV_ROOT/shims:$PATH
# 效率
# 统计当前文件夹下文件的数量
alias showFilesCount='ls -l |grep "^-"|wc -l'
```
退出编辑,执行 `source .zshrc`
验证:在你的 git 项目所在的目录的终端下输入 `glg`
![Git日志](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2019-08-13-GitLogs.png)
## 为你的终端添加常用快捷键
我们经常在终端做着一些纯指令的事情天天敲、月月敲这个时间的很浪费的一天节约5分钟一年节约365*5/60 = 30H。一算吓一跳。我们每年在一些终端的指令上浪费了这么多时间。今天记录下如何给自己的 Mac 终端添加快捷键。
如果是 zsh 的话,可以编辑 `.zshrc` 文件里面的内容。自带的终端则编辑 `bash_profile`
脚本具体看上一条。
## 输出文件目录结构
```powershell
brew install tree
```
用法:
1. 我们可以在目录遍历时使用 -L 参数指定遍历层级
```powershell
tree -L 2
```
2. 如果你想把一个目录的结构树导出到文件 Readme.md ,可以这样操作
```powershell
tree -L 2 >README.md //然后我们看下当前目录下的 README.md 文件
```
3. 只显示文件夹
```powershell
tree -d
```
4. 显示项目的层级n表示层级数。例显示项目三层结构tree -l 3
```powershell
tree -L n
```
5. tree -I pattern 用于过滤不想要显示的文件或者文件夹。比如要过滤项目中的node_modules文件夹
```powershell
tree -I “node_modules”
```
## 浏览器相关
1. 搜索
在指定的站点下搜索 `inurl: jobbole.com intitle:Hybrid`
## 百度云盘破解
1. 会员体验一般为60秒通过本代码可以一直以会员的速度下载。
```
git clone https://github.com/CodeTips/BaiduNetdiskPlugin-macOS.git && ./BaiduNetdiskPlugin-macOS/Other/Install.sh
```
2. 百度网盘全速下载
- 先将你需要下载的地址复制进浏览器
- 然后在域名 baidu 后面拼接 wp
- 回车。访问页面选择下载地址1即可全速下载。
```
// 之前
https://pan.baidu.com/s/1ubcQH34m69hIjYu3CD2S2g
// 之后
https://pan.baiduwp.com/s/1ubcQH34m69hIjYu3CD2S2g
```
## 「安全与隐私」中系统不显示「任何来源」
在终端执行下面的命令
```
sudo spctl --master-disable
```
## 系统错误信息的集中展示
```Shell
pod spec lint *** 2>&1|tee 1.log
```
经常在终端做操作,有个情况就是在 iOS 的组件库维护的时候去检测合法性。你会发现满屏幕都是信息,甚至好几页,但是事实上错了问题后我们去翻页的时候发现很不方便定位问题,所以想到的就是将该过程产生的任何输出,集中打印到一个地方去查看。代码如上。
几个概念:
- 0 stdin1 stdout2 stderr
- |:管道。管道的作用是提供一个通道,将上一个程序的标准输出重定向到下一个程序作为下一个程序的标准输入。
- tee从标准输入中读取并将内容写到标准输出以及文件中。
## 终端查找文件
1. 终端查找以‘.log结尾的文件
```Shell
find . -name '*.log'
```
2. 安装 **ack** 包.
```shell
brew install ack
```
使用起来很简单,比如 `ack + 你要查找的关键词`,它可以将查到的结果展示在下面,有完整的文件路径.
![效果图](https://github.com/FantasticLBP/knowledge-kit/raw/master/assets/2019-09-30-searchTools.png)
### 终端每次执行 brew install 都会更新,非常耗时,如何禁止更新。
```shell
export HOMEBREW_NO_AUTO_UPDATE=true
```
## Mac 翻墙环境和终端翻墙环境
强烈安利一个我用过最快速、最便宜也就是性价比最高的科学上网工具。[链接](http://su.nseducloud.com/aff.php?aff=362) 个人使用的也就是一年120元不到一个月 60G 流量足够了,打开一些网站秒开。
另外很多开发都需要终端下载一些资源,但是终端走的通道和浏览器不一样,所以浏览器可以翻墙,终端还是不可以,所以可以在 `.zshrc` 或者 `.bash_profile` 下加下面的脚本
```shell
function proxy_off(){
unset ALL_PROXY
echo -e "已关闭代理"
}
function proxy_on(){
export ALL_PROXY=socks5://127.0.0.1:1081
echo -e "已开启代理"
}
```
使用 proxy_on 开启终端翻墙模式、proxy_off 关闭终端翻墙模式。
## 终端快捷键
很多情况下,我们会在终端编辑文件,为了提交效率就有了以下快捷键。
- ESC + dd删除当前一行的数据
持续更新中...

View File

@@ -0,0 +1,60 @@
# 2018年年终总结
> 临近年终,各大 App 纷纷给用户推送了年度小结,你在这年发了多少条微博、第一条微博是什么、最晚几点在发微博...这是微博给我推送的小结。我这么写的原因并不是让自己盲目跟风,看别人写自己也去写一个。古人云“吾日三省吾身”,那么年终肯定也是需要自我总结一下的。那么本文我将从今年的见闻方面、学习方面、健身方面、生活方面、来年计划对自己做一定的总结和规划
## 时间轴
2018年3月份进入一个大数据公司担任技术负责人一个月期间完成 App 开发,期间为了调试接口用 Charles 抓包分析 Android App 通信问题发现了 Android 端的一些 Bug 和服务端的 Bug找到并反馈给相应的技术。短时间开发完 AppApp 进入测试阶段,因为个人较为完美主义,也算是瞎搞吧,给 App 加入了 3D Touch 功能,不知道是不是鸡肋。完了之后组织技术分享。研究出了一套 Web 端的反爬虫技术方案并找公司的4个爬虫工程师调研看看我的研究成果好不好爬取。觉得效果不错公司内技术分享将技术选型、研发思路、部署等都给小伙伴们讲了。慢慢的小伙伴们叫我“大佬”。之后因为我们自己老爬取别人的数据所以对产品的数据安全问题比较在乎研究出 App 端的防抓包技术方案。
因为有 Web 经验,用 Vue 全家桶对公司的官网进行重构。技术、业务都进行了全新改版。
之后帮爬虫工程师解决了一些他们不太好解决的技术问题。比如爬取小程序内的数据、网站的数据。我们的爬虫程序经常在爬取一个网站数据后还需要给网站进行截图,现有的截图的成果会不太满意,比如会截不全、黑屏等,我将这个模块拎出来重写。我们有专门的编辑人员负责将一个报告去别的第三方平台校验数据正确性,这个过程比较耗费时间。利用浏览器插件的原理,给那个第三方平台页面上注入了一个”一键导出“按钮。点击一下当前页面的数据全部更新到我们自己的数据平台。
期间负责招聘一些职位、解决技术问题,成长较大,在身边的同事和领导那里得到一个较为良好的反馈,由于好的口碑让我做事更加快乐。形成一个良性循环。因为自己年龄很小,所以一直还是一个学生的态度吧,但是在这个地方完成了从学生到职场人的角色转换。
2018年12月底进入一个新零售大公司各方面很酷最近入职培训刚考完试还有3个月考核期希望自己继续加油吧
## 学习方面
iOS 方面RunLoop、Runtime、KVC、KVO 、GCD、多线程等的底层原理等。
Web 前端方面Vue 技术的熟练使用、包括在移动端的 H5 开发、Hybrid 的设计、通信规范。React Native 的学习等Flutter 的关注。
服务端方面: Node.js 做了一些接口开发、爬虫方面的事情。PHP 做了几个网站的服务端开发。
数据库方面:几个网站的数据库设计。知道了关系型数据库、非关系型数据库的区别。实战操作了 Redis 的使用场景。
自己也写了一些这方面的文章记录。
自己买了一些感兴趣的书,但是由于杂七杂八的事情,或者说懒惰吧。
- JavaScript高级程序设计(第3版)
- Objective-C高级编程iOS与OS X多线程和内存管理
- Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法
- Node.js实战 第2版
- 啊哈!算法
- iOS Auto Layout开发秘籍第2版
- HTTP权威指南
- 音视频开发进阶指南基于Android与iOS平台的实践
- iOS应用逆向与安全
来年计划要把前5本书看完吧。
## 健身方面
健身的话零零散散可能这周的话保持在4天下周可能保持在1天或者干脆没有。总的来说天气在温暖的时候不是很热很冷的情况下健身的次数会比较多。希望自己保持一定的健身频率。
## 生活方面
喜欢到处玩、认识有趣的人、吃好吃的、看各种电影、打乒乓球、游西湖、穿梭在杭州和附近城市的大街小巷,所以总体在这一方面花了较大的时间。所以来年要控制好生活娱乐和学习方面的比重。找到 Miss.Right携手未来
## 来年计划
2019年是自己的本命年我希望在学习、健身、生活、心智各方面都“能打”吧。现在是一个“iOS 高级工程师”的 title但是希望在这一年继续深入做一个很能打的工程师。身体是革命的本钱话糙理不糙我需要保持充分的运动时间和频率有一个更好的身材和更高的健康状态。不断学习深入看完自己喜欢领域的书籍做一些读书笔记应该是技术博客。优质社交、心智更加成熟。更懂人性做产品、过人生、都需要这一点。做一个感性且善良的人。平时喜欢帮助身边的朋友解决技术问题2019年继续、助人为乐一辈子践行。不要局限自己的思维模式、理科生可能有一些些太理性了。之前洗澡听到湖畔大学一个老师提到2个词语“管理员视角”、“用户视角”这里就不细说大体意思是蛮多理科生、程序员都在以“管理员视角”做系统将自己想的、现有的东西做成产品让用户按照现有的约定设置好的情况去使用产品而不是站在用户角度出发去设计一个易用的产品。
2019年多做一些技术输出、积累自己的知识和学习路上的一些心得、或者是总结吧。看完2本 iOS 、1本 Javascript、1本Nodejs 、1本设计模式、1本算法方面的书籍。培养正确的三观看到事物的本质做一个享受生活、善良的人
具体到技术细节就是:大前端落地到移动端身上的多端融合能力和动态化的能力。在这一年内有一定的输出和一定高度的总结。
(蛮多人谈Hybrid、Flutter、RN但是需要细节到技术栈的选取比如你的开发效率、业务迭代能力、程序性能等细节方面一个学习和应用到工作内容中去需要非常多的细节去考虑也需要有经验。)
做过前端的人都知道 Redux、Vuex 蛮多人都觉得好用,但是不去想想这个技术方案产生的原因是什么?符合什么场景、符合什么设计思想、设计模式在?你会用它那就是一个普通的初级程序员,你会修改代码去定制化也就是中级程序员,你懂得设计原理,你将前端的这个技术方案换到 Native 里面去实现一套类似的方案,你就是一个高级程序员,你很清楚的知道原理和设计模式、思想、利弊、场景后设计一个更加优秀的东西你就是专家。所以对于新技术先考量场景、再入门、再去思考设计原理、设计模式、设计哲学、设计思想...
总之2019年是自己的本命年希望自己更加能打、各方面不断优化自己过完2019年回归头来看看希望自己进步更多。

View File

@@ -0,0 +1,54 @@
# OKR
## 背景
OKR大概在2013年传入中国开始主要是一些有硅谷背景的初创企业在推行现在OKR逐步受到IT、互联网、高科技企业的追捧开始变得流行起来国内知名的互联网公司豌豆荚、知乎都成功的在企业内部实施了OKR
## 正确认识 OKR
百科定义OKRObjectives and Key Results即目标与关键成果法是一套明确和跟踪目标及其完成情况的管理工具和方法其实我更偏向于Paul R. Niven和Ben Lamorte给出的另外一个定义
OKR是一套严密的思考框架和持续的纪律要求旨在确保员工紧密协作把精力聚焦在能促进组织成长的、可衡量的贡献上。
按照这个定义可以明确以下几点:
严密的思考框架OKR并不是简单的每个周期跟踪一下执行的结果而是要超越数字本身思考这些数字对你以及组织来说意味着什么。
持续的纪律要求OKR代表了一种时间和精力上的承诺。
确保员工紧密协作OKR的目的在于促进员工团队的协作与组织的目标对齐而不是对员工的绩效考核。
精力聚焦OKR用于识别最关键的业务目标而不是一些待办事项的简单罗列。
可衡量的贡献:对最终的结果确保可以衡量,而不是靠主观评价。
促进组织成长判断OKR实施成功与否的最终标准就是看是否促进了组织成长。
事实上OKR并不是什么新鲜的事物它是在目标管理的发展过程中融合了一系列框架、方法和哲学的产物Peter Drucker在上世纪60年代提出了MBO的思想此后80年代S.M.A.R.T目标和KPI开始流行起来1999年John Doerr把OKR引入Google。
## 准备启动OKR
在组织或者公司中实施OKR最困难的部分在于前期的准备环节盲目的实施只会导致OKR流于形式只得其形不得其神最终的效果其实只是变成另一种形式的KPI而已不能给组织、公司和个人带来任何的成长。所以我建议在准备实施OKR之前先思考清楚下面几个问题。
## 为什么要实施OKR
在开始实施OKR之前不妨先问自己这样一个问题为什么要实施OKR不能很好的回答这个问题后面所做的一切都没有意义。如果答案只是“因为Google、Intel在用”、“想让公司变得更好”诸如此类的毫无意义的空洞答案那就不如暂时搁置直到思考清楚这个问题为止要让公司全员明白为什么实施OKR。
## 在哪个层面实施OKR
一般来讲OKR的实施有三个层面公司级、部门级、个人级但这并不意味着从开始就要三个层面一起实施。更好的做法是选定一个层面由点到面逐步推广最终全员实施OKR。
根据公司具体业务情况,可以有两种方式:
一是纵向实施开始只实施公司级的OKR在高管层实施成功后再推广到部门级最后再推广到个人级
二是横向实施选定某个业务单元或者部门在该业务单元中同时进行公司、部门、个人级OKR实施最后再在全公司范围推广。
## 实施OKR的周期
在开始OKR前需要考虑以多长的周期进行实施推荐的做法是按季度但这并不是绝对的也可以根据公司的业务情况按月为周期进行实施不建议按年、半年或者周为周期。周期太长导致目标的制定不合理周期太短关键结果的制定就变成了待办事项无法做到聚焦目标。推荐在季度和月之间选择一个作为公司实施OKR的周期。
## 对OKR的统一认识
最后最为重要的一点是参与实施OKR的所有人员是否对于OKR有统一的认识在没有达成共识前不要推行OKR否则在实施的过程中由于认识的偏差最终的OKR实施也会出现偏差。推荐的方式是在开始前通过OKR宣讲的方式进行统一认识在该宣讲会上需要明确回答上面提到的三个问题为什么要实施OKR在哪个层面实施OKR以及实施OKR的周期。
## 制定有效的OKR
接下里我将会详细介绍如何制定有效的OKR首先分别说明一下O目标和KR关键结果
目标:目标回答的是“我们想做什么”问题,是定性的,好的目标应该是有时限要求的,简洁直白的陈述,能鼓舞人心的、能激发团队共鸣。
关键结果关键结果回答的是“我们如何知道自己是否达成了目标要求”问题是定量的设计KR最具挑战的部分是如何把目标中定性的部分翻译为定量的数字化的表示。

View File

@@ -0,0 +1,60 @@
# 面试学问
1. 技术面试问你遇到的难题是什么,如何解决的?
在考察你的技术边界
2. 至今遇到过的比较麻烦的技术问题?
- 在App首次安装启动的时候商品列表快速滑动到底部再向上慢慢滑动看到商品view上面的文字和价格都显示正确但是图片显示是有问题的。想到的是由于SDWebImageView图片问题导致的因为再快速滑动的时候图片开启了下载任务但是异步下载的cell也在复用池了所以当你停止滑动看到商品view的时候正是之前的其他的图片任务下载结束这样子再去响应给view设置图片就会造成当前的显示的图片并不是当前model对应的图片。知道问题的原因那么事情就好解决啦。思路就是如何区分当前下载好的cell是不是当前正在现实的cell。所以思路有2个。
- 自定义的 cell 里面可以拿到 model.imageUrl那么当下载图片完成的时候可以在 block 里面去判断回调完成里面的 url 和 model.imageUrl 是否一致,一致的话就设置图片,否则不设置
- 在 cellForRow 里面去通过 indexPathForCell: 这个 api 拿到 indexPath然后根据拿到的复用的 indexPath.row 再和当前现实的 indexPath.row 做比较,如果一致则设置图片,不一致则不设置图片
- 代码在编译的时候一直报出问题某个pod的某个头文件file not found。最后排查问题发现工程中存在2个同名的 Framework一个版本新、一个版本旧。主工程中链接到旧工程中了所以一直找不到文件。
## 网络篇
- [App网络优化](https://blog.cnbang.net/tech/3531/)
- [IP 直连](https://www.jianshu.com/p/63a94cb46cd20。SNIServer Name Indication。一个服务器的 IP 可能对应多个域名,也就说可能有多个 HTTPS 证书,如果在请求的时候不指定具体哪个的证书,服务器可能会返回错误的证书
- 多路复用
## 系统优化
- [移动端监控体系](https://www.jianshu.com/p/8123fc17fe0e)
- [启动时间优化](http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time/)
稳定性、常见的稳定排查、crash率监控、提升工程效率的工具性能效率安全成本体验、电量优化、看大图体验
## 思考
组件:重用、解耦。模块:封装、隔离。
架构中模块复用的第一要求便是代码的功能组件化。组件化意味着拥有独立功能的代码从系统中进行抽象并剥离再以“插件”的形式插回原有系统中。这样剥离出来的功能组件便可以供其他APP使用从而降低系统中模块与模块之间的耦合性也同时提高了APP之间代码的复用性
借助于 Redux 的方式,将 MVC 更改为 MVCSs为store。MVC 中的 view 做到无状态,完全依赖于 Store 中返回的各种状态信息。
组件化之后分为技术组件、公用业务组件、每个业务线都是单独组件。通过把不同功能的组件代码拆分到不同的 pod 里,实现了业务线仅依赖于公共就可以迭代开发。改善了功能开发和协同版本。
流量过大,和服务器交互过多,采用 protoBuf 作为数据载体,有效减小流量消耗。
热修复JavascriptCore + Aspects
组件化、模块化、热修复、RN 兜底后架构模式:
![App架构](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2019-07-05-App-structure.jpeg)
- Runtime
- 网络
- Hybrid
- RN、Weex
- JavascoriptCore 如何传递 Block

View File

@@ -0,0 +1,17 @@
# Markdown 的妙用
## 1. 代码折叠功能
有时候我们会在文章上插入一些代码,但是这样的情况下我们的文章整体会显得很长,所以为了保证阅读性比较好,我们最好是将代码折叠起来,有需要的时候再点击展开。
我们需要使用 **\<details></details>** 和 **\<summary></summary>** 标签。如下所示
<details>
<summary>代码详情</summary>
```Objective-c
NSLog(@"hello world.");
```
</details>

View File

@@ -0,0 +1,83 @@
# 1995年的资深工程师和你谈谈如何进阶
## 自我介绍
网络ID杭城小刘城市顾名思义人在杭州。1995年出生本科毕业现在是一名 iOS 资深工程师。兴趣爱好广泛乒乓球、美食、电影、健身、山地车、养了2只布偶猫Simba & Bella、养花。技术领域iOS、Web 前端,写过 Node、PHP 后端服务、写过爬虫、研究过[反爬虫技术方案](https://github.com/FantasticLBP/Anti-WebSpider)。在成长的路上...
## 工程师生涯的两三事
刚毕业开始还是一名普通的 iOS 工程师,做的东西一般是跟着 TL 开会讨论需求完了自己脑补技术细节完了编码、UI 还原、测试、发布、维护。在第一家公司做开发的时候,某次和一个后端工程师对接口遇到问题,人家说“别跟我说接口有问题。你跟我说是什么样的问题?我需要参数”。然后初生牛犊(小菜鸟)就把 Xcode 下面的 Debug 信息截图发出去被人怼说我需要网络的具体参数Request、Reponse 信息。当时很尴尬,我在想封装好的网络框架,我一个个下断点 Debug 截图给你吗。后来才知道有 Charles 这么个抓包工具,简单搞了搞 Charles 之后就将截图 Request、Response 信息给他了,这样他没话说了,老老实实改了接口 Bug。当时他问我 Request、Response 的时候真的超尴尬,我说你等我半小时,我找好发给你。(😂 Too young, too simple
第一次看到 Charles 有那种看到仙女一样的感觉,因为它不只是可以抓包看 HTTP、HTTPS 的网络请求,还可以模拟数据、篡改网络请求信息、篡改网络返回的信息、模拟弱网环境、接口压力测试(类似于 Load Runner、还可以隔山打牛Map Remote请求域名 A 下的接口 a 却重定向到域名 B 下的接口 b。功能非常多让我爱上了它顺道写了一篇[文章](https://segmentfault.com/a/1190000017955654)。
另一个有趣的事情是慢慢在公司有了起色,自己钻研进步了很多。在做的东西 iOS Native + Hybrid 模式的应用,因为在校实验室期间有 web 前端经验,所以在公司经常设计 JS 与 NativeiOS、Android的通信机制、Hybrid 的能力等等Debug 的时候经常踩坑,比如 Android 浏览器访问 localStorage 需要开启权限、某些低版本的 Android 不支持 ES6 写法Vue、React等工程自动引入 Babel 打包构建的工程是转换过的。之前的老工程直接写 ES6则低版本浏览器不支持。还有一些 CSS 在 iOS、Android 两端表现不一致。因为公司和别的上市公司合作项目,成立了微信群,我们公司对外输出 SDK由于另一名同事解决不了。直接跟我说“刘哥上吧”。由于经常解决疑难杂症导致对面那个公司的项目经理问我要不要跳槽让我去他们公司工作 😂
## 优秀工程师如何进阶
说到工程师,肯定要谈如何进阶。那么我作为一个刚毕业不久,从 普通工程师 -> 高级工程师 -> 资深工程师,谈经验不敢当,说说个人的心路历程吧。
首先刚踏入职场,你必须完成从学生到职场的转换,这个转换不是说换个地方做事就行了,而是态度和观念需要改变。学生时代在校不管是课程作业还是毕设、或者学校实验室的那些东西,现在看看都很 low排除一些高端院校的顶级实验室项目
遇到项目,你要认真分析、思考、编码。完了之后想想有没有优化空间、[代码规范](https://github.com/FantasticLBP/codesnippets)。代码写多了,可以自定义自己的[工作流](https://github.com/FantasticLBP/GitWorkflow) 和[快捷键](https://github.com/FantasticLBP/knowledge-kit/blob/master/第六部分%20开发杂谈/6.11.md)。
很多人强调没时间去学习说什么白天在工作下班后可能要回家路上花费时间、吃晚饭、然后累了一天可能要想着健身、娱乐下。一天除非睡觉、吃饭时间你有多少时间所以我觉得学习和工作不是互斥的事件你需要矫正态度工作中的每个需求都是一次学习进阶和检验的过程别人给了需求你需要系统设计、架构设计、思考需要几个类、每个类负责什么行为、属性对外暴露什么接口类与类如何通信、如何低耦合、高内聚、可拓展Unit test 设计等等问题都要考虑清楚。剩下就是编码实现了,这个时候考虑的就是一行行代码如何书写,才符合团队规范、业界规范、代码如何分组、如何做到自解释、代码注释等等都需要做到极致。完成后跑单元测试、最后集成测试。提交给测试工程师的项目个人至少保证 90% 的测试 case 通过ut 覆盖率至少 90%。关于测试也有一堆经验,等后期我会出文章讲讲。
个人学习和工作的时候注意积累和归纳总结,梳理自己的技术栈和知识体系,等下次学到了新的东西塞到体系里面对应的地方去。最后你的知识系统会越来越完善。
工程师强调几个方面:
- 专业能力是第一要素。你的专业能力决定你是否具有不可代替行和价值。
- 软技能决定你的广度和效率:比如查找知识的能力、快速定位问题的能力、快捷键的熟练程度、自己的 WorkFlow、代码规范程度、为团队打造工程化的程度。比如我经常翻墙查找资料公司的网络和自己家里的网络都可以翻墙查找资料。使用 iterm2 自己制定了很多 iOS、Web 相关的快捷键、这将显著提高工作效率、一天提高1分钟一年下来就不少的时间节约如果想看我的快捷键或者 WorkFlow 可以在评论区留言)。团队的代码规范在前端开发中有 ESLint 集合业界的 js 规范比如 airbnb 或者标准的。iOS 这端我使用 shell 脚本开发了一套团队的代码规范,最后还有一套 shell 脚本检测全局工程的代码规范,最后会生成报表用浏览器自动打开。
- 不要过分追求框架等表层东西,要思考原理。很多人初学前端会纠结用 Vue、React、Angular哪个我觉得没必要你首先需要打好基础功基础功好了框架就很好学习了。框架一般做的事情是在现状的基础上做了封装让你很方便的做某些事情或者使用一些设计模式或者先进一些的开发方式比如单向数据流、虚拟 Dom、组件化等。这些东西为什么诞生还不是传统的命令式编程效率太低、操作 DOM 成本太高了,复杂逻辑的页面维护很复杂吗?因为是命令式编程,所以你需要思考每一步步骤,以及中间产生的状态变量,告诉计算机如何处理具体逻辑,导致代码量太大,维护不方便。响应式编程 + 虚拟 DOM + 单向数据流催生了类 React 的前端框架。比如我之前就看过 Vue 的关键逻辑的源代码,看过 React 的 Redux 的源代码。
- 你的水平高了你关心的技术点应该就是业界的研究方向了,比如多端融合能力。你会看到现在的 Flutter、React Native、Hybrid 他们不是没有关系的而是一步步演进升级。电商公司其他业务不再举例业务经常变、运营活动经常变传统的开发方式需要发布、审核、上线iOS 这里尤其负责,审核严格,随意这样的流程不能满足,早期的 Hybyrid 就是这样诞生的Native 提供基础能力JS 写业务逻辑和 UI操作但是这样很零散比如 UI 操作JS 需要一个 UINative 就需要事先注册号或者提供好这样的能力。React Native 解决了这个问题JSX 的方式写业务操作数据setState 做 diff 算法计算出需要更新的虚拟 DOM在移动端这样的虚拟 DOM 就可以和 Native UI 组件进行绑定,这样就可以有 Native UI 能力。JS 写业务Native 捕获事件回调给 JS然后操作数据继续 setState。这样还不错但是在低端手机上会卡顿其中一个问题就是不同语言JS、native语言之间通信效率比较低Flutter 诞生了Dart 诞生就是为了解决 JS 的缺点。Google 自己的 skia 渲染引擎封装了 OpenGL 接口,所以不需要 Native 提供 UI 能力Dart 使用声明式写 UI、Skia 去渲染看上去还不错,所以一开始国内的咸鱼团队就在跟进 Flutter现在阿里 all in Flutter。
## 经验分享
大多数人喜欢碎片化时间阅读一些文章或者自己感兴趣的技术博文。比如你在上下班路上、点餐等饭时间看几个公众号技术文章,很多人会大致浏览完。我觉得这样不如不读,或者收效甚微。因为脑子只有印象的话,看完的文章过半年后问,肯定一问三不知了。与其多篇文章大致浏览,不如精读一篇文章,并动手实践每个技术点和细节。必要时做好博文记录最后总结输出。
另外对于每个技术不要停留在会用(我称之为 api 资深工程师)而是知道这个 api 背后的原理,设计模式、设计的优缺点。比如 iOS 领域著名的 WKWebView 很多人知道 NSURLProtocol 可以拦截其他的网络请求却拦截不到它里面 post 的 body 内容。你查看了 webkit 源代码之后就知道 WKWebView 官方宣传快,是说自身做的事情少了,很多任务比如网络是新开了一个独立线程去处理,所以独立线程处理网络完了通过 IPC 的方式将 post 的 body 通过压缩然后 IPC 给 WKWebView 这会非常消耗资源,所以系统索性不给你传递了。
带着这个疑问看看 Chrome for iOS 的开源项目至于为什么会看它因为个人研究多端融合能力、Chrome 这样的浏览器如何渲染处理等流程感兴趣所以看的),看到它里面在用 post 传 body。纳闷了和 webkit2 源代码不一致。这些现象等都是需要深入才可以理解的。当你遇到一个问题发现网上找不到资料或者资料比较少的时候你就算对这个问题的研究比较深入了。
此外,不管做产品还是技术都不要凑合,必须要做到极致或者最好。上面说的反爬虫技术是我在公司担任 iOS 工程师的时候做的。当时进去一个月写完一个 App追到 Android 进度。然后不满足于进度,在此基础上做到的一些优化、且通过抓包方式进行业务测试的时候找到了 Android 和服务端的一些 Bug最后还发现安全性较低在此基础上做了 HTTPS + 证书验证 +RSA 证书校验、AES 数据加密,做到了 App 被别人抓包马上就断掉链接。假如技术再高明些看到请求信息也是加密过的(不是 HTTPS 自己的加密,是自定义的加密)和防重放策略。
之后鉴于公司的网站太落后,用 Vue 进行重写,再做了安全升级等工作,这样总经理看到个人能力,担任小公司大前端负责人的岗位。这阶段的成长也蛮快的
然后换工作也是一样严格要求自己半年时间做了无痕埋点、组件化、模块化、Hybrid 能力提升、商城业务模块开发等等从高级工程师升级为资深工程师。个人目标2年后成为技术专家。
很多人会去问有没有较好的学习资料是什么?我觉得如果有人回答除官方文档之外的答案,那么这个人本身就不够专业。在我看来官方文档是设计者(最熟悉技术细节的人)写出的注释和说明。那么肯定是最佳实践。举个例子 Objective-C 里面对 NSDictionary 进行处理成 JSON 字符串,解析的结果是会带空格和换行符的,但是服务端恰好如果对空格和换行敏感的话,那么你们的逻辑就会和预期的不一致。看看下面的代码。
```Objective-C
NSJSONWritingSortedKeys兼容性、NSJSONWritingPrettyPrinted (换行符)
NSDictionary *dict = @{@"name": @"lbp"};
NSData *json = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding];
````
很多人转换后可能会去做字符串处理,正则替换空格和换行符。稍微好一些的可能会看到官方的在 iOS11 推出一个新的枚举值 `NSJSONWritingSortedKeys`。那么就是判断当前系统小于 11 则字符串替换,否则就使用新的参数。如果你仔细看官方文档,上面说的非常仔细。看看下面的官方说明。
> Generate JSON data from a Foundation object. If the object will not produce valid JSON then an exception will be thrown. Setting the NSJSONWritingPrettyPrinted option will generate JSON with whitespace designed to make the output more readable. **If that option is not set, the most compact possible JSON will be generated.** If an error occurs, the error parameter will be set and the return value will be nil. The resulting data is a encoded in UTF-8.
另外,越来越觉得架构设计对于架构组同学来说是非常重要的。
为什么假设你一个需求预期10天时间前期架构设计、类的设计、Uint Test 设计估计7天到时候编码开发2天完成。
这么做的好处很多,比如:
- 除非是非常优秀不然脑子想的再前面到真正开发的时候发现有出入coding 完发现和前期方案设计不一样。所以建议用流程图、UML图、技术架构图、UT 也一样,设计个表格,这样等到时候编码也就是 coding 的工作了,将图翻译成代码
- 后期和别人讨论或者沟通或者 CTO 进行 code review 的时候不需要一行行看代码。你将相关的架构图、流程图、UML 图给他看看。他再看看一些关键逻辑的 UT保证输入输出正确一般来说这样就够了
- 软件项目管理也一样确定好关键时间节点、甘特图、确定干系人、kick-of meeting、定期碰头等
## 程序员这个工作怎么样?
个人是很喜欢程序员这个工种的。做事情纯粹些、且培养了不断学习思考的能力和习惯。不断学习和思考是每个行业都需要的基本素养,所以看到事情本质、不断学习、不断进阶就是人生常态吧

View File

@@ -0,0 +1,22 @@
# 区块链技术和比特币
> 近日, 国家在中央政治局第十八次集体学习时强调: 把区块链作为核心技术自主创新重要突破口,加快推动区块链技术和产业创新发展.
一夜之前,区块链技术成为大家口中的焦点, 此外各种相关的“币”也摇身一变,翻了好几番身价.可能有人要问了区块链技术和比特币、各种币到底是什么关系? 网上各种“炒币、割韭菜”这些词捆绑在一起.
那么到底什么是区块链技术、什么是比特币?
### 中心化和去中心化
1. 周末在家从电影天堂站点下载的电影,这个行为属于中心化
2. 假如电影天堂的某部电影被10万用户下载过,都保存在自己的电脑里.除非10万人的电脑同时坏掉、互联网服务不可用,否则这部电影不可能消失,这就是去中心化
假如存在每个人电脑上面的电影被黑客入侵,破坏或删除了电影内容. 怎么办?
有一个很聪明的人叫做“中本聪”,他发明了一种新技术.假如有这样一个协议,协议内容规定
```
本人承认:不得编译修改本影片中的任何细节, 同时针对这部影片的任何行为, 都会按时间戳记录, 并同步广播更新存储
```
这样一来, 假如张三看电影到 12分50秒, 他电脑重的影片会按时间戳更新最新播放进度的记录,然后广播传输给其他的 10万台电脑,同步更新保存张三电脑中的数据.

View File

@@ -0,0 +1,52 @@
# 如何写一份夺目的简历
经常有很多朋友或者学弟学妹让我辅导简历, 让简历在筛选的时候从一堆被筛选的简历里面更加夺目,从而获得一个面试机会.自己写过几次,也帮助朋友辅导过、也面试过别人,所以有一点点小心得,而且这个心得是随着自己的技术阅历和对人生阅历的增长而持续改变的,所以这篇文章是会持续更新的.
> 如何让简历加分、夺目,本质上就是让简历的内容更加有价值、让看的人更加知道你具备什么样的技能和综合素质, 和当前的招聘需求是否足够匹配, 以致于看完之后能否给你邀约,给你和面试官一个互相了解的机会.(偏向于社招,对于学生而言也有一定的参考价值)
## 什么是简历
> 个人简历是求职者给招聘单位发的一份简要介绍。包含自己的基本信息:姓名、性别、年龄、民族、籍贯、政治面貌、学历、联系方式,以及自我评价、工作经历、学习经历、荣誉与成就、求职愿望、对这份工作的简要理解等等。以简洁重点为最佳标准。 ~摘抄自网络
一份简历可以让查看简历的人(为什么不用面试官? 因为一般来说你投出去的简历可能是某公司的 HR、也有可能是交给朋友内推、也有可能是某个猎头,所以查看简历的人身份可能有很多)快速的了解你, 知道你的基本信息(什么学校、什么专业、时间段)、专业技能信息(掌握什么技术、掌握什么行业经验)、实践经验信息(在什么时间段在什么公司做过什么项目,有何成长).
所以鉴于上述目的和意义,你的简历需要具有真实性、针对性、条理性.
## 怎么样写好
简历只是一个敲门砖,我们的目的是让面试官看上去产生好感,然后给我们一个面试的机会,简历不需要表达全部的自己,面试官一定是从面试中获取大量的情报来深入了解你。所以简历写到什么程度,我们的目标是相当明确的。
如何从简历中让人看出你【做成了】什么,以及你未来【可能做成】什么,以下几点可以参考:
1. 表达一件有挑战的完整的事情.
比如实现了一个平台的架构推导和落地; 再如使用三个月时间经历四轮优化将系统的整体性能提升了 1.2 倍等等;而不是我写了某个网站的前端,沉淀了几个通用组件等等
2. 展示你跨专业的特性
比如作为前端工程师,我在运维工作上做了比较突出的贡献;在图形图像方面有深入研究和良好产出;曾并发管理 4 个中型项目并保证准时交付等等;
3. 从业务价值的角度去发现问题和分析问题
比如通过融合两个相似系统后,降低了运营的成本,提高了数据从线下到线上展示的效率等;而不是简单地说,实现了数据层的合并,统一了前台交互等这种纯技术的表达
说到底,还是需要让面试官看到你这几方面的能力:
- 技术综合能力/学习能力(硬实力)
- 业务洞察力(理解力)
- 拿结果的能力(执行力)
## 可参考的点
看过不少简历,优秀的人大概都有这么一些特征(具备两三条甚至更多):
1. 名企呆过,有大厂背书
2. 参与的项目非常有震撼力
3. 在技术领域跨度大的项目有成绩
4. 有门槛的技术领域里有沉淀
5. 技术产出对团队/业务有突出的影响
6. 接二连三的专利
7. 拿过一些很难拿到的奖项
8. 非常好的韧劲,某一/几件事情上坚持不懈
9. 思考力惊人,行动力惊人
10. 思维敏捷且逻辑无比严谨
11. 具备一定的社区影响力​​​​

View File

@@ -0,0 +1,4 @@
# 团队写作、标准开发流程
### 研发流程规范

View File

@@ -0,0 +1,26 @@
# 云服务器靠谱推荐
作为计算机从业人员,不管做前后端、算法、运维有台自己的云服务器至关重要。
## 为什么要买云服务器
首先,我作为一名客户端工程师分析下我购买云服务器的初衷。 我首先是想大搭建自己的博客系统、然后我还会写一些 App 然后自己写 App 的后台服务器,可能是 Node 语言也可能是 PHP 语言。也有可能部署一些定时服务或者 Spider 项目 😂
1. 可能有些人说有成熟的博客系统,为什么要自建?
我想着自己搭建的话,可以随意定制开发;另外可以掌握服务端运维的一些知识
2. 那有了云服务器可以做什么?
自己做文件服务器、邮件服务器、App 服务器、爬虫脚本、定时服务、个人博客、社区平台等等、也可以训练模型等等
## 推荐靠谱的产品
之前用过阿里云服务、新浪云服务。这次良心安利一波腾讯云服务,在 11.11 折扣还在,价格很良心。推荐我购买的配置
![云服务器](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2019-11-26-VPS.png)
[购买地址](https://cloud.tencent.com/act/cps/redirect?fromSource=gwzcw.3018172.3018172.3018172&redirect=10140&cps_key=8ec198cb362709e63ff6e05753a3d0d3&from=activity)

282
Chapter7 - Geek Talk/7.2.md Normal file
View File

@@ -0,0 +1,282 @@
# Charles 从入门到精通
## 内容清单
- Charles 的简介
- 安装 Charles
- Charles 初始化设置
- 过滤网络请求
- 截取HTTP/HTTPS数据
- 模拟弱网环境
- 修改网络请求
- 修改服务器返回内容
- 服务器压力测试
- 反向代理
- 解决与翻墙软件的冲突
## Charles 的简介
**Charles** 是目前最主流的网络调试工具Charles、Fiddler、Wireshark...)之一,对于一个开发者来说与网络打交道是日常需求,因此很多时候我们需要调试参数、返回的数据结构、查看网络请求的各种头信息、协议、响应时间等等。所以了解 Charles 并使用它
Charles 通过将自己设置为系统的网络访问代理服务器,这样所有的网络请求都会通过它,从而实现了网路请求的截获和分析。
Chareles 不仅可以分析电脑本机的网络请求HTTP 和 HTTPS还可以分析移动端设备的网络请求。
Charles 是收费软件,作者开发出这样一个方便开发者使用的伟大工具,我们鼓励使用正版软件,但是对于一些囊中羞涩或者学生来说,有破解版的更好,别担心,这些我都准备好了,下一个 section 会讲解如何下载安装。
## 安装 Charles
- 方式1[ Charles 官网地址](https://www.charlesproxy.com/download/),根据你的电脑操作系统选择合适的下载方式。此时下载下来的是需要收费的,不差钱的同学当然可以直接购买。[购买链接](https://www.charlesproxy.com/buy/)
- 方式2:按照方式1的方式去官网下载然后下载相应 **[JAR包](https://pan.baidu.com/s/1QqSiEwMGIFrxwyKYg_6Kdw)**。这里以 MAC 为例,打 **Finder**,选择应用程序,选中 Charles右击并选择“显示包内容”看到 **Contents** 目录,点击进去选择 **Java** 文件夹,将下载下来的 **JAR包** 拖进去替换。至此,完成了 Charles 的破解。
## Charles 初始化设置
Charles 的工作原理是将自身设置为系统的代理服务器来捕获所有的网络请求。所以使用 Charles ,我们必须设置 Charles 为系统的代理服务器。
打开 Charles当第一次启动的时候如果没有购买或者没有破解会有倒计时之后会看到软件的主界面然后会请求你赋予它为系统代理的权限。点击授权会让你输入当前系统用户的密码。当然你也可以忽略或者拒绝该请求然后等想要抓包的时候将它设置为系统的代理服务器。步骤**选择菜单中的“Proxy” -> "Mac OS X Proxy"。**如下图:
![Charles在MAC的初始化](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/Charles-Setting.png)
之后你的电脑上的任何网络请求都可以在 Charles 的请求面板中看到
看看 Charles 的主界面
![Structure模式查看网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-004135@2x.png)
![Sequence模式查看网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-004435@2x.png)
- 图上红色圈1:这里代表所有网络请求的展示方式。分别名为 “Structure” 和 “Sequence”。
- Structure 将所有的网络请求按照域名划分并展示
- Sequence 将所有的网络请求按照时间排序并展示
- 图上红色圈2一些的网络请求设置比如 HTTPS 以及端口等信息都在这个菜单栏设置
- 图上红色圈3证书设置都在这里进行
## 过滤网络请求
由于 Charles 可以将电脑或者设置过的手机的所有网络请求捕获到,而且我们分析网络传输应该是针对某个特定的网络下的抓包分析,为了清楚明显地看到我们感兴趣的网络请求通常会用到 Charles 的**“过滤网络请求的功能”**。
- 方法1:在 Charles 主面板的左侧所有网络请求的下方可以看到看到一个 **”Filter“** 输入栏在这里你可以输入关键词来筛选出自己感兴趣的网络请求。比如我想分析的网络请求来自于”www.baidu.com" 下,你可以在下面输入"baidu"即可。
![Filter 过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-090550.png)
- 方法2:在 Charles 菜单栏的顶部会看到 “Proxy” 的选项,点击菜单栏选择 “Proxy” -> "Recording Settings" 。选择 “include”。看到面板上面有一个 “Add” 按钮,点击后在弹出的面板里面设置好我们需要分析的网络请求的**协议、主机名、端口、路径、参数**,当然你也可以只设置一些主要的信息,比如协议和主机名的组合。
![Recording Settings 过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-090926.png)
- 方法3:一般打开 Charles 并设置好配置信息后(比如电脑本机或者设置过代理的手机)所有的网络请求都将在 Charles 的面板上显示,同时我们感兴趣的网络请求如果也在面板上显示的话,**“Structure”模式下**可以选中需要分析的网络请求,鼠标右击选择**“Focus”**。**“Sequence”模式下**可以在面板的网络请求显示面板的右下角看到一个**Focus**按钮,点击勾选后 Charles 只会显示你感兴趣的网络请求。
![Structure模式下Focus过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午9.22.39.png)
![Sequence模式下Focus过滤网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-092259.png)
## 截取HTTP/HTTPS数据
### 截取 HTTP 请求
Charles 的主要目的是抓取捕获网络请求,这里以 iPhone 的抓包为例讲解。
#### Charles 的设置
要截获 iPhone 的网络请求就需要为 Charles 开启代理功能。在菜单栏选择**“Proxy” ->"Proxy Settings"**。填写代理的端口号并将**“Enable transparent HTTP proxying”**勾选上。
![抓取手机网络请求的电脑端设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-092856.png)
### iPhone 上的设置
在电脑“系统偏好设置”中心打开网络查看本机 IP 地址,打开手机“设置”->“无线局域网”,进入当前使用的网络,点击进入当前 WIFI 的详情页(可以看到当前 WIFI 的基本信息包括子网掩码、端口、IP地址、路由器在最下角可以看到**“DNS”和“HTTP代理”**2个section。我们点击**“配置代理”**,设置 HTTP 代理选中“手动”。服务器处填写电脑ip地址端口写8888。设置好后我们打开 iPhone 上的任意需要网络请求的应用,就可以看到 Charles 弹出请求的确认菜单,单击"Allow"按钮,即可完成设置。
![抓取手机网络请求的手机端设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/11532309922_.pic.jpg)
### 截取 HTTPS 请求
如果你需要捕获 HTTPS 协议的网络请求,那么则需要安装 Charles 的 CA 证书。步骤如下;
- 首先需要在 MAC 上安装证书。点击 Charles 顶部的菜单栏,选择 **“Help” -> "SSL Proxying" -> "Install Charles Root Certificate"**。
![HTTPS抓包电脑端证书安装](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aa40822368.png)
- 在 keychain 处将新安装的证书设置为永久信任
![HTTPS抓包电脑端证书信任](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aab5332151.png)
- 即使安装了 CA 证书Charles 默认是不捕获 HTTPS 协议的网络请求,所以我们需要对某个主机下的网络请求抓包分析的话,选中该网络请求右击选中 **“SSL Proxying Enabled”**。这样就可以看到我们感兴趣的HTTPS 网络请求了。
![Charles确认开启抓取HTTPS](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午9.47.09.png)
如果你需要捕获移动设备的 HTTPS 网络请求,则需要在移动设备上安装证书并作简单的设置
- 选择 Charles 顶部菜单栏选择 **“Help” ->"Install Charles Root Certificate on a Mobile Device or Remote Browser"**。然后就可以看到 Charles 弹出的安装说明了。
![Charles提示手机端安装CA证书](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-101259.png)
- 在手机设置好 Charles 代理的情况下,在手机浏览器输入 **“chls.pro/ssl”**。安装提示下载好**CA证书**。
- 验证刚刚安装的 CA证书
![描述文件的验证](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a99ea05b2e.png)
- iPhone 打开设置 -> 通用 -> 关于本机 -> 证书信任设置 -> 开启开关
![手机端CA证书的信任](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a9ca26c907.png)
- 在 Charles 菜单栏 Proxy -> SSL Proxying Setting -> 点击 Add 按钮 -> 在弹出的对对话框设置需要监听的 HTTPS 域(*:代表通配符)
![HTTPS抓包端口和主机设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9aaad2c0ff8.png)
- 设置完毕,尽情抓取你想要的 HTTPS 网络请求吧。
![抓取京东HTTPS数据](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/164ac9a9a966fafe.png)
## 模拟弱网环境
在平时开发的时候我们经常需要模拟弱网环境并作弱网环境下的适配工作。Charles 为我们提供了这个服务。
在 Charles 菜单栏选择 **“Proxy” -> "Throttle Settings"**。在弹出的面板上设置网络请求的参数(上行,下行带宽、利用率、可靠性等等信息)。如下图所示。
![模拟弱网环境](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午10.27.22.png)
如果你想对**指定主机**进行弱网环境下的测试可以点击上图的“Add”按钮在弹出的面板上设置协议、主机、端口来对指定的主机进行弱网设置。
![设置指定网络请求的弱网模拟](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-102606.png)
## 修改网络请求
对于捕获的网络请求我们经常需要修改网络请求的cookie、Headers、Url等信息。Charles 提供了对网络请求的编辑和重发功能。只需要选中需要修改编辑的网络请求,在对应的右上角看到有一个“钢笔”的按钮,点击后就可以对选中的网络请求进行编辑了,编辑好后可以在右下角看到 **Execute** 按钮。这样我们编辑后的网络请求就可以被执行了。
![修改网络请求](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-105440.png)
## 修改服务器返回内容
很多时候为了方便调试代码,我们会有这种需求,修改接口返回的数据节点或者内容、甚至是状态码。比如数据为空、数据异常、请求失败、多页数据的情况。 Charles 为我们提供了超实用的功能,**“MapMap Local、Map Remote功能”、Rewrite功能、Breakpoints功能** ,都可以实现修改服务端返回数据的功能。但是有区别和适用场景:
- Map 功能适合长期地将某一请求重定向到另一个指定的网络地址或者本地 JSON 文件
- Rewrite 功能适合对网络请求进行一些正则替换
- Breakpoints 功能适合对网络请求进行一些临时性的修改(类似于我们开发的断点作用)
### Map 功能
Map 功能分为 Map Local将某个网络请求重定向到本地 JSON 文件) 和 Map Remote 功能(将网络请求重定向到另一个网络接口)。
在 Charles 菜单栏选择 **“Tools” -> "Map Remote" 或 “Map Local”** 即可进入相应的功能模块。
#### Map Remote 功能
适合于切换线上到本地、测试服务到正式服务的场景。比如下图从正式服务切换到测试服务
![Map Remote](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-113200@2x.png)
#### Map Local 功能
我们需要填写重定向的原地址信息和本地目标文件。我们可以先将某个接口的响应内容保存下来(选择对应的网络请求,右击点击 **Save Response** )成为 data.json 文件。然后我们编辑里面的 status 、message、data 等信息为我们想要的目标映射文件。
![Save Response](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018-07-23%20上午11.37.44.png)
如下所示,我将一个网络请求的内容映射到我本地的一个 JSON 文件。之后这个请求的内容都从网络变为返回我本地的数据了。
![Map Local](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-113951.png)
Map Local 可能会存在一个小缺陷,其返回的 HTTP Response Header 与正常的网络请求不一样,如果程序设置了校验 Header 信息,此时 Map Local 就会失败,解决办法是同时使用 **Rewrite功能**将相关的HTTP 头部信息 rewrite 成我们需要的信息
#### Rewrite 功能
Rewrite 适合对某个网络请求进行正则替换,以达到修改结果的目的。
假如我的 App 的界面上的显示的功能模块及其点击事件是根据接口来完成的,我想实现替换功能模块的名称的目的。步骤:点击顶部菜单栏的**“Tools” -> "Rewrite"**。在弹出的面板上勾选 **“Enable Rewrite”**。点击左下角的 **Add按钮**,在右上角的 **Name**处写好本次配置的名称(如果有多个 Rewrite为了后期容易区分
- 可以针对特定的网络请求进行 Rewrite。可以点击右上角 **Location** 面板下面的 **Add按钮**。在弹出的面板上设置网络请求配置信息。注意此时需要同时设置 Protocol、Port、Host、Path信息我测试加了 Protocol、Host、Port这3个是无效的
![Rewrite 针对特定网络请求的设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-115820.png)
- 然后对指定的 **Type****Action** 进行 Rewrite。
Type 主要有 Add Header、Modify Header、Remove Header、Host、Path等等。
Where 可以选择 Request 和 Response。指的是下面的修改是针对 Request 还是 Response
![Rewrite 设置范围](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-115855.png)
- 完成设置后点击 **Apply** 按钮,即可生效。下次继续请求该网络,返回的内容就是我们刚刚设置的内容。比如当前的“政策法规”要变成“哈哈哈,我是假的政策法规”。这时候就可以使用 Rewrite 功能
![Rewrite 测试结果](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-114826.png)
#### Breakpoints 功能
Breakpoints 相比于其他几个修改网络请求的特点是只是针对当前的网络请求Breakpoints 只存在于设置过的当前的网络请求Charles 关闭后下次打开 Breakpoints 消失了。想要修改网络请求 Breakpoints 步骤最简单,跟我们调试工具里面设置的断点一样方便。
对于我们设置了 Breakpoints 的网络请求, Charles 会在下次继续访问该请求的时候停止掉,就跟 debug 一样。此时我们可以 **Edit Request**,修改过 Request 之后点击右下角的 **Execute** 按钮。然后等到服务端返回的时候继续是断点状态,此时可以 **Edit Response**。步骤: **选中某个网络请求 -> 右击 -> 点击“Breakpoints”。**
如下图:对该接口设置了 Breakpoints。请求网络后 Edit Response点击 execute 后服务端返回的结果就是我们编辑的内容了。
![对指定的网路请求设置断点](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151811.png)
![在Reponse的时候修改返回的数据](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151850.png)
![再次请求该接口返回的数据为我们设置过的](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-151906.png)
## 服务器压力测试
我们可以使用 Charles 的 **Repeat** 功能地对服务器进行并发访问进行压力测试。步骤:**选中某个网络请求 -> 右击 -> Repeat Advanced -> 在弹出的面板里面设置总共的迭代次数Iterations、并发数Concurrency -> 点击“OK” 。**开始执行可以看到以设置的并发数的规模,进行总共达设置的总共迭代次数的访问。(专业的压力测试工具:**Load Runner**
![简单压力测试](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-135943.png)
## 反向代理
Charles 的反向代理功能允许我们将本地指定端口的请求映射到远程的另一个端口上。设置:**点击顶部菜单栏 Proxy -> 点击 Reverse Proxies**。
如下所示,我将本地的 8080 端口映射到远程的 80 端口上,点击 OK 生效后,当我继续访问本地的 80 端口,实际返回的就是远程 80 端口的提供的内容了。
![反向代理设置](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/WX20180723-141057.png)
## 解决与翻墙软件的冲突
Charles 的工作原理是把自己设置为系统的代理服务器,但是我们开发者经常会利用 VPN 翻墙访问谷歌查找资料这些翻墙软件的工作原理也是把自己设置成为系统的代理服务器为了2者和平共处。我们可以在 Charles 的 External Proxy Settings 中将翻墙的代理端口等信息填写。同时我们需要关闭翻墙软件的自动设置,更改为**“手动模式”**。(使其不主动修改系统代理)
## 总结
Charles 功能强大、界面简洁,读完这篇文章并做出练习,相信你能很快掌握它,“工欲善其事,必先利其器” ,掌握了它,相信可以为你大大提高开发中调试网络的效率。**Enjoy yourself**
## 参考链接
[唐巧的博客](http://blog.devtang.com/2015/11/14/charles-introduction/)

View File

@@ -0,0 +1,127 @@
# 规范化团队 git 提交信息
> 同一个工程项目为了方便管理git 的 commit 信息最好按照一定的格式规范,以便在需要的时候方便使用。什么是方便的时候,比如出现了一个线上 bug所以需要回滚操作知道了提交信息可以方便的定位问题。
## 实现
可以马上想到的是利用 shell 结合 git hook 实现在 git commit 阶段检查输入是否符合规范。符合就通过,不符合就不通过,抛出警告信息,并给出提示信息。
### 规范是什么
常见的分类有下面几种情况:
- build修改项目的的构建系统xcodebuild、webpack、glup等的提交
- ci修改项目的持续集成流程Kenkins、Travis等的提交
- chore构建过程或辅助工具的变化
- docs文档提交documents
- feat新增功能feature
- fix修复 bug
- pref性能、体验相关的提交
- refactor代码重构
- revert回滚某个更早的提交
- style不影响程序逻辑的代码修改、主要是样式方面的优化、修改
- test测试相关的开发
### 轮子
在 github 上有 [commitlint](https://github.com/conventional-changelog/commitlint) 这个项目,它可以很方便的在工程中做配置,并允许你自定义上面说的「规范」、「分类」。
[commitlint](https://github.com/conventional-changelog/commitlint):用于检查提交信息
[husky](https://github.com/typicode/husky)hook 工具,用于 git-commit 和 git-push 阶段。
怎么用?
1. 初始化一个 node 项目:`npm init -y`
2. 安装所需依赖。`npm install --save-dev @commitlint/config-conventional @commitlint/cli husky`
3. 在工程根目录下新建配置文件,名称为 `commitlint.config.js`
4. 在 commitlint.config.js 中添加配置信息
```shell
const types = [
'build',
'ci',
'chore',
'docs',
'feat',
'fix',
'pref',
'refactor',
'revert',
'style',
'test'
];
typeEnum = {
rules: {
'type-enum': [2, 'always', types]
},
value: () => types
}
module.exports = {
extends: [
"@commitlint/config-conventional"
],
rules: {
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72],
'type-enum': typeEnum.rules['type-enum']
}
};
```
5. 在 package.json 文件中添加以下代码,代码层级跟 **devDependencies** 同级。
```json
"husky": {
"hooks": {
"pre-commit": "echo '哈喽,小伙伴们,在这里可以做测试相关的逻辑哦,一般结合公司的 ci'",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-push": "echo 提交代码前需要先进行单元测试 && 可以做测试相关"
}
}
```
上面的流程配置完成,当你在提交 commit 信息的时候如果输入不符合 `<type>: <subject>` 规则,会给出提示信息。
type 就是上面的种类subject 就是需要提交的文字概括。比如feature增加摇一摇推荐酒店功能。
小说明:
- 如果某次提交想禁用 husky可以添加参数 `--no-verify`
```shell
git commit --no-verify -m "xxx"
```
### 大体流程
安装包 husky 的时候,会在目录 `.git/hooks/` 下生成一堆 shell 脚本,负责 hook git 相关时机。
`"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"` 这个配置告诉 git hooks当执行 `git commit -m` 的时候触发 commit-msg 钩子,并通知 husky从而执行 `commitlint -E HUSKY_GIT_PARAMS`,实际上执行的是 `./node_modules/husky/bin/run.js`,读取 commitlint.config.js 里的配置,然后对我们 commit -m 里的字符串校验,如不通过则输出错误信息并终止。
## 拓展篇
git commit 的几个钩子,也暴露出来了,所以可以结合时机做一些额外的逻辑。
- pre-commit在 git commit 之前触发
- commit-msg在编写 commit 信息的时候触发
- pre-push在 git push 之前触发
所以基于上述时机,可以根据项目特点做一些别的事情。比如在 git commit 之前判断是否单元测试通过。是否自动化根据 commit 信息生成 changeLog 等。

View File

@@ -0,0 +1,68 @@
# git常见使用
```
http://blog.csdn.net/wirelessqa/article/details/20153689
```
1. git init
2. git add .
3. git commit -am "\#\#\#"
4. git remote add origin git@xx.xx.xx.xx:repos/xxx/xxx/xxx.git
5. git push origin 本地分支:远程分支
fatal: refusing to merge unrelated histories
决办法git pull origin master --allow-unrelated-histories
### 创建新版本
* 从现有的分支创建新分支
* git checkout -b dev
* 将新创建的分支提交到远端
* git push origin dev
* 提交代码
* git add .
* git commit -m 'add a new branch named dev'
* git pull origin dev
* git push origin dev
## Githubu 不允许上传超过 100MB 文件
关键点:
- git-lfs 添加允许上传的文件名称或者文件类型
- 如果按照顺序1-2-3-4-5-6-10-11-12 还是会存在上传不成功的情况,所以需要严格按照下面的顺序执行
```Shell
//1
git rm --cached -r video/Company-Website-Pro.mov
//2
git commit --amend
//3
git push
//4
brew install git-lfs
//5
git lfs install
//6
git lfs track "*.mov"
//7
git add .gitattributes
//8
git commit -m '.gitattributes'
//9
git push origin master
//10
git add /Users/liubinpeng/Desktop/Github/Company-Website-Pro/video/Company-Website-Pro.mov
//11
git commit -m 'video'
//12
git push origin master
```
## 代码回滚到某个 tag
- 先查看所有的 tag: `git tag`
- 查看需要回滚的 tag 对应的 commitid: `git show {tag号}`
- 回滚: `git reset --hard {commitId}`

125
Chapter7 - Geek Talk/7.4.md Normal file
View File

@@ -0,0 +1,125 @@
# chrome开发者工具各种骚技巧
对于每个前端从业者来说除了F5键之外用的最多的另外一个键就是F12了。
今天看了一个网站才知道chrome还有各种骚姿势。
网站是:[umaar.com/dev-tips/](https://link.juejin.im/?target=https%3A%2F%2Fumaar.com%2Fdev-tips%2F)
所有的我都看了,这里随便列举几个个人之前不了解,觉得挺有用的。
### 1.曾经,在线调伪类样式困扰过你?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634df09634771d9?imageslim)
### 2.源代码快速定位到某一行ctrl + p
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e3570cd65624?imageslim)
### 3.联调接口失败时后台老哥总管你要response
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e35c4f2022e8?imageslim)
### 4.你还一层层展开domAlt + Click
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e386ca68401d?imageslim)
### 5.是不是报错了,你才去打断点?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e391d78c2ccf?imageslim)
### 6.你是不是经常想不起来,在哪绑定事件的?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634dfc23d6b8c65?imageslim)
### 7.你是不是打断点时还要去改代码?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e023e06569dd?imageslim)
### 8.看dom层级的最直观的方式
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e38c30aa44f4?imageslim)
### 9.查一些特定的请求,过滤器用过吗?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e396bfc4f2a8?imageslim)
### 10.在Elements面板调整dom结构很不方便
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e0c3fb6095d6?imageslim)
###
### 11.想知道某图片加载的代码在哪Initiator
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e1c2fa3c98f7?imageslim)
### 12.不想加载某个文件了?
![](https://user-gold-cdn.xitu.io/2018/5/11/1634e3a5cba66c92?imageslim)
多的就不列举了可以看看开头的网站。看了有几个功能我电脑win10是没有的也可能跟chrome版本有关。
开发者工具的功能确实挺多,多的有时根本用不上,官网教程建议每个前端人员都看看:
[developers.google.com/web/tools/c…](https://link.juejin.im/?target=https%3A%2F%2Fdevelopers.google.com%2Fweb%2Ftools%2Fchrome-devtools%2F)
中文版:
[www.css88.com/doc/chrome-…](https://link.juejin.im/?target=http%3A%2F%2Fwww.css88.com%2Fdoc%2Fchrome-devtools%2F)
本文完。

View File

@@ -0,0 +1,70 @@
# Git 实用操作
## 合并多次提交记录
有的时候我们对于某个功能为了实时保存自己写的代码可能会有多次提交所以等功能稳定下来我们可能会有这种需求将前面多余几次的提交记录合并为1个记录。幸运的是 Git 为我们提供了这样的命令。
有2种做法
- 合并部分
- git rebase -I HEAD~n。这里的 n 代表压缩最后n次提交。执行这条命令后会弹出 vim 编辑窗口,这 n 次提交记录会倒序,最上面的是最早的提交,最下面的是最新的提交。
```
pick cc77998 ...
pick 1821f6a ...
...
pick 124422 ...
```
我们需要修改第2到n行的 pick 为 squash这个的意思为将最后n-1次的提交合并为1次提交。然后我们保存退出git 会一个个压缩提交历史,如果有冲突则解决冲突就好。
- 完成之后我们将本地的修改提交到远端。 Git push -f
- 全部合并
```
git rebase -i --root
```
将全部的提交记录合并为1个
## 删除项目中所有的提交记录
之前个人在 Github 开源了一些完整的项目,但是有些人用于商业用途,所以有了这个需求,就是将项目改动一下,删除一些重要代码提交最新的代码到仓库并且让用户不能通过提交的历史记录会滚到指定的版本看到代码。
以下为步骤
```
1.Checkout
git checkout --orphan latest_branch
2. Add all the files
git add -A
3. Commit the changes
git commit -am "commit message"
4. Delete the branch
git branch -D master
5.Rename the current branch to master
git branch -m master
6.Finally, force update your repository
git push -f origin master
```
## 给项目打 tag
```shell
git tag -a 1.0.0 -m 'release SPM lib'
```

View File

@@ -0,0 +1,26 @@
# 短网址(short URL)系统的原理及其实现
> 如果不想重复的造轮子,想开箱即用,可以使用基于 PHP 的开源软件 YOURLS。YOURLS 还可以和 WordPress 整合到一起,功能强大,可扩展性高。
##什么是短链接 ?
就是把普通网址转换成比较短的网址。比如http://t.cn/RlB2PdD 这种,在微博这些限制字数的应用里。好处不言而喻。短、字符少、美观、便于发布、传播。
百度短网址 http://dwz.cn/
谷歌短网址服务 https://goo.gl/ (需科学上网)号称是最快的 ?
##原理解析
当我们在浏览器里输入 http://t.cn/RlB2PdD 时
* DNS首先解析获得 http://t.cn 的 IP 地址
* 当 DNS 获得 IP 地址以后比如74.125.225.72),会向这个地址发送 HTTP GET 请求,查询短码 RlB2PdD
* http://t.cn 服务器会通过短码 RlB2PdD 获取对应的长 URL
* 请求通过 HTTP 301 转到对应的长 URL https://m.helijia.com 。
这里有个小的知识点,为什么要用 301 跳转而不是 302 呐?
> 301 是永久重定向302 是临时重定向。短地址一经生成就不会变化,所以用 301 是符合 http 语义的。同时对服务器压力也会有一定减少。
但是如果使用了 301我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力但是我想是一个更好的选择。
来自知乎 iammutex 的答案

View File

@@ -0,0 +1,59 @@
# 浅谈iOS和Android后台实时消息推送的原理和区别
> 前言 iOS和Android上的实时消息推送差异很大往小了说是技术实现的差异往大了说是系统实现理念的不同。实时消息推送在移动端互联网时代很平常也很重要它的存在让智能终端真正成为全时信息传播的工具。本文将从原理上谈谈两个平台上实时消息推送的区别。
* 简要对比
* iOS 系统的推送APNS即 Apple Push Notification Service依托一个或几个系统常驻进程运作是全局的接管所有应用的消息推送所以可看作是独立于应用之外而且是设备和苹果服务器之间的通讯而非应用的提供商服务器。你的例子里面腾讯 QQ 的服务器Provider会给苹果公司对应的服务器APNs发出通知然后再中转传送到你的设备Devices之上。当你接收到通知打开应用才开始从腾讯服务器接收数据跟你之前看到通知里内容一样但却是经由两个不同的通道而来。
* Android就不同更像是传统桌面电脑系统做法。每个需要后台推送的应用有各自的单独后台进程才能和各自的服务器通讯交换数据。另外其实 Android 也有类似 APNS 的 GCMGoogle Cloud Message属于开发者可选非强制。
* 技术原理
* 首先讲解下服务器如何先找到设备、再找到app的问题。
* 每一个设备都有一个自己的设备号而设备中的app又都有一个唯一的包名。所以服务器只需要找到设备号与包名就可以定位到某个设备的某个应用而这设备号与包名会一起构成一个标识符叫做device\_token因此问题就简化为把device\_token与消息内容等信息交给服务器服务器把内容发到唯一的device\_token上。这就好像你在上海要通过顺丰寄送一个快件儿给某某小区的某某房间那么快件儿首先会邮递到顺丰公司在北京的总站点之后再根据小区的地址投递/路由到某某房间,这样一个寄件过程就算完成了。
* iOS 实时消息推送
iOS的推送是通过苹果自己的APNs服务进行的用户需要将device\_token以及消息内容等推送信息交给APNs服务器剩下的均由苹果自己来完成。iOS应用的推送大部分情况下都要依赖苹果生态提供的APNsApple Push Notification Service服务。
https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/db29e6a729147172d199cde6e2cf3682_hd.png
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/db29e6a729147172d199cde6e2cf3682_hd.png)
首先作为设备标识的device-token是由APNs颁发的App开发者或者第三方推送平台\(图中的Provider\)做的工作是收集这个device-tokenAPNs的推送是要求基于APNs颁发的device-token来推送的。只有正确的device-token会被APNs接受如果是一个错误的、或者无效的device-token\(比如App已经卸载了\)APNs就不会接受。
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/442e4085cf4b8f62c7ad359343c5f155_hd.png)
接着开发者使用第三方推送平台图中的Provider在将推送内容与范围选定之后进行推送第三方推送平台将信息提交给APNs剩下的操作全部都由APNs来进行完成整个过程第三方推送平台就不能控制了。但是如果提供的device\_token是失效的app被卸载、系统版本升级导致device\_token变化等情况那么推送过程就会被中断频繁的断线重连甚至会被APNs认为是一直DoS攻击。[详情可以参考为什么苹果的推送,两次推送之间间隔比较久的话,第二次推送会很慢?](http://www.baidu.com)
* Android 实时消息推送
Android平台在不使用GCM的情况下就需要将自己的服务器或是第三方推送服务提供商的服务器与设备建立一条长连接通过长连接进行推送。但是不建议自己设置服务器实现推送功能一是因为成本太高开发成本、维护成本自己搭建的服务器无论是稳定性还是速度上都比不了第三方推送服务提供商的效果。另一个是因为自己的数据量较小使用第三方推送服务提供商可以用他们的维度进行推送实现精准推送。友盟推送就是做的比较好的可以根据用户分群、地区、语言等多维度进行推送最大程度减少对于用户的干扰仅把消息推送给相关用户。![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/224420fhxsp8e00v0s0b0s.png)
* 开发者通过第三方推送服务提供商将信息直接下发给需要的设备第三方推送服务提供商与设备建立一条长连接通道并且将消息路由到APP中图中的设备1与设备2对于像设备3这种无网络连接或是没有成功建立长连接通道的设备会在设备3连网且推送消息没有过期的情况下自动收到由第三方推送服务提供商推送过来的消息保证消息不会丢失。
* ## 实现上的差异所带来的直观感受
* ### iOS的实时消息推送
iOS 在系统级别有一个推送服务程序使用 5223 端口。使用这个端口的协议源于 Jabber 后来发展为 XMPP ,被用于 Gtalk 等 IM 软件中。
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/224819kyaynn1zzoyoulzn.jpg.png)
所以 iOS 的推送可以不严谨的理解为:
* 苹果服务器朝手机后台挂的一个 IM 服务程序发送的消息。
* 然后,系统根据该 IM 消息识别告诉哪个 Apps 具体发生了什么事
* 然后,系统分别通知这些 Apps 。
带来的好处是不会出现杀后台这种脑残事。(不用大量 Apps / Apps 的服务为了推送挂后台)。也不会出现 Apps 被杀就收不到推送这种脑残事(早一点的新浪微博 Android 版仍然如此)。
* Android的实时消息推送
Apps 挂后台一直是 Android 引以为豪的特性(虽然我真的不知道是好处多还是坏处多。。),大家挂后台等待推送就成为技术选择。当然, Google 事后也提供类似苹果的推送方式了。倒也谈不上抄袭,毕竟苹果的整个技术实现也没有什么特别创新之处。
用户的电池? Apps 的开发者不会站在系统层面考虑的。他会假设其他 Apps 没有那么“不自觉”。而 Google 不强制的结果就是:没人真正为用户的电池负责。
但是, Google 的方案也并非全是悲剧:也因为整个技术方案非强制, Android 的 Apps 在接收到推送后的表现更为灵活。像 Line 的 Android 版本可以在推送通知的 Popup 上直接回复, iOS 就需要越狱才能做到了。

View File

@@ -0,0 +1,16 @@
# iOS 隔了较久时间推送变得缓慢
![](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/442e4085cf4b8f62c7ad359343c5f155_hd.png)
这个图是重点描述了真实消息推送的过程App开发者或者第三方推送平台的服务器\(图例中的Provider\)向APNs发起推送指令的请求**推送指令包含了要下发设备的device-token和要下发的内容payload两部分**由APNs根据device-token\(device-token是APNs生成颁发的\)将payload下发到设备上再由设备路由给具体的App。我们这里只关注第一步Provider到APNs的过程即Provider的服务器和APNs的服务器通信的过程。APNs要求Provider首先与APNs建立一条长连接Provider通过长连接可以将单个或者一批device-token发送给APNs这个过程中只要有一个device-token是不合法的\(错误或者失效\)那么APNs就会主动断掉Provider到APNs的长连接Provider探测到连接断掉之后需要重新建立连接跳过上次失败的device-token从下一个device-token接着发送。这个过程循环往复直至将本次要发送的所有的device-token都推送到APNs那么这次推送任务就算完成了。剩下的工作就是APNs将消息下发到具体设备了APNs将消息下发给设备这个过程不管是App开发者直接和APNs打交道、亦或是第三方推送服务器和APNs打交道我们都是无法控制的了所以推送的重点就是图例中的第一步Provider到APNs之间的通信了。
接下来我们回到问题就是为什么隔了很久之后再去做推送发送过程会变得非常慢。其实经过上面的解释大家就应该能把原因猜的差不多了就是因为长时间不发送的话会有很多设备上的device-token已经无效了比如设备卸载了App或者系统版本升级过导致device-token变化了或者是其它导致APNs认为device-token不合法的原因。总之时间长了不合法的device-token就会变多在上面的章节中也提到Provider和APNs的服务器建立长连接进行消息发送时如果碰到了不合法的device-tokenAPNs就会断掉长连接需要Provider重新建立连接。失效的device-token多了那么断掉连接-重新连接的次数就会增多,每次重新连接都需要耗费时间,甚至如果频繁的断掉-重连APNs有时候会被APNs认为是一种DoS攻击\(APNs官网这么解释但是具体判定的算法没有透露\)会导致短时间内APNs拒绝Provider的连接这种情况下不管是App开发者自己直接和APNs打交道还是第三方推送平台和APNs打交道碰到这种情况都是无能为力的。 只能被动的接受“断掉-重连”的工作方式,因此整个发送过程会特别缓慢。 所以总结下来长时间不发送消息再次发送的时候必然会出现推送缓慢的情况原因就是无效的device-token越来越多导致不断的“断开-重连”。所以在本文开头的时候就提到过如果App开发者亲自使用过APNs服务的话对这种现象必定是非常熟悉了也会见怪不怪了。 如果是两次发送任务之间隔得时间不是太长两次发送期间失效device-token不是那么多的时候速度还是比较快的。
那么既然失效的device-token是导致发送变慢的主要原因那么开发者朋友们肯定会想能不能提前判断出失效的device-token直接从发送列表中剔除掉这些失效的token。其实APNs是提供这样的feedback接口的调用这个接口会得到一批失效的device-token列表。那么是不是在一次发送之前去调用一下这个接口获取到无效的device-token在发送的过程中剔除掉这些无效的device-token就能加快发送速度呢 其实不然因为feedback接口是一个后验的接口即只有一次推送任务结束之后APNs才会把该次失效的device-token更新到feedback接口的返回结果里面。如果你在一次推送任务前调用feedback接口那么得到的失效device-token是基于上一次推送任务的结果的两次推送任务之间发生的失效的device-token是无法提前获取到的只能等当次推送任务结束之后才可以去获取新的失效token列表。
问题到这里就解释清楚了,那么碰到这种情况,我们该如何提升发送速度呢? 这里我们给大家讲讲友盟推送平台针对这种情况做的一些优化相比App开发者直接连接APNs做推送还是有一定的优势:\) 解决方法很简单就是友盟有很多台连接APNs的服务器每个服务器我们又会开很多个线程去和APNs做连接所以在并发度上会有较大的优势。所以针对一次发送任务使用友盟平台做推送速度肯定会比自己直接连接APNs有优势这个也是不少开发者放弃了直接和APNs打交道而是选择友盟推送来实现iOS推送的原因之一。

View File

@@ -0,0 +1,84 @@
# Charles 抓包原理
> HTTPS(Hyper Text Transfer Protocol Secure)是一种基于SSL/TLS的HTTP所有的HTTP数据都是在SSL/TLS协议封装之上进行传输的。HTTPS协议是在HTTP协议的基础上添加了SSL/TLS握手以及数据加密传输也属于应用层协议。所以研究HTTPS协议原理最终就是研究SSL/TLS协议。
### 运行过程
我们都知道HTTPS在保证数据安全传输上使用了加密算法但是具体是如何加密的或许许多人和我一样也是云里雾里。
实际上SSL/TLS协议的基本思路是非对称加密和对称加密结合来传输数据**一言以弊之HTTPS是通过一次非对称加密算法如RSA算法进行了协商密钥的生成与交换然后在后续通信过程中就使用协商密钥进行对称加密通信**,之所以要使用这两种加密方式的原因在于非对称加密计算量较大,如果一直使用非对称加密来传输数据的话,会影响效率。
![Charles 原理](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/Charles-method.png)
#### 1. HTTPS请求
这个步骤是整个通信过程中的第一步,首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,在这一步中,客户端主要向服务器提供以下信息:
- 支持的协议版本比如TLS 1.0版
- 一个客户端生成的随机数RandomC稍后用于生成**“协商密钥”**。
- 支持的加密方法比如RSA公钥加密。
- 支持的压缩方法。
#### 2. 服务器响应
服务器收到客户端请求后,向客户端发出回应,服务器的回应一般包含以下内容:
- 确认使用的加密通信协议版本比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数RandomS稍后用于生成*“协商密钥”**。
- 从客户端支持的加密方法中选择一个作为确认要使用的加密方法比如RSA公钥加密。
- 服务器证书。
这个服务器证书就是表明服务器身份的东西,其中也包含了非对称加密中需要使用的公钥。
#### 3. 证书校验、生成密码、公钥加密
客户端收到服务器回应以后,首先验证服务器返回的证书。如果证书不是可信机构颁发,或者证书中的域名与实际域名不一致,或者证书已经过期,以浏览器为例客户端会向网页访问者显示一个警告,由其选择是否还要继续通信。 如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后生成密码、公钥加密。
生成密码的过程会先产生一个随机数Pre-master key该随机数是整个握手阶段出现的第三个随机数稍后会经过公钥加密发送到服务端有了它以后客户端和服务器就同时有了三个随机数——RandomCRandomSPre-master key接着双方就用事先商定的加密方法各自生成本次会话所用的同一把“协商密钥”。
#### 4. 加密信息C-S
加密信息是指上面一步生成的内容,主要包括
- 一个随机数Pre-master key。用于给服务端生成“协商密钥”。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知表示客户端的握手阶段已经结束。这一项通常也是前面发送的所有内容的hash值用来供服务器校验。
#### 5. 私钥解密、解密握手消息、验证Hash
服务器收到客户端公钥加密的第三个随机数Pre-master key之后通过自身私钥解密该数值并由之前的RandomC和RandomS计算生成本次会话所用的“会话密钥”。然后通过约定的Hash算法验证客户端发送的数据完整性。
#### 6. 加密信息S-C
主要是指
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知表示服务器的握手阶段已经结束。这一项同时也是前面发生的所有内容的hash值用来供客户端校验。
#### 7. 解密握手消息、验证Hash
客户端解密并计算握手消息的HASH如果与服务端发来的HASH一致此时握手过程结束。
#### 8. 正常加密通信
握手成功之后,所有的通信数据将由之前协商密钥及约定好的算法进行加密解密。
# Charles抓HTTPS包原理
Charles本身是一个协议代理工具如果只是普通的HTTP请求因为数据本身没经过再次加密因此作为代理可以知道所有客户端发送到服务端的请求内容以及服务端返回给客户端的数据内容这也就是抓包工具能够将数据传输内容直接展现出来的原因。对于HTTPS请求468步骤的数据都已经经过了加密代理如果什么都不做的话是无法获取到其中的内容的。为了实现这个过程的数据获取Charles需要做的事情是对客户端伪装服务端对服务端伪装客户端具体
- 截获真实客户端的HTTPS请求伪装客户端向真实服务端发送HTTPS请求
- 接受真实服务器响应用Charles自己的证书伪装服务端向真实客户端发送数据内容

View File

@@ -0,0 +1,23 @@
# 第七部分
第七部分主要记录在开发中遇到的工具经验或者效率工具总结。
* [1、命令行文件查找](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.1.md)
* [2、Charles 从入门到精通](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.2.md)
* [3、git常见使用](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.3.md)
* [4、Chrome 正确调试姿势](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.4.md)
* [5、Git 实用操作](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.5.md)
* [6、短链接](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.6.md)
* [7、移动端推送杂谈-part one](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.7.md)
* [8、iOS 隔了较久时间推送变得缓慢](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.8.md)
* [9、抓包工具的原理](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.9.md)
* [10、Mac 成吨提升效率的技巧](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.10.md)
* [11、OKR](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.12.md)
* [12、面试技巧](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.13.md)
* [13、Markdown的妙用](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.14.md)
* [14、1995年的资深工程师和你谈谈如何进阶](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.15.md)
* [15、区块链技术和比特币](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.16.md)
* [16、如何写一份夺目的简历](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.17.md)
* [17、一套开发规范](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.18.md)
* [18、云服务器靠谱推荐](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.19.md)
* [19、规范化团队 git 提交信息](https://github.com/FantasticLBP/knowledge-kit/blob/master/Chapter7%20-%20Geek%20Talk/7.20.md)