Giter Club home page Giter Club logo

blog's Introduction

This project was bootstrapped with Create React App.

Available Scripts

In the project directory, you can run:

yarn start

Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.

The page will reload if you make edits.
You will also see any lint errors in the console.

yarn test

Launches the test runner in the interactive watch mode.
See the section about running tests for more information.

yarn build

Builds the app for production to the build folder.
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.
Your app is ready to be deployed!

See the section about deployment for more information.

yarn eject

Note: this is a one-way operation. Once you eject, you can’t go back!

If you aren’t satisfied with the build tool and configuration choices, you can eject at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except eject will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.

You don’t have to ever use eject. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.

Learn More

You can learn more in the Create React App documentation.

To learn React, check out the React documentation.

Code Splitting

This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting

Analyzing the Bundle Size

This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size

Making a Progressive Web App

This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app

Advanced Configuration

This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration

Deployment

This section has moved here: https://facebook.github.io/create-react-app/docs/deployment

yarn build fails to minify

This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify

blog's People

Contributors

joephon avatar

Stargazers

 avatar firstfu avatar  avatar

Watchers

James Cloos avatar  avatar  avatar

blog's Issues

How to deal with Certbot(letsencrypted)

OS

Ubuntu 16

Dependencies

  • software-properties-common
  • certbot
  • python-certbot-nginx

Step 1 Add Certbot PPA

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

Step 2 Install Certbot

sudo apt-get install certbot python-certbot-nginx

Step 3 get and install your certificates

sudo certbot --nginx

Step 4 Test automatic renewal

sudo certbot renew --dry-run

Reference

这篇文章价值一块钱

为什么要写交付文档

所谓交付文档,便是一份项目实际情况的陈述

甲方将项目托付给你,经过一顿狂敲猛撸之后,部署上线。但你觉得开发的过程十分精彩,就这样草草了事的话,不仅数月后自己会忘记了此间发生的种种,而且前来接手的人也难以读懂这个伟大的项目,最要命的是:甲方会隔三差五来找你讲故事。

于是你决定书写一份记录开发细节,部署细节,依赖细节的文档,交付回去。把项目比作女儿的话,交付文档就像一纸嫁妆清单,女儿过门,嫁妆入库,好~这门亲事算是了结了,嗯~这个项目算是告一段落了。

为什么需要交付文档

先说说~如果没有交付文档,这个世界将会怎样?

BAT 同时意识到:移动即时通讯,将会撕开一道很大很大的口子,于是~

百度决定做个叫百信的通信软件,然而第一版开发完毕后,研发团队忽然离奇失踪。人找不到了,却木有留下交付文档,李彦宏抓狂。

原来,是给阿里集体挖去了墙角,这波人被安排开发一款叫来往的通信软件,几个礼拜后~来往被部署上线,可就在此时,费劲九牛二虎之力的李彦宏终于把这班人给请了回去。走时~时间仓促,依然木有留下交付文档,于是,轮到马云先生抓狂。

但是呢,重回百度的那拨人发现~虽然是自己写的代码,但个把月过去了,该忘的不该忘的都忘得七七八八,加上近期又写了个来往,脑海里牛头和马嘴混淆在一起,十分混乱。

于是,在木有交接文档的情况下,凭着部分记忆加上对代码的不断 review,艰难地推着进度。

结果,马化腾的微信横空出世,并以惊人的成长、迭代速度艳压群芳~balabalabala

上面是我胡乱编造的故事,实际上微信才是第一个领跑的巨头。但同学们读到这里应该能明白~交付文档对于互联网产品而言,有多么重要了吧?

How to deploy gitlab with nginx and certbot via docker

Dependencies

  • docker

  • cerbot

  • nginx

OS

  • Ubuntu

Step 1 install docker

sudo apt-get install docker

Step 2 test docker

sudo docker -v
// => Docker version 18.09.2, build 6247962  | or your version

Step 3 pull gitlab image

sudo docker pull gitlab/gitlab-ce:latest

Step 4 run gitlab image

sudo docker run --name='gitlab' -d \
--publish 3443:443 --publish 3080:80 --publish 3022:22 \
--restart always \
--volume /srv/gitlab/config:/etc/gitlab \
--volume /srv/gitlab/logs:/var/log/gitlab \
--volume /srv/gitlab/data:/var/opt/gitlab \
--privileged=true \
gitlab/gitlab-ce:latest

Step 5 test gitlab

sudo docker ps
// =>  (health: starting) | or (healthy)

Step 6 install nginx

sudo apt-get install -y nginx

Step 7 install certbot

sudo apt-get install certbot  python-certbot-nginx

Step 8 config nginx

sudo vim /etc/nginx/sites-enabled/gitlab.conf

// /etc/nginx/sites-enabled/gitlab.conf

server {

  server_name example.com;

  location / {
    # try_files $uri $uri/ =404;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://localhost:3080;
    client_max_body_size    100m;
  }

}

Step 9 reload nginx

sudo nginx -s reload

Step 10 register https

sudo certbot --nginx
// =>  Congratulations! Your certificate and chain have been saved

Bingo!

go to visit your self-hosted gitlab server via whatever browser

这篇文价值一块钱

重装Mac系统后,简单配置开发环境

XCode

可以从 App Store 安装,如果不是IOS开发者,可以直接安装 Xcode command line tools

xcode-select --install

安装HomeBrew

安装

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

添加环境变量

$ echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile

验证

brew doctor

Iterm2,zsh

插件:zsh-autosuggestions

git clone git://github.com/zsh-users/zsh-autosuggestions $ZSH_CUSTOM/plugins/zsh-autosuggestions

插件:zsh-syntax-highlighting

git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

在 .zshrc 配置

plugins=(git colorize github jira vagrant virtualenv pip python brew osx zsh-syntax-highlighting zsh-autosuggestions)

命令行启动 vscode

command + shift + p

输入 > shell command

命令行启动 typora

将下面这行添加到 .bash_profile

alias t="open -a typora"

生成密钥对

ssh-keygen -t rsa -C "your email address"

git

brew install git
git --version
git config --global user.name "Your Name Here"
git config --global user.email "[email protected]"

CSS 入门

♦️ A CSS 的作用

CSSWeb 三大核心技术之一

JS 处理业务逻辑,HTML 撑起整体骨架,CSS 处理页面细节

栗子

html { height: 100% }

.class { color: red }

#id {
  height: 100%;
  color: yellow
}

html 是标签名,class 是类名, id 是 id

CSS 可以通过标签名、类名和 id 来找到对应的元素

元素名直接写,类名前面加个 ".",id 前面加个 "#"

小知识点

CSS 样式只有一行的时候,末尾的分号 ";" 可以省略,多行时不可省略。

♦️ 2 指定元素

CSS 可以为特定的元素订制样式

方法是直接指定标签名

栗子

html { height: 100% }

div { color: red }

input {
  height: 100%;
  color: yellow
}

htmldivinput 都是 HTML 的标签

小知识点

直接指定标签名定义样式的时候,整个 HTML 文档流里的所有此类标签都将拥有的样式

♦️ 3 指定类名

CSS 也可以为拥有同样类名的元素订制样式

方法是直接指定该类名

栗子

.class1 { height: 100% }

.class2 { color: red }

.class3 {
  height: 100%;
  color: yellow
}

class1class2class3 都是类名

小知识点

一个元素可以拥有多个类,当大于两个的时候,元素的样式将由这些类来共同决定

相同的属性会彼此覆盖,规则是后者覆盖前者

♦️ 4 指定 id

CSS 还可以为拥有特定 id 的元素订制样式

方法是直接指定该元素的 id

栗子

#id1 { height: 100% }

#id2 { color: red }

#id3 {
  height: 100%;
  color: yellow
}

id1id2id3 都是元素的 id

小知识点

一个元素可以拥有多个类,但只能有一个 id

♦️ 5 样式的属性

CSS 给元素定义样式的时候,你需要为其书写属性和属性特定的值

attribute : value

栗子

selector {
  attribute: value;
  ...
}

选择器 {
  属性: 属性值;
  ...
}

html {
  width: 100%;
  height: 100%;
}

前面两个是中英文 伪代码 ,最后一个才是真实例子

小知识点

CSS 的属性被一个分号隔开,左边是属性名,右边为属性的值

♦️ 6 宽和高

CSS 描述一个元素的大小,需要用两个属性

widthheight 即:宽和高

栗子

html {
  width: 100%;
  height: 100px
}

body {
  width: 100rem;
  height: 100em
}

widthheight 的值有 4 种类型

px百分比remem

小知识点

CSS 里横的那条是宽,竖的那条是高,记住咯

♦️ 7 颜色和背景颜色

CSS 给一个元素上色,有两个属性

colorbackground-color 即:颜色和背景颜色

栗子

div {
  color: red;
  background-color: #fff
}

p {
  color: rgb(0,0,0);
  background-color: rgba(255,255,255,0.8)
}

colorbackground-color 的值有 4 种类型

颜色名HEXRBGRGBA

小知识点

color 被用来定义文本的颜色

background-color 则被用来定义元素的背景颜色,或者说~填充颜色

♦️ 8 内边距和外边距

CSS 定义元素之间的距离,有两个属性

paddingmargin 即:内边距和外边距

栗子

div {
  padding: 100px;
  margin: 100px
}

p {
  padding: 100px 50px;
  margin: 100px 50px
}

h1 {
  padding: 100px 40px 50px 60px;
  margin: 100px 40px 50px 60px;
}

padding 定义了元素的内边距,margin 定义了元素的外边距,

只写一个数值的话,表示上下左右都一样。

写两个数值的话,第一个表示上下,第二个表示左右

四个都写的话,第一个表示上,第二个表示右,第三个表示下,第四个表示左

上右下左,记住咯

小知识点

paddingmargin 的属性值除了 px,也可以是 百分比remem

只要属性值是数值,一般都可以是这四种类型。

♦️ 9 边框

CSS 所有块级元素都有一层皮,这层皮叫边框。

border 即:边框

栗子

div { border: 1px solid red }

border 定义元素的边框

1px 定义了边框的厚度

solid 定义了边框的类型为实线

red 定义了边框的颜色为红色

小知识点

1pxsolidred 的顺序是可以任意调换了

♦️ 10 文本

CSS 为文本元素提供了丰富的控制属性

最常用的有 font-sizefont-weighttext-alignline-height

栗子

span {
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  line-height: 30px
}

font-size 定义文本的字体大小

font-weight 定义文本的粗细

text-align 定义文本的排列模式:居中、居右还是居左

line-height 定义文本的行高

小知识点

font-weight 的常用可选择有:boldnormal 和 100 - 900 的范围值

400 等同于 normal,700 等同于 bold

text-align 的常用可选择有: centerleftright

♦️ J 布局

HTML 拥有多种布局方式

可使用 CSSdisplay 属性来定义

栗子

div { display: block }

p { display: none }

a { display: inline }

.class { display: inline-block }

.class2 { display: box }

.class3 { display: flex }

block 表示块级布局方式

none 表示不显示

inline 表示内联布局方式

line-block 表示行内块布局方式

box 表示盒子布局方式

flex 表示弹性盒子布局方式

小知识点

想要更好地掌握 CSS 布局,很有必要深入了解什么是 盒子 模型

♦️ Q 定位

HTML 文档流存在着多种定位模式

可使用 CSSposition 属性来定义

栗子

div { position: static }

div {
  position: relative;
  left: 20px;
  top: 10px;
}

div {
  position: absolute;
  right: 20px;
  bottom: 10px;
}

div {
  position: fixed;
  left: 0;
  bottom: 0;
}

static 是默认文档流

relative 表示相对定位

absolute 表示绝对定位

fixed 表示固定定位

小知识点

position 的值如果不是 static 一般与之相随的还有:

topbottomleftright,分别对应上、下、左、右

通常情况下,上下左右只需要写两个就可以了。

♦️ K 注释

CSS 有两种注释风格

单行://,多行: /**/

栗子

// 我是单行注释
div {
  position: relative;
  // left: 20px;
  top: 10px;
}

/* 我是多行注释 *div {
  position: absolute;
  /*
    right: 20px;
    bottom: 10px;
  */
}

小知识点

被注释掉的代码,会被程序忽略,注释的作用是给程序员一点方便

对代码块进行标记或临时性屏蔽

这篇文章价值九元

HTML 入门

♦️ A 标签结构

HTML 标记语言是 XML 的一种拓展模式,所以它们有一些共同的特性

有开始就有结束,<></>

如果中间没有标签嵌套的话,也可以写成这样子 </>

HTML 标签由一对 尖括号 包裹起来的

栗子

<html>
</html>

小知识点

HTML 的标签名,是固定的,譬如 <html></html> 不能写成 <httl></httl>

后者是无效的。

有开始就有结束,记住咯~

♦️ 2 HTML 文档

HTML 文档有一个固定的结构,包含 5 对基本标签,一个格式声明

<!DOCTYPE>

<html />

<head />

<meta />

<title />

<body />

栗子

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>标题</title>
  </head>
  <body>
  </body>
</html>

小知识点

HTML 的文档结构,是固定的。

譬如:每一个 Web 页面都至少包含 栗子 里的 5 对标签 和一个格式声明。

♦️ 3 结构标签

HTML 标签都是成对地出现,且有各自的作用,下面来学习这些标签

<!DOCTYPE> 声明 HTML 文档的格式

<html /> 定义 HTML 文档流从这里开始

<head /> 定义 HTML 文档流的头部

<meta /> 定义 HTML 文档的资源

<title /> 定义 HTML 文档的标题

<body /> 定义 HTML 文档流的主体

栗子

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>标题</title>
  </head>
  <body>
  </body>
</html>

小知识点

HTML 的标签是相互嵌套的,嵌套在外面的叫爸爸,嵌套在里面的是儿子,爸爸外面是爷爷,儿子里面是孙子,依此类推。

为了让标签更有可读性,一般采用缩进风格来表示嵌套关系

即:缩进 2 个 空格

♦️ 4 标签的属性

每一个 HTML 标签都拥有自己的属性

属性 写在开始标签里面,也就是 <> 里面

栗子

<meta charset="utf-8" />

<div class="class"></div>

<p style="color: #000">我是一个段落</p>

上面 <meta /> 标签的标签名是 meta

charset="utf-8"<meta /> 标签的属性

charset 是属性名,"utf-8" 是属性值

<div /> <p> 同理

小知识点

由此可见,HTML 标签不但被一对尖括号包裹

还拥有标签名属性名属性值

♦️ 5 属性的作用

HTML 的标签都拥有属性,这是为了让标签更好地工作

不过,某些标签是可以不写任何属性的

譬如:<div /> <p>

但有些标签如果不写属性,将无法正常工作

譬如:<input /> <video />

栗子

<div>我是一个块级元素,如果不加属性,也可以正常显示</div>

<p>我是一个段落,也是块级元素,需要不需要属性,主要看程序猿</p>

<input value="我是input标签的值,某些时候我是必不可少的"/>

<video src="如果没有定义视频资源,我将无法工作">
  你能看到我,说明你的浏览器不兼容 video 标签
</video>

小知识点

HTML 的所有属性里,绝大多数都是 通用属性

即:每个标签都拥有的属性

譬如:styleclass

♦️ 6 注释风格

编程的世界里,但凡能称为语言的一般都会有注释

HTML 的注释风格遵循 XML 的风格

都被包裹在一对尖括号里 <>

以 "!" 开头,两条横杆紧随其后 "--"

栗子

<!-- -->

<!-- <div> Hello </div> -->

<!--
<input value="我是value的值"/>
-->

小知识点

注释在编程世界里是很常见也很有用的东西

注释会被浏览器或者编译器忽略

因而不会对代码产生任何效果,除了稍微增加了代码体积

但却给了程序员很大的方便

♦️ 7 p 标签

HTML 有许许多多的标签,一口气学完,可能够呛

大多数人都很难办到一下子掌握几百个标签,毕竟,罗马不是一天建成的

然而,千里之路,始于足下

接下来我们将一个一个积累,不积硅步无以至千里嘛~

栗子

<p>我是一个段落</p>

<p>我也是一个段落

<!-- 如果你想偷懒的话,p 标签的结束部分</p>是可以省略的 -->

<p>
  我也是一个段落哦
</p>

<!-- 段落一般都会比较长,为了结构为清晰,一般会缩进两个空格 -->

小知识点

标签有许许多多,即有共性,也有差异性

悄悄告诉你,p 标签属于块级元素哦

♦️ 8 h1 标签

<h1 /> 标签有一个系列,分别是 1,2,3,4,5,6

h 是 head 的缩写,表示头部,顾名思义 <h1 /> 标签一般被用来表示标题

h 后面的数字 1,2,3,4,5,6 表示标题的权重,或者说字号的大小。

所以数字越小,字号越大,权重越高。

栗子

<h1>我是最大的标题</h1>
<h2>我是老二</h2>
<h3>所以我只能是老三了</h3>
<h4>请叫我四爷</h4>
<h5>辣么我就是龙五了</h5>
<h6>倒数第一也是第一</h6>

小知识点

<h1 /> 系列的标签非常好掌握,学一个就懂 6 个

不过呢,h 系列可以说是 HTML 里有且仅有的了

所以后面的标签,还得扎扎实实一个一个积累

悄悄告诉你,h 标签和 p 标签一样,都是块级元素哟

♦️ 9 a 标签

<a /> 标签是一个强大的标签!

为什么呢?因为它让你可以在 Web 的世界里驰骋

这是怎么办到的?

a 标签俗称锚点,它有一个 "href" 的属性

给这个属性赋一个正确的值,a 标签就能拽你装逼带你飞

栗子

<a>我现在还不能带你飞,因为木有href属性</a>

<a href="https://baidu.com">点我,带你飞到李彦宏面前!</a>

<a href="https://qq.com" target="_blank">点我,带你去另外一个页面装逼</a>

小知识点

a 标签大有用途,除了上面的用法还有很多哟

不过现在来不及解释那么多了,童鞋们自己撸几个 a 标签体验下上面的区别哈

对了,a 标签和 p、h 标签不一样,它是内联标签哟

♦️ 10 span 标签

如果 HTML 的世界是一场撸啊撸的话,<span /> 标签便是一枚强大辅助

它通常和 p 标签一起出现

在处理文本的时候,p 标签是 ADC,span 标签呢,乃一枚给力辅助

栗子

<p>
  我系ADC啊
  <span class="niuB">我系辅助啊</span> 
</p>

小知识点

span 标签运用得最多的地方,是局部文字高亮

除此之外,通常还被用来做文字图标 font icon

对了,span 标签和 a 标签一样,它是内联标签哟

♦️ J style 标签

HTML 里,有一类标签是是专门用来引入资源的,其中 style 标签算一个

除此之外 style 标签和寻常标签没啥两样

都是有开始,有结束,被包裹在 </> 一对尖括号之间

栗子

<style>
  .niuB { color: red }
</style>

嵌套在 style 标签里面的东东,叫做 CSS 这里知道就好,不深究。

<!DOCTYPE html>
<html>
  <head>
    <style>
      .niuB { color: red }
    </style>
    ...
  </head>
  <body>
    ...
  </body>
</html>

小知识点

style 标签是一种资源标签,用来引入 CSS 样式

一般嵌套在 head 标签之间,为啥呢?

因为样式要优先加载,不然用户就会看到一坨木有样式的简陋页面

作为资源标签,style 即不是内联也不是块级哟

♦️ Q script 标签

HTML 里,还有一个资源标签叫 script

script 的意思是:脚本,顾名思义 script 标签引入的定然是脚本语言了

没错,你猜对了,被嵌套在 <script /> 标签里的正是 JS

栗子

<script>
  var a = "niuB!"
</script>

<script src="https://newteo.com/static/js/demo.js"/>

嵌套在 script 标签里面的东东,叫做 JavaScript 也就是 JS。 一句带过,不深究。

<!DOCTYPE html>
<html>
  <head>
    <script src="https://newteo.com/static/js/demo.js"/>
    ...
  </head>
  <body>
    <script>
      var a = "niuB!"
    </script>
    ...
    <script src="https://newteo.com/static/js/demo2.js"/>
  </body>
</html>

小知识点

script 标签是一种资源标签,用来引入 JS 代码

可以被嵌套在 head 和 body 之间

有两种书写方式,注意到了吗?自闭合、带 src 属性的模式,和开标签、闭标签模式

作为资源标签,script 和 style 一样,即不是内联也不是块级哟

♦️ K 综合练习

学习到这里,童鞋们总共掌握了 16 个标签、一条声明、一个注释

惊不惊喜,意不意外?

为了方便童鞋巩固知识点,可以简单归纳为几句话

5 根钢筋水泥
2 处资源入口
9 枚文本常客
1 条声明
1 个注释

栗子

<!-- 5 根钢筋水泥 -->
<html /> <head /> <title /> <meta /> <body />

<!-- 2 处资源入口 -->
<style /> <script />

<!-- 9 枚文本常客 -->
<h1-6 /> <p /> <span /> <a /> 

<!-- 1 条声明 -->
<!DOCTYPE html>

<!-- 1 个注释 -->

小知识点

掌握这些标签,你就可以编写最基本的网页啦~

这篇文章价值九元

How to run your NodeJS app via docker

Dependencies

  • Docker

Step 1 write your NodeJS code

mkdir node && cd node && vim app.js
// node/app.js

const app = require('http')
const PORT = 3000

app.createServer((req, res) => {
  res.end('Hello World!')
})

app.listen(PORT, () => console.log(`Server is running  on port: ${PORT}`))

Step 2 write your Dockerfile

vim Dockerfile
// node/Dockerfile

FROM node:latest
COPY . /app
WORKDIRE /app
EXPOSE 3000
CMD node ./app.js

Step 3 build your docker file

docker build . 

Step 4 run your app

docker run -p 3000:3000 -d [your docker image id]

Bingo~

curl -get localhost:3000
// => Hello World!

这篇文章价值一块钱

How to set up a git self-hosted server with gitea and nginx via docker

Dependencies

  • gitea
  • nginx-
  • docker
  • docker-compose

OS

Ubuntu 16

Step 1 install docker && docker-compose

sudo apt-get install docker docker-compose

Step 2 create your project

mkdir gitea && cd gitea
vim docker-compose.yaml

write sth in your docker-compose file

version: "2"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:latest
    environment:
      - DB_TYPE=mysql
      - DB_HOST=db:3306
      - DB_NAME=gitea
      - DB_USER=gitea
      - DB_PASSWD=gitea
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

  db:
    image: mysql:5.7.27
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=gitea
      - MYSQL_USER=gitea
      - MYSQL_PASSWORD=gitea
      - MYSQL_DATABASE=gitea
    networks:
      - gitea
    volumes:
      - ./mysql:/var/lib/mysql

set up your gitea server via docker

docker-compose up -D

Step 3 set up a nginx server

sudo apt-get install -y nginx

Step 2 bing your domain with nginx

sudo vim /etc/nginx/site-enable/gitea

The nginx config file might look like as below

server {
  listen 80;
  server_name your.domain.com;  
  location / {
     proxy_pass      http://localhost:[your port]/;   
     proxy_set_header Host   $host;           
     proxy_set_header X-Real-IP;      
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}
sudo nginx -s reload

Bingo~

Open a browser and try to visit your gitea web site

这篇文章价值两元

浅谈小程序对于创业人,意味着什么

尽管这个话题,有点儿烂大街,然而作为开发者兼创业人,兹以为很有必要为自己梳理一番。

多年前,当萌生创业的念头时,我是这样在脑海里绘制这幅蓝图的:

我需要一个域名,一个服务器,并且备了案。

我需要至少一个前端,至少一个后端,至少一枚设计师,由他们来完成开发。

我需要一个产品,一个营运,一个策划,一个市场,这样我们开发出来的产品才能让世界知道。

如果可以的话,再来一个文案,一个运维。

最后,我得去注册一家公司,这样,便可名正言顺地运作这一切。

想了很多很多,最后放弃了创业的念头,转而去做了一枚程序员。

为什么呢?

我只是一个普普通通,简简单单的苍头,不会技术,不懂产品,不善管理,完全没有市场触觉。对于当时的我而言,这是一个新的行业,新的领域。

而且那阵子,我得了异常严重的‘近视’,因为打开荷包,根本看不到钱。是的,那会儿,我失业很久了。

现在来看看我列出的基本清单:

前端 * 1
后端 * 1
设计师 * 1
产品 * 1
营运 * 1
策划 * 1
市场 * 1
文案 * 1
运维 * 1
我 * 1

十个手指头,刚好数得过来。

假设能用三四线城市的酬薪,聘来中等level的人才。那么按5k计,一个月,我将不得不在人力成本上支出5万,一年那就是60万。再加上场地,设备,各种费用,没有100万,也得80万吧。不不不,这种起点,不是我这种人能够承担的。

在这个BAT横行的年头(那会儿正群魔乱舞,大环境并未出现‘合并’和‘圈养’的势头,电商领域,才刚刚步入’战国时代‘),我不敢确定我想做的,他们是不是也打算做;我不确定,会不会变成互联网的炮灰。

于是在即没底气又没才气更没财力的情况下,重写了这份清单:

全栈 * 1

哈,这样一来,就很清爽了。

几年后的某一天,在一无所有,一无所知的境遇下,成为一枚‘野路子’程序员,并在接下来的一个月里,开始了远程工作。

那是一段破釜沉舟的岁月,由一个执念引发的人生‘灾难’,亲朋好友都说不可,我却坚决踏上一条必须不断跨越悬崖才能苟且的路。

当我知道微信公众平台的时候,已经错过了微信公众平台的红利期,当我意识到全栈并不能解决一切的时候,已经错过了产出‘孤胆英雄’的时代,总之,后知后觉,不断慢半拍。

2016年9月21号晚,手机微信忽然弹出一个对话框:『微信邀请你内侧』

我想都没想直接取消,嘀咕着~什么鬼,又升级,我不升级。

几天后满大街都讨论着微信小程序,内测,200名额,邀请制。肠子悔青了。

2016年11月3日,小程序公测。

这意味着什么?意味着终于能够在恰当的时机,做正确的事。

小程序类似于公众号,前者是微信app自身,后者基于HTML5实现。所以小程序更像是微信内置的各种服务,比如交水电费。

对比小程序的文档和微信公众号的文档,可以看出,前者写的非常负责任,清晰,简洁,不忘细节。

小程序用类似于Vue.js的开发风格,底层为类似于React Native的实现,有点集当下前端大成者的意味。

对于创业者而言,小程序非常适合作为demo来快速迭代。

想象一下,小程序 VS App

这组PK对象,小程序性能还是可以比肩原生App的,但受限太多。

尽管如此,小程序比之App依然有着天生的优越性,况且这段时间,一群弄潮儿已经移植了大量APP(见末位示例源码)。

  • 暴露在6亿微信用户面前

  • 无需安装

  • 文档清晰、简洁,API设计优良。

  • 与生俱来部分微信APP的能力。

  • 中等程度的前端就能胜任

  • 开发迅捷,代码结构清爽

综上所述,小程序可以打上:灵活、便民、用户、高效、低耗的标签。

当然了,这种种好处,都是相对于中小玩家而言,对于实力雄厚的巨头们来说,呵呵就可以了。

不管小程序被高估了,还是天生丽质,当公测结束的那一刻到来时,它就会是一种不可忽视的存在。承不承认,它都是一阵东风。

现在,再次罗列我的创业清单:

公众号 * n   // n <= 50
小程序 * n  // n <= 20

看起来依然清爽

最后来声明一个创业类

class 创业 {
  constructor(资源, 切入 ) {
    this.资源 = 资源
    this.切入 = 切入
    this.成功率 = undefined
  }
 
  开搞() {
    const 条件1 = this.资源 < 1000000   // 一百万
       ,  条件2 = this.切入 === '小程序' 
    if (条件1) {
      if (条件2)
        this.成功率 = Math.random() * (1 - 0.5) + 0.5   // 50%概率加成
      else 
        this.成功率 = Math.random()  
     }
    else 
        this.成功率 = '不在探讨范围'
    return this.成功率
  }
}

const 小本创业小程序 = new 创业(100000, '小程序')
const 小本创业APP = new 创业(100000, 'APP')


拷贝源码黏贴到chrome console里,再分别拷贝下面代码看看概率如何

小本创业APP.开搞()   // => 成功率
小本创业小程序.开搞()   // => 成功率

小程序开源代码示例&&相关文献(摘自justjavac的开源项目

目录

置顶

官方文档

↑ 返回目录 ↑

工具

  • WePY ★18k+ - 支持组件化的小程序开发框架
  • mpvue ★17k+ - 基于 Vue.js 的小程序开发框架,从底层支持 Vue.js 语法和构建工具体系
  • Taro ★19k+ - 使用 React 的方式开发小程序的框架,同时支持生成多端应用
  • uni-app ★13k+ - 使用 Vue 语法开发小程序、H5、App的统一框架
  • chameleon ★5k+ - 一套代码运行多端,一端所见即多端所见
  • megalo ★1.3k - 基于 Vue 的小程序开发框架
  • MPX ★1k+ - 增强型小程序框架,深度性能优化,支持跨小程序平台开发,完全兼容原生小程序组件
  • Labrador ★1.6k - 支持 ES6/7 的微信小程序组件化开发框架
  • wept ★2.1k - 微信小程序实时运行环境
  • wafer ★2k - 快速构建具备弹性能力的微信小程序
  • licia ★1.1k - 支持小程序的 JS 工具库
  • Remax ★1k+ - 使用真正的 React 构建小程序
  • wechat_web_devtools ★600+ - Linux 下微信开发者工具
  • minapp ★400+ - TypeScript 版小程序开发框架(兼容原生小程序代码)
  • tina ★300+ - 轻巧的渐进式微信小程序框架
  • Okam ★200+ - 使用类 Vue 方式开发小程序的渐进增强框架,支持生成微信/百度等主流平台的小程序
  • xpmjs ★100+ - 微信小程序云端增强 SDK
  • WeApp-Workflow ★100+ - 基于 Gulp 的微信小程序前端开发工作流
  • gulp-wxa-copy-npm - 微信小程序 gulp 插件,解决 npm 包管理和 babel-runtime
  • weact - 用 JSX 快速开发小程序
  • socket.io-mp-client - 微信小程序 socket.io 客户端
  • wxa - 方便的小程序开发框架
  • px2rpx - Px 转 Rpx 在线工具
  • wxml-parser - JavaScript WXML parser
  • weappx - 基于 redux 的数据层管理框架
  • weapp-start - 基于插件机制的开发脚手架,改善原生小程序开发体验
  • Egret Wing - 支持微信小程序实时预览的 IDE
  • wxapp-graphql - 小程序 GraphQL 客户端
  • gulp-wxapp-boilerplate - 小程序+小程序云 Gulp 开发脚手架,支持云函数 mock
  • wenaox - 小程序数据层管理 ,轻量性能好,支持中间件
  • authing-wxapp-sdk - 身份认证 for 微信小程序
  • weapp-eslint-boilerplate - 微信小程序 Eslint 通用模板文件,节省自己配置的时间
  • Anka - 渐进式小程序开发工具集,提供通用的开发函数库及组件
  • WeAppBunXin - 微信小程序开发之影分身术,一套代码生成多个小程序
  • miniprogram-build - 小程序命令行编译工具(支持typescript,原生npm,资源文件压缩...)
  • wcc.js - wcc.js 是wxml文件和wxs文件编译器的nodejs实现
  • wcsc.js - wcsc.js 是wxss文件编译器的nodejs实现
  • weapp-gulp - Gulp高效构建微信小程序,让开发变得更简单

↑ 返回目录 ↑

插件

↑ 返回目录 ↑

组件

↑ 返回目录 ↑

Demo

How to config email for gitlab setting with alimail

Dependencies

  • gitlab

  • docker

Step 1 edit gitlab.rb file

sudo vim /srv/gitlab/config/gitlab.rb    #denpens on your config path
### your/config/path/gitlab.rb

### Email Settings
gitlab_rails['gitlab_email_enabled'] = true
gitlab_rails['gitlab_email_from'] = '[email protected]'   # should be as well as gitlab_rails['smtp_user_name']
gitlab_rails['gitlab_email_display_name'] = 'newTeo'
gitlab_rails['gitlab_email_reply_to'] = '[email protected]'

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.mxhichina.com"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "[email protected]"
gitlab_rails['smtp_password'] = "[your ali mail password]"
gitlab_rails['smtp_domain'] = "smtp.mxhichina.com"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'none'

Step 2 save gitlab.rb file and run reconfigure

sudo docker exec gitlab gitlab-ctl reconfigure

Step 3 get in docker image and run some command to test whether email feature is ok or not

sudo docker exec -it gitlab bash   // get in docker image

gitlab-rails console production   // get int rails console

Notify.test_email('[email protected]', 'Message title', 'Message body').deliver_now   // send test mail

Bingo~

go to check out your mail inbox

这篇文章价值一块钱

How to enable decorators for create-react-app

Dependencies

  • @babel/plugin-proposal-decorators
  • customize-cra
  • react-app-rewired

Step 1

yarn add -D @babel/plugin-proposal-decorators customize-cra  react-app-rewired 

Step 2

create a file called config-overrides.js in your root dir

// config-overrides.js

const { override, addDecoratorsLegacy } = require("customize-cra");

module.exports = override(
    // enable legacy decorators babel plugin
    addDecoratorsLegacy()
)

Step 3

rewrite package.json file as well as below

// package.json

{
  ...
  "scripts": {
    - "start": "react-scripts start",
    - "build": "react-scripts build",
    - "test": "react-scripts test",
    + "start": "react-app-rewired start",    
    + "build": "react-app-rewired build",   
    + "test": "react-app-rewired test",     
    ...
  },
  ...
}

Bingo~

yarn start
function bingo() {}

@bingo
class Bingo {}

这篇文章价值一块钱

嗯哼

记一次树莓派烧录 ubuntu 系统

准备工作

  • 树莓派 4B/1G/2G/4G
  • TF 卡 8G 以上
  • TF 读卡器
  • Ubuntu for 树莓派
  • Mac OS

步骤

插入 TF 卡并格式化

diskutil list

找到 TF 卡挂载点

diskutil eraseDisk FAT32 PI_Volume  MBRFormat /dev/disk3

卸载 TF 卡

diskutil unmountDisk /dev/disk3

烧录系统

dd if=/path/to/your/img of=/path/to/your/tfcard bs=32m

如果mac上烧录缓慢,试下 把/dev/disk{n} 换成 /dev/rdisk{n}

弹出 TF 卡 插入树莓派

树莓派插入网线、键盘、显示器然后开机

Bingo~ Done!

默认账号和密码都是ubuntu 初次登录系统会要求初始化

设置时区

sudo cp /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime

更换阿里云源

sudo sed -i 's/ports.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

更新系统 & 安装net-tools

sudo apt update
sudo apt install net-tools -y
sudo apt install bluetooth -y

启动蓝牙

sudo hciattach /dev/ttyAMA0 any
sudo bluetoothctl
power on
discoverable on
scan on

搜索蓝牙&配对

show
devices
connect {id}

配置wifi

sudo apt install wireless-tools -y
sudo apt install iw -y
sudo ip link set wlan0 up

上面只是工具 可选

sudo vim /etc/netplan/50-cloud-init.yaml


network:
    ethernets:
        eth0:
            dhcp4: false
            addresses: [10.200.12.222/24]
            gateway4: 10.200.12.254
            nameservers:
                    addresses: [10.200.10.1,10.200.10.2]
           # option:true
    wifis:
            wlan0:
                    dhcp4: true
                    access-points:
                            "ssid":
                                    password: "password"
    version: 2

测试

sudo netplan --debug apply

done!

继续外包吗?

众包平台

且不说国外,咱国内就很多。

码市

英选

实现网

程序员客栈

大鲲

猪八戒

智城

......

实在太多,各有定位,各有侧重。

之所以这么多,只有一个原因:存在市场需求。

这是个双向需求,一方面开发者有接包意愿,另一方面企业、团队有丢包想法。

于是乎,众包平台如雨后春笋,充当承上启下的中间环节。

于是乎,资本市场融融融,投投投,这是一块正在变大的蛋糕。

远程工作

外包,老早就有。近几年,从线下发展到线上,离不开 远程工作这一模式在国内的逐步普及。

在欧美发达国家,10个人里面有3个人在远程工作,他们生活、工作两不误,早上在地里干活,下午在房间里做事,晚上陪家人happy。

或者任意颠倒顺序,或者一整天不做事,或者一整天在做事,总之,他们自由而高效,洒脱且任性。

何等令人向往的生活。

如果厌烦了朝九晚五,有两个极端可以靠拢:去创业,或者远程工作。

没有第三个选择了。

外包长久吗?

要说外包,邓哥 算鼻祖,承包制开天辟地激发了劳动力。

然而演变到各个领域的外包,尤其在IT,却是名声不大好。

尽管如此,外包不会被消灭,包工头、包租婆还会继续生存很长时间,但是IT领域的外包,显然无法满足当前的市场需求。

外包不一定劣质,但要找到优质的却是不易。

外包也未必就不可靠,但要找到靠谱的有点难。

外包市场是混乱的,众包平台并不能带来秩序,他们看到了市场,却没有从根源上解决问题。

所以众包平台注定是要做陪嫁的。

有些平台打着共享经济的旗号,说本平台有海量BAT人士提供高端的优质的空闲流量包可供使用。

这噱头听起来不错,但我还是觉得很奇怪。

把BAT所有的DEV、PM、DESIGN通通加起来,也才多少人?

这个数量级比之当下遍地开花的广大中小企业、新创团队的基数,还不到一个零头,就算是种马也只能望洋兴叹。

市场不会接受 欲求不满

所以天朝的开发者、设计师、产品|项目经理群体基数之增长势头必然要比房价还迅猛。

BAT噱头此去十万八千里。

什么是根源?

得从克强哥 互联网+说起。

这是个热词,家喻户晓。

但未必人人了然于胸。

马化腾说互联网+,马云也说互联网+。

腾讯出了小程序,阿里说明年也出小程序

马云有阿里云,马化腾有腾讯云,但是加来加去,云来云去,传统企业木有RD资源,这些都是浮云。

小程序也好,云端解决方案也罢,传统企业没有RD,再优秀的东西也+不起来。

阿里腾讯提供了能带来万家灯火的工具,却没有挨个儿递给千家万户。

只能是那些看得出苗头的企业自己来拿,让RD去用。

实现互联网+的根本在RD,得有自己的RD。

RD还是外包?

RD很昂贵,风险也不小。

外包比之,两方面都很有吸引力。

所以才会有外包名声差,但往往是首选的无奈之举。

这是个要命的惯性思维。

以为丢个包,花个1W~20W,一个月把东西做出来,就没有必要花100W养一个RD小team一年去把这个东西做全面。

为什么呢?吃过亏的朋友冷暖自知,不再赘述。

总之互联网的载体是程序,程序是程序员写的。

不养RD,花小钱买个应用程序,是办不到互联网+的。

养不起RD?

这就是众包平台这种外包形式目前还可以继续存在的一个主要理由。

然而,存在即合理吗?

那得看有木有更合理的模式出现?

继续外包吗?

2017年,有一种服务,本质是RD,却没外包那么丑,你养得起,只是有时效。

使命

下个话题,接着聊。

TO BE CONTINUED

我眼中的小程序

对比

小程序是个新物种,体验上稍逊App,小胜Web。

开发成本:App > Web > 小程序

使用成本: 得看 UI/UE/业务逻辑的设计

营运成本:尺度上是一样的

首次进入

App:

  1. 记住关键字
  2. 打开 App Store
  3. 搜索 App
  4. 下载 App
  5. 安装 App
  6. 打开 App

Web:

  1. 记住网址
  2. 打开浏览器
  3. 输入网址

小程序:

  1. 记住关键字
  2. 打开微信
  3. 搜索小程序
  4. 打开小程序

分享进入

App:

  1. 进入下载页面
  2. 点击下载
  3. 安装
  4. 打开

Web:

  1. 直接进入

小程序:

  1. 直接进入

二次进入

App:

  1. 打开 App

Web:

  1. 记住网址
  2. 打开浏览器
  3. 输入网址

小程序

  1. 打开微信
  2. 打开小程序

所谓限制,所谓入口

相信酒香不怕巷子深,一款实实在在解决了刚需的应用,假若是个App,我不会吝惜那几十兆的空间,短暂的等待;假若是个web,我会不厌其烦地记住网址,从浏览器进入;假若是个小程序,我也不在乎多进了几层微信目录。

我在乎的是它好不好用,二次进入时好不好找,分享时有没有障碍。

假若一款应用实实在在地解决了刚需,正常情况下我应该很快就都能从上述渠道进入。

所谓红利

小程序不能直接涨粉,但可以间接让公众号涨粉。

如何间接涨粉,得看业务逻辑。

粉如何变现,那得看适用场景。

所谓基因

好的基因从来取决于好的商业模式,不取决于单一实现形式。放眼望去,成功的产品基本都有多种实现形式。

永远的唯快不破

先入为主,而后高速迭代,而后孜孜不倦且与时俱进,然后保持领跑,牢牢守住壁垒。

快速论证想法的可行性,确认刚需还是伪需,才是新创团队压缩试错成本,延长生命周期的正确指导**

我眼中的小程序

App 级的体验、比 Web 还迅捷的开发速度、一定的传播能力、看起来巨大,实际上也不小的微信入口、微信无感登录。

显然,小程序是符合精益创业,最适合拿来设计冲刺的新物种。

一家之言

纯属个人看法,不喜勿拍 :)

How to fix the problem when local kubernetes-helm version dosent match server side's

Situation

If you are trying to install some chart and some error show up like below

Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.13.1", GitCommit:"618447cbf203d147601b4b9bd7f8c37a5d39fbb4", GitTreeState:"clean"}

That means your local helm version is different with server side's

Then you will need this post

Step 1 unlink current version

brew unlink kubernetes-helm

Step 2 pick up the target version's commit hash on github

visit this link and try to find out your target version such as :2.13.1 etc etc

And then paste the target hash instead of this link's hash part

brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/[your target hash]/Formula/kubernetes-helm.rb

Step 3 swith version

brew switch kubernetes-helm [your target version]

Or you can do it in that way

Download your desired version

kubernetes-cli version issue

If you still get stuck in some error like below, then you might need that solution below

error: SchemaError(io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1beta1.CustomResourceSubresources): invalid object doesn't have additional properties

Step 4 check out your kubectl version

kubectl version

Something might look like this

Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.11", GitCommit:"637c7e288581ee40ab4ca210618a89a555b6e7e9", GitTreeState:"clean", BuildDate:"2018-11-26T14:38:32Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}

Step 5 fix problem

rm /usr/local/bin/kubectl
brew link --overwrite kubernetes-cli

Optional sh

brew link --overwrite --dry-run kubernetes-cli

Bingo!

How to set up a VPN in Ubuntu

Step 1

Install shadowsocks

sudo apt install shadowsocks

Step 2

Edit the config file

column description
server server side address
server_port server side port
local_address local address
local_port local port
password your password
timeout senconds
method crypto
fast_open TCP-Fast-Open

for an example

{
  "server": "0.0.0.0",
  "server_port": 8623,
  "local_address": "127.0.0.1",
  "local_port": 1080,
  "password": "your password",
  "timeout": 300,
  "method": "aes-256-cfb",
  "fast_open": false
}
sudo vim /etc/shadowsocks/config.json

For multi users might look like this

{
    "server":"0.0.0.0",
    "port_password": {
        "8388": "user1 password",
        "8888": "user2 password"
    },
    "local_address": "127.0.0.1",
    "local_port":1080,
    "timeout":300,
    "method":"aes-256-cfb",
    "fast_open": false,
    "workers": 1,
    "prefer_ipv6": false
}

Step 3

Start ssserver

sudo ssserver -d start -c /etc/shadowsocks/config.json

Step 4

Set up once boot

sudo vi /etc/rc.local

+ sudo ssserver -d start -c /etc/shadowsocks/config.json

Bingo~

什么是需求

所谓需求,便是你的产品需求,或者说:项目需求

在产品需求之前,还有一个市场需求,不过这个话题不在探讨范围。

我们从产品需求出发,展开一段追问式自问自答。

为什么要做这款产品?

当开始一个项目的时候,首先得明白:为什么要做它,可不可以不做,做的话,解决了什么问题?

这,很恼人。

有些时候,你只知道自己想做,但不曾深究过为何要做,于是在一顿忙活之后最终发现:其实自己并不是真的想做。

有些时候,你不得不做,因为这是甲方委托的项目。于是,你分析完了功能,也找来了参照,按部就班完成了项目之后,发现:说好的长期合作,结果成了一锤子买卖。其实发生这种情况,不一定就是你事情没做好,反而很有可能,是甲方没有想好。

有些时候,你根本不需要知道自己为何要做,你就是想做,因为你能~或者你希望你能。于是雷厉风行地开撸了,不管结果怎么样,它都成为你的某一个 Demo。这种更像是在刷经验,打怪升级,属于心里需求,或者职业需要。

讲真,除了第三种,关于需求,你必须投入时间和精力来思考。因为需求的真伪影响着产品的定位,进而决定产品后续将会拔地而起,还是注定烂尾。

为什么不做这款产品?

在思考为什么做这款产品之前,先思考为什么不做这款产品。

这听起来很怪,却十分有用。

人都会有脑门一热的时候,尤其是有产品思维的程序员。一旦心中敲定了某个 Idea,整个世界都无法阻止他动手实现。这种人,叫:『产品猿』

然而,当热情褪去,重归冷静,理性取代感性成为主导时,『产品猿』会忽然发现,自己辛辛苦苦做了一坨 shit!

So,当存在一个理由足够驱动你去做一件事的时候,再找找有没有另外一个足够强悍的对立面来说服你打消这个念头。

以前,我常把一句话挂在嘴边:即便有一万个理由告诉你不要,只要存在一个你可以要的理由,就可以去做。

后来,我做了一点修正:要做一件事,找到一个非做不可的理由,再找一个一定不可做的理由,然后把决定权丢给直觉。

为什么讲了这么多,不见剖析需求?

童鞋们以后或许会经手各种各样的需求,不得不对其进行这样和那样的拆解,这是必然。

然而在这,在我的公开课里,我只说明一件事:比拆解需求更重要的是捕获需求的嗅觉和拍板解决需求的魄力和速度,这个咧,都离不开直觉。

需求,一句话可以讲完:达成你需要的效果、功能

栗子

做一个服装电商,我可以卖衣服,顾客可以买衣服。

我可以在后台发布,修改,上架和下架。

顾客可以通过微信支付来购买。

顾客可以选择尺码,颜色,数量。

顾客购买完后要能看到发货进程。

顾客收到货后可以评价。

......

越细化,需求就拆解得越明确。

这些没啥好说的,童鞋们顺藤摸瓜,多思考多借鉴就可以了~

关于需求,最后我想说

什么成功学、什么谋定而后动、什么经验主义,Bull Shit!

这个互联网,不存在任意一款产品,可以像验证 BUG 那样反复重现的。

但是,人可以。

所以,我鼓励你培养自己的直觉。

乔布斯从来不向世人解释为什么他就一定知道 iPhone 3 必然会火

那些剖析 iPhone 为什么会火的文章和报道到是挺多,他们做出 iPhone 了吗?

Well

用言简意赅的一句话阐明

需求是什么?

JS 入门

♦️ A 变量

变量是有名字的容器,容器用于存储数据,通过容器名字获取容器内的数据

JS 定义变量,需要一个关键字、一个操作符、一个变量名和要存储的数据

关键字

var let const

操作符

=

栗子

var a = 20
let b = "20"
const c = [20, "20"]	

小知识点

letconst 被设计来取代 var

三者的区别见 『♣️ A』

♦️ 2 操作符

运算符 描述 例子
+ a + b
- a - b
* a * b
/ a / b
% 除余 a % b
++ 递增 a++
-- 递减 a--
= 赋值 a = b
== 等于 a == b
=== 严格等于 a === b
! 逻辑非 !a
&& 逻辑与 && a
|| 逻辑或 || a

重点掌握

= 赋值操作符

栗子

var a = 20

小知识点

+ - * / 无异于日常数学运算符

但是 = 在 JS 里是赋值,不是 等于

JS 里的 等于 是一种 布尔运算

如: =====

♦️ 3 数据类型(上)

JS 里,数据的类型可以是 数字字符串

关键字

Number String

栗子

var num = 2 

其中 2 是数字类型

Number阿拉伯数字

var str = "2"
var str2 = '2'
var str3 = '晓程序公开课'
var str4 = ' + num + '      // str4 = '2'
var str5 = `"${num}"`       // str5 = "2"

其中 "2"'2''晓程序公开课' 都是字符串类型

String单引号双引号 包裹起来的字符

小知识点

str4 str5 是两种常见的字符串拼凑方式

♦️ 4 数据类型(下)

JS 里,数据的类型还可以是 数组对象

关键字

Array Object

栗子

var arr = [1, 2, 3, 4]
var arr2 = [1, "晓程序公开课", arr, [1, 2], {x: 1}]

其中 [...] 由一对中括号包裹起来的都是数组类型

Array 数组的每一项可以是任意数据类型,以 , 分隔,

var obj = { x: 1, y: 2}
var obj2 = { x: 1, y: "晓程序公开课", z: [1, 2, 3] }
var obj3 = { arr, obj }
    
// obj3 = { 
//    arr: [1, 2, 3, 4], 
//    obj: { x: 1, y: 2},
//  }

其中 {...} 由一对花括号包裹起来的都是对象类型

Object键值对 的方式呈现 x: 1key: value 每一对以 , 分隔

小知识点

函数 也是一种对象 function class

♦️ 5 实操

分别申明类型为 Number String Array Object 的 4 个变量

栗子

Number

var num = 2017

String

var str = "晓程序公开课"

Array

var arr = [num, str]

Object

var obj = { x: num, y: str, z: arr }

小知识点

掌握了四大基本数据类型,便可以根据实际需求为数据选择一种最恰当的存储方式

♦️ 6 特殊类型

JS 里,除了 Number String Array Object 四大基本类型

还有 Boolean null undefined

其中 Boolean 为布尔类型,存在两种值 truefalse

null 的值是 null 表示不存在

undefined 的值是 undefined 表示未定义

栗子

var yes = true
var no = false

其中变量 yes 和变量 no 都是 Boolean 布尔类型

var none = null
var unset = undefined

其中变量 nonenull 类型

变量 unsetundefined 类型

小知识点

true false null undefined 属于 JS 的关键字,这类特殊字符可以在在声明变量的时候可以直接用

♦️ 7 数据的基本操作(上)

JS 的数据类型有 Number String Array Object Boolean nullundefined

每一种数据类型,都有独特的操作方式

栗子

// 声明
var num = 1
var num2 = 2
var num3 = num + num2 

// 调用
num3      // => 3   

数字类型基本遵循数学里的加、减、乘、除等运算

// 声明
var str = '晓程序'
var str2 = '公开课'
var str3 = str + str2    

// 调用
str3      // => '晓程序公开课'
str3[0]   // => '晓'

字符串类型可以通过索引来拿到对应节点的字符 string[index]

小知识点

NumberString 可以强制转化

Number('123')   // => 123 
String(123)     // => '123' 

♦️ 8 数据的基本操作(中)

Boolean nullundefined

栗子

// 声明
var ok = true
var yes = Boolean(ok)
var bad = false
var no = Boolean(bad)

// 调用
ok      // => true  
yes     // => true 
bad     // => false 
no      // => false 

布尔类型的数据,非 truefalse

Boolean()             // => false
Boolean(undefined)    // => false
Boolean(null)         // => false
Boolean('')           // => false
Boolean(0)            // => false
Boolean(1)            // => true
Boolean(' ')          // => true
Boolean('ooxx')       // => true
Boolean([])           // => true
Boolean({})           // => true

nullundefined 都是 false

小知识点

JS 里,0 表示 false 1 表示 true

'' 空字符串表示 false

任何非 0 '' null undefined 的数据都是 true

♦️ 9 数据的基本操作(下)

Array Object

栗子

// 声明
var arr = [1, 2, 3, 4]

// 调用
arr[0]                  // => 1
arr[1]                  // => 2
arr.length              // => 4 
arr[arr.length - 1]     // => 4
arr[4] = 5              // => arr = [1, 2, 3, 4, 5]

数组有个属性 length 可以放回数组的长度

数组的 索引 总是从 0 开始

// 声明
var obj = { x: 1, y: 2 }

// 调用
obj.x                   // => 1
obj['y']                // => 2
obj.z                   // => undefined
obj.z = 3               // => obj = { x: 1, y: 2, z: 3 }
obj['x'] = 0            // => obj = { x: 0, y: 2, z: 3 }

通过调用 对象属性 可以获得 属性

obj.key                // => value
obj['key']             // => value

小知识点

获取数组的最后一项,可以通过数组的 长度 - 1 来拿到最后一位的 索引

arr[arr.length - 1]

获取 对象属性 有两种书写方式

obj['key'] obj.key

♦️ 10 函数(上)

JS 里,函数是一种可以重用的代码块

关键字 function

栗子

function func() {
  // 函数体
}

函数由一个关键字 function、一个函数名、一对圆括号、一对花括号组成

// 声明
function name() {...}

// 调用
name()
function() {...}

没有名字的函数叫 匿名函数

匿名函数 没有名字,所以定义之后无法调用,因而一般会赋给一个变量来存储或直接执行

// 声明
var fn = function() {...}   // => 将匿名函数赋给变量 fn

// 调用
fn()

// 声明 && 调用
(function(){...})()         // => 声明匿名函数后立执行(俗称闭包)

小知识点

一般情况下,匿名函数 可以用 箭头函数替代

function() {...}            // => 匿名函数
() => {...}                 // => 箭头函数

♦️ J 函数(下)

函数在声明的时候,可以拥有自己的参数

function func(arg) {
  // 函数体
}

其中 arg 就是函数 func 的参数

函数的参数写在圆括号内,可以有多个,表示 从函数外部传入函数内部的数据

// 声明
function name(arg, arg2) {
  return arg + arg2
}

// 调用
name(1, 2)           // => 3

其中 argarg2 是形参

1 2 是实参

returnJS 的关键字,表示 返回 也表示 逻辑结束

小知识点

JS 里,所有函数都有一个默认的 返回值undefined

声明函数时,定义的参数叫 形参

调用函数时,输入的参数叫 实参

函数可以有任意类型的返回值 Number String Array Object null undefined

甚至,函数也能返回函数 function

♦️ Q 判断 && 遍历

关键字 if else map

栗子

if (true) {
  // 条件为真的逻辑
} else {
  // 条件为假的逻辑
}

if else 语句需要有一个条件,写在一对圆括号里 ()

这个条件必须为布尔值,非 truefalse

[1, 2, 3].map(function(item) {
  return item         // => 1, 2 ,3
})

每一个数组都内置了一个 map 方法,用于遍历数组的每一项

小知识点

map 方法需要传入一个函数

var arr = [2, 3, 4]

function func(arg) {
  return arg
}

arr.map(func)        // => 2, 3, 4

♦️ K 综合实操

写一个函数来遍历一个数组的每一项

在遍历之前,需要判断输入的参数类型是否为数组

如果是,则遍历并打印数组的每一项

如果不是,直接返回,什么也不做

栗子

// 声明
var arr = ["小白", "新手", "高手", "大神"]

function mission(arr) {
  var condition = arr instanceof Array
  if (!condition) {
    return 
  } 
  arr.map(function(item) {
    console.log(item)
  }) 
}

// 调用
mission(arr)           // => "小白", "新手", "高手", "大神"
mission()              // => undefined
mission("arr")         // => undefined
mission(1)             // => undefined
mission({})            // => undefined

小知识点

instanceofJS 的关键字,常用于判断数据类型

JS 代码执行顺序是 由上而下

这篇文章价值九元

这个时代,要么最好,要么最坏

在公司门口 “嘀” 了一辆膜拜座驾,骑行回家。

3.5 公里的路程,往常更多是 “滴滴” 代步。

朋友聚会、看电影、唱歌、差旅习惯性打开美团预定。

用饿了么叫外卖,吃前先拍一拍,然后朋友圈发状态。

爸爸妈妈这一辈人,现在一言不合就微信视频,隔三差五发一段语音。

一年中,多了双十一,双十二两个 “大节(劫)”。

路上不仅能看到比亚迪的 E6,还能看到半自动驾驶特斯拉。

路上也经常看到戴着小米手环夜跑的人在 keep fit。

......

我现在居住的地方,是一个三线小城市,很多以为得去一线才能体验到的,现在切切实实就在身边;本以为父辈们不习惯智能手机,可他们现在天天玩微信;终于我渐渐意识到,物联网,没有想象那么遥远。

这两三年潜移默化发生了很多......
电商风起云涌、分布式、大数据、AI。
心里想着,明年、后年,我还会像现在一般,静静享受着互联网越来越多的便利,而自己只是这一切的旁观者吗?

我想做参与者,更想做缔造者!

回望往昔那段最黑暗的日子,每天最大的乐趣就是研读孙皓晖的《大秦帝国》,反反复复,读了一遍又一遍。神往春秋战国五百年,痴迷诸子百家迸发的璀璨**。那是一个伟大的时代,她残酷、现实,狰狞,却也开放、兼容、争鸣。

敬畏法家『极心无二虑,尽公不顾私』
垂涎墨家『鬼斧神工,榫卯绝艺』
陶醉兵家『铁骑与武卒,战鼓和金鸣』
叹服纵横家『凭三寸不烂,煮天下沸腾』
膜拜计然家『崛国无声息,灭国无血刃』
陶养道家『超然脱俗,即有即无』
独不屑儒家『迂腐固化,框国框民』

收回思绪,还看当下:巨头们线上割据,线下拉锯;传统行业蓄势待发,蠢蠢欲动;国家蒸蒸日上,撬动世界格局。这全球化了的天下大势,已不必再神往那尘封了两千多年的战国与春秋,脚下的沙土,我能听到震天战鼓,感知电闪雷鸣,伸手一握,如浴春风。

甚幸,不偏不倚,落在这个介于互联网与物联网的时代。
甚幸,不骄不躁,掌握了一丢丢编程技能。
甚幸,不早不晚,沉淀了一群可以仰仗的小伙伴。

不计划点什么,不做点什么,太愧对这个最好的,也可能是最坏的时代。

借朋友圈搜来的一句话:“随便找个馆子吃饭,桌子和桌子之间的距离不足一米,旁边桌儿两男一女天南地北的扯淡听得一清二楚。从小米的危机,到如家的商业模式,然后竟然聊起了唐诗宋词,其中不乏争论一下何为绝句,最后终于关心起了整个宇宙,将多维世界的真谛说得一清二楚。我想,也只有在北京,有这样有意思的吃饭经历了......”

朋友久居狮城,可能无法像我这般身处其中,感同身受。这隔壁桌的对话,在我看来,那不是一群吃饱没事闲扯淡的人,就是一群宏观大千之云涌,微观不漏颗粒,竖看时代风向,横踏人生前路的人。不敢说会是实实在在的行动派,但至少是能在棋局中切换自如,清醒活着的家伙。

当下,行事不仅要有足够的代入感,还要能分分钟置身事外。正如做产品的、搞开发的、玩设计的,不但要在代码里搞设计,还要在设计中想代码,更要在产品中显亮点,又得切换到用户角度寻共性,切换回市场视野觉差异,最后才比较有可能迎击用户痛点,邂逅刚需。

在产品的路上不忘设计,不怠慢编程。
在梳理思绪的过程中不厌总结,不荒于书写。
在思考的同时不藏、不掖,分享是最好的校验,这个声音有没有落地,直接去看能不能和万千枚有同等认知的头脑产生共鸣。

坐拥当下,把玩编程,品鉴设计,淬炼产品,舞文弄墨,稍不留神,就觅了个诸子百家。

三十而立于这个时代,受宠若惊!
三载恒有小伙伴同行,由是感激!

末了点个题:这个时代,要么最好,好么最坏~

警醒着相互共勉~
愉快地常来交流~

How to initial a kubernetes cluster by kubeadm

first of all

It's easy nowaday to build up a k8s cluster, so dont worry, lets move step by step

step 1 host with ubuntu

At the very beginning, you at least need a host which running ubuntu 16.04+ on it or what ever local host you have, but this tutorial is all about k8s with ubuntu stuff, so assume you've got those.

step 2 install docker ce

There are kinds of elder version of docker on ubuntu which called docker.io etc etc

We are not talking about the above metioned but going to install the docker ce version

Just follow the shell script below

# (Install Docker CE)
## Set up the repository:
### Install packages to allow apt to use a repository over HTTPS
apt-get update && apt-get install -y \
  apt-transport-https ca-certificates curl software-properties-common gnupg2
# Add Docker’s official GPG key:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
# Add the Docker apt repository:
add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) \
  stable"
# Install Docker CE
apt-get update && apt-get install -y \
  containerd.io=1.2.13-2 \
  docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) \
  docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs)

Finally, you still need a daemon config file for docker like that:

# Set up the Docker daemon
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF

This line "exec-opts": ["native.cgroupdriver=systemd"], is typically not required but here it is!

In order to make it works well with k8s, you'd better do it the same

This line "registry-mirrors": ["http://hub-mirror.c.163.com"] is also not required, for some reason in China mainland, you may need something magical like that : )

After the above all have done then restart docker service like that:

mkdir -p /etc/systemd/system/docker.service.d
# Restart Docker
systemctl daemon-reload
systemctl restart docker

step 3 install k8s

Befor install k8s, you may need to do these:

# disabled fire wall
sudo ufw disable
# disabled swap
sudo swapoff -a

Now you are ok to install k8s

apt-get update && apt-get install -y apt-transport-https
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF 
apt-get update
apt-get install -y kubelet kubeadm kubectl

Let's initialization the k8s

sudo kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.18.0 --pod-network-cidr=10.244.0.0/16

Arg --image-repository registry.aliyuncs.com/google_containers is for China mainland issue, something magical you know~

Arg --kubernetes-version v1.18.0 is about which k8s version you want, here I choose v1.18.0, actually you can pick up whatever version you want if there it is.

Arg --pod-network-cidr=10.244.0.0/16 is important because that define which network cidr that k8s will use, typically there are kinds of cidr of k8s, if you do not name one, then it will use the default, and the 10.244.0.0/16 format means I choose flannel as my cidr

Then wait for minutes, if there is no any error occur that means you are almost there

# if you want to run as regular user, then do it below
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Finally, the last move: install flannel

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

All right check out the below command and make sure everything is fine~

kubectl get cs

kubectl get nodes

kubectl get pods -A

How to run your Koa app via docker

Dependencies

  • Docker

  • npm

Step 1 init project and write your koa code

mkdir koa && cd koa && vim app.js
npm i --save koa
// koa/app.js

const Koa = require('koa')
const app = new Koa()
const PORT = 3000

app.use((ctx) => {
  ctx.body = 'Hello World!'
})

app.listen(PORT, () => console.log(`Server is running  on port: ${PORT}`))

Step 2 write your Dockerfile

vim Dockerfile
// koa/Dockerfile

FROM node:latest
COPY . /app
WORKDIRE /app
RUN npm i
EXPOSE 3000
CMD node ./app.js

Step 3 build your docker file

docker build . 

Step 4 run your app

docker run -p 3000:3000 -d [your docker image id]

Bingo~

curl -get localhost:3000
// => Hello World!

这篇文章价值一块钱

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.