1 - 子网掩码

名词解释

子网掩码

它就是拿来划分子网的,更准确的说,划分子网的同时,还能通过它知道主机在子网里面的具体ip的具体地址。

网络号(subnetwork)

表示我住哪个小区。

主机号(host)

表示我家门牌号是多少。

CIDR(无类别域间路由)/VLSM(可变长子网掩码)

比如: 192.168.0.0/24

更多 CIDR / VLSM 例子

参考

[1] 知乎 noopsphere: 什么是子网掩码


·End·

2 - OAuth 2.0 Token Exchange协议解读

S3、OSS使用了STS,但是对其原来并不了解。通过这篇文档梳理对STS实现有一定的了解.

名词解释

security token: a set of information that facilitates the sharing of identity and security information in heterogeneous environments or across security domains. Examples of security tokens include JSON Web Tokens (JWTs) and Security Assertion Markup Language (SAML) 2.0 assertions. Security tokens are typically signed to achieve integrity and sometimes also encrypted to archive confidentiality.

实践

需要找一个实现的开源代码看看.

参考

OAuth 2.0 Token Exchange: a protocol extending OAuth 2.0 that enable clients to request and obtain security tokens from authorization servers acting in the role of an STS . https://tools.ietf.org/html/rfc8693


·End·

3 - OIDC(OPENID CONNECT)身份认证授权

只有一张图!

OIDC = (identity,authentication) + OAuth2.0,在OAuth2.0 上构建了一个身份层,是一个基于OAuth2.0协议的身份认证标准协议。
OIDC应用场景

再来一张图吧! 基于OAuth的认证与身份协议的各个组件

名词解释

RP: 在新的协议语境中,客户端叫依赖方,或者叫 RP

IdP: 从概念上将手段服务器和受保护资源合并为身份提供方

ID令牌: 用于携带有关身份认证事件本身的信息。解决不同身份提供者的协议各不相同的问题。

身份认证

  • 资源拥有者要在授权服务器上授权端点上进行身份认证 为什么有?想想。“忽略了一个环节:对资源拥有者进行身份认证”。
  • 客户端要在授权服务器的令牌端点进行身份认证
  • 最后,基于OAuth实现的身份认证 - OpenID Connect

发现协议

openid-connect discovery 动态服务器发现, 客户端需要知道 IdP的发布者URL。

  • 可以直接配置,比如NASAR
  • 也可以基于WebFinger协议来发现发布者。

客户端注册协议

可以昂客户端向新的身份提供者注册。与OAuth动态客户端注册协议扩展并行,两者是相互兼容的, 参考OAuth动态客户端注册扩展。

  • 如果客户端需要访问的API是由多个不同的服务器提供的。
  • 如果客户端软件有多个实例,每个实例都需要与同一个授权服务器交互。

不同的OpenID Connect客户端

Authorization Code Flow

Authorization Code Flow

Implicit Flow

Successful Authentication Response里返回id_token和token, 而不是code

Hybrid Flow

区别在与reponse_type 可以为 code id_token, code token or code id_token token
不同的返回适用于什么样的场景了?

其他

Access Token

JSON Web Token(JWT) Profile for OAuth2.0 Access Tokens
定义了Token的Data Structure,以及发布和消费Access Token具体的内容

实践

Kong OpenID Connect 支持多种授权流程.罗列下常见的流程

  • Session Authentication
  • JWT Access Token Authentication
  • User Info Authentication
  • Introspection Authentication
  • Authorization Code Flow

更多内容,见参考

Apache Apisix 支持的认证非常少,比如 Authorization Code Flow 不支持。

参考

  1. OIDC 身份认证授权
    http://www.csharpkit.com/2017-09-23_58568.html

  2. OpenID Connect Core 1.0 incorporating errata set 1
    https://openid.net/specs/openid-connect-core-1_0.html

  3. User Authentication with OAuth 2.0 https://oauth.net/articles/authentication/

  4. OAuth 2.0 实战 在web.kamiapp.com里

  5. OpenID Connect Plugin https://docs.konghq.com/hub/kong-inc/openid-connect/


·End·

4 - Io wait 告警问题

%iowait 表示在一个采样周期内有百分之几的时间属于以下情况:CPU空闲、并且仍未完成的I/O请求。

Percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.

两个误解:

  • %iowait 表示 CPU 不能工作的时间
  • %iowait 表示 I/O 有瓶颈

参考:

理解%IOWAIT(%WIO)


·End·

5 - Daily 0201

docker-compose

docker-compose 在同一个目录下启动两个容器,不出现覆盖的情况

docker-compose -p dev  up
docker-compose -p test up 


很方便了

How do I run the same docker-compose.yml several times on same docker daemon with different names?

Iterm 2

前进后退一个单词是不是伤老壳,终于解决了

vim中使用ESC + b/f 来前进或者后退一个单词,ESC真远
设置profile - key来搞定一切 Option + b/f

参考文档 item2常用快捷键总结

6 - Daily 0321

mysql character_set

show variables like ‘character%’;
从my.ini下手(标签下没有的添加,有的修改)

      [client]
       default-character-set=utf8
      [mysql]
       default-character-set=utf8
      [mysqld]
      default-character-set=utf8

Set character_set_database = utf8 重启失效

unicodeencodeerror-latin-1-codec-cant-encode-character

gerrit admin and h2 database

问题: gerrit admin没有实际的权限

Since UUID from groups file and db table account_groups were different I;ve updated table with correct hashes from the group file and added my accont to Administrators group.

e.g. update account_groups set group_uuid=‘9d3ab2b20b498a1793e2e6112d7bdcb01b852588’, owner_group_uuid=‘9d3ab2b20b498a1793e2e6112d7bdcb01b852588’ where group_id=1; INSERT INTO account_group_members (account_id, group_id) VALUES ( “1”, “1”);

Admin group member cannot create

问题:怎么进入h2数据库

java -cp  h2-1.3.175.jar  org.h2.tools.Script -url jdbc:h2:/home/gerrit/db/ReviewDB

查找h2的jar包,然后找到ReviewDB的数据库文件位置

docker服务器时间同步

  1. 安装tzdata软件(apt-get install -y tzdata)
  2. ENV TZ America/Los_Angeles

7 - Daily 0503

vCPU的解释

虛擬主機(Virtual Machine,VM)的CPU稱之為vCPU,當虛擬主機需要CPU運算資源的時候,VMkernel會將此虛擬主機需要的運算資源對應(Mapping)到實體伺服器的CPU核心運算HEC(Hardware Execution Context)能力,以使得虛擬主機得以進行運算。簡單來說,HEC就是實體伺服器的CPU核心數(Cores)。

所以,如圖5所示當虛擬主機配有1 vCPU,在需要運算資源時,只要VMkernel對應到實體主機上其中一個HEC就可以執行運算;若虛擬主機配有2 vCPU,在需要運算資源時,則必須對應到2個HEC才能運算;若4 vCPU則要對應4個HEC才能運算。

虛擬主機vCPU與實體伺服器HEC對應 更多内容

google python style guide

Python 是 Google主要的脚本语言。这本风格指南主要包含的是针对python的编程准则。
中文版Git

elk

更新license: Update License API
注册之后,可以使用xpack, 后台日志不会重复打

logstash_1       | [2018-05-03T11:31:00,614][INFO ][logstash.licensechecker.licensereader] Running health check to see if an Elasticsearch connection is working {:healthcheck_url=>http://logstash_system:xxxxxx@elasticsearch:9200/, :path=>"/"}
logstash_1       | [2018-05-03T11:31:00,615][WARN ][logstash.licensechecker.licensereader] Attempted to resurrect connection to dead ES instance, but got an error. {:url=>"http://logstash_system:xxxxxx@elasticsearch:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError, :error=>"Got response code '401' contacting Elasticsearch at URL 'http://elasticsearch:9200/'"}
logstash_1       | [2018-05-03T11:31:03,796][INFO ][logstash.outputs.elasticsearch] Running health check to see if an Elasticsearch connection is working {:healthcheck_url=>http://logstash_system:xxxxxx@elasticsearch:9200/, :path=>"/"}
logstash_1       | [2018-05-03T11:31:03,797][WARN ][logstash.outputs.elasticsearch] Attempted to resurrect connection to dead ES instance, but got an error. {:url=>"http://logstash_system:xxxxxx@elasticsearch:9200/", :error_type=>LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError, :error=>"Got response code '401' contacting Elasticsearch at URL 'http://elasticsearch:9200/'"}

elastalert

docker elastalert

FROM python:2.7

WORKDIR /
RUN git clone https://github.com/Yelp/elastalert.git
RUN cd  elastalert && git checkout v0.1.30 && pip install -r requirements.txt


WORKDIR /elastalert/
RUN ls -l 

RUN apt-get install -y tzdata
ENV TZ Asia/Shanghai

CMD ["python", "elastalert/elastalert.py"]

参考文档:
Using ElastAlert
ElastAlert: Alerting At Scale With Elasticsearch 各种异常机制

index_not_found_exception 定位python报错行, 问题在于: elastalert判断elastsearch存在index,而实际上并不存在
github elastert isssue 1
解决办法:
create_index.py 244行注释掉delete函数

elasticsearch

some Elasticsearch terminology: an Elasticsearch cluster is made up of one or more nodes. Each of these nodes contains indexes which are split into multiple shards. Elasticsearch makes copies of these shards called replicas. These (primary) shards and replicas are then placed on various nodes throughout the cluster.
更多内容

Elasticsearch 中写一致性原理以及quorum机制

[查看详情](Elasticsearch 中写一致性原理以及quorum机制)

Elasticsearch 5 docker 集群部署–单虚拟机多容器实例

实践

基于 《Elasticsearch: The Definitive Guide》的笔记



GET /my_index/_search
{
  "query": {
    "match_phrase": {
      "names": "Lincoln Smith"
    }
  }
}

GET /_analyze
{
  "analyzer": "standard",
  "text": [
    "John Abraham",
    "Lincoln Smith"
  ]
}

GET /my_index/_doc/9 

PUT /my_index/_doc/9  
{
  "names": ["John Abraham", "Lincoln Smith"]
}


GET /my_blog/_search
{
  "query": {
    "match_phrase": {
      "body": "quick brown fox"
    }
  }
}

GET /my_blog/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "title": "Quick pets"
          }
        },
        {
          "match": {
            "body": "Quick pets"
          }
        }
      ],
      "tie_breaker": 0.7
    }
  }
}



GET /my_blog/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}




# 返回了并不是用户想要的结果 
GET /my_blog/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}



PUT /my_blog/_doc/2
{
  "title": "Keeping pets healthy",    
  "body":  "My quick brown fox eats rabbits on a regular basis."
}

PUT /my_blog/_doc/1
{
  "title": "Quick brown rabbits",    
  "body":  "Brown rabbits are commonly seen."
}


PUT /my_blog



GET /my_index/_search
{
  "query": {
    "match": {
      "title": {
        "query": "BROWN DOG",
        "operator": "and"
      }
    }
  }
}

GET /my_index/_search 
{
  "query": {
    "match": {
      "title": "QUICK!"
    }
  }
}


POST /my_index/_bulk
{ "index": { "_id": 1 }}
{ "title": "The quick brown fox" }
{ "index": { "_id": 2 }} 
{ "title": "The quick brown fox jumps over the lazy dog" }
{ "index": { "_id": 3 }}
{ "title": "The quick brown fox jumps over the quick dog" } 
{ "index": { "_id": 4 }} 
{ "title": "Brown fox brown dog" }


# 为什么 shard 为 1 
PUT /my_index
{
  "settings": {
    "number_of_shards": 1
  }
  
}


DELETE /my_index 


GET /my_store/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "productID": "KDKE-B-9947-#kL5"
          }
        },
        {
          "bool": {
            "must": [
              {
                "term": {
                  "price": "30"
                }
              },
              {
                "term": {
                  "productID": {
                    "value": "JODL-X-1937-#pV7"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}


DELETE /my_store

GET /my_store/_search
{
  "query": {
    "bool": {
      "must": [
        {
        "match_all": {}
        }
      ], 
      "filter": [
        {
          "term": {
            "productID": "XHDK-A-1293-#fJ3"
          }
        }
      ]
    }
  }
}


PUT /my_store 
{     
  "mappings" : {         
      "properties" : {                 
        "productID" : {                     
          "type" : "keyword"
        }            
        }        
      }     
    }


POST /my_store/_doc/_bulk 
{ "index": { "_id": 1 }} 
{ "price" : 10, "productID" : "XHDK-A-1293-#fJ3" } 
{ "index": { "_id": 2 }} 
{ "price" : 20, "productID" : "KDKE-B-9947-#kL5" } 
{ "index": { "_id": 3 }} 
{ "price" : 30, "productID" : "JODL-X-1937-#pV7" } 
{ "index": { "_id": 4 }} 
{ "price" : 30, "productID" : "QQPX-R-3956-#aD8" }



GET /us-tweet/_search
{ 
  "query": {
    "match_all": {}
  }
  , "_source": ["tweet", "date"]
}

GET /us-tweet

GET /us-tweet/_search?search_type=dfs_query_then_fetch

# explain API to understand why one particular document matched or, more important, why it didn't match .
GET /us-tweet/_doc/12/_explain 
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "user_id": "3"
        }
      },
      "must": 
        {
          "match": {
            "tweet": "honeymoon"
          }
        }
      
    }
  }
}

GET /_search?explain=true
{
  "query": {
    "match": {
      "tweet": "honeymoon"
    }
  }
}

GET /_search
{
  "query": {
    "bool": {
      "must": { "match": {
        "tweet": "managee text search"
        } 
      },
      "filter": [
        { "term": {
          "user_id": "2"
          }
        }
      ]
    }
  }
}



GET /us-tweet/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "user_id": 1
        }
      }
    }
  },
  "sort": {
    "date": {
      "order": "desc"
    }
  }
}


GET /_search

PUT /us-user
PUT /gb-user
PUT /gb-tweet
PUT /us-tweet

POST /_bulk
{"create":{"_index":"us-user","_id":"1"}}
{"email":"john@smith.com","name":"John Smith","username":"@john"}
{"create":{"_index":"gb-user","_id":"2"}}
{"email":"mary@jones.com","name":"Mary Jones","username":"@mary"}
{"create":{"_index":"gb-tweet","_id":"3"}}
{"date":"2014-09-13","name":"Mary Jones","tweet":"Elasticsearch means full text search has never been so easy","user_id":2}
{"create":{"_index":"us-tweet","_id":"4"}}
{"date":"2014-09-14","name":"John Smith","tweet":"@mary it is not just text, it does everything","user_id":1}
{"create":{"_index":"gb-tweet","_id":"5"}}
{"date":"2014-09-15","name":"Mary Jones","tweet":"However did I manage before Elasticsearch?","user_id":2}
{"create":{"_index":"us-tweet","_id":"6"}}
{"date":"2014-09-16","name":"John Smith","tweet":"The Elasticsearch API is really easy to use","user_id":1}
{"create":{"_index":"gb-tweet","_id":"7"}}
{"date":"2014-09-17","name":"Mary Jones","tweet":"The Query DSL is really powerful and flexible","user_id":2}
{"create":{"_index":"us-tweet","_id":"8"}}
{"date":"2014-09-18","name":"John Smith","user_id":1}
{"create":{"_index":"gb-tweet","_id":"9"}}
{"date":"2014-09-19","name":"Mary Jones","tweet":"Geo-location aggregations are really cool","user_id":2}
{"create":{"_index":"us-tweet","_id":"10"}}
{"date":"2014-09-20","name":"John Smith","tweet":"Elasticsearch surely is one of the hottest new NoSQL products","user_id":1}
{"create":{"_index":"gb-tweet","_id":"11"}}
{"date":"2014-09-21","name":"Mary Jones","tweet":"Elasticsearch is built for the cloud, easy to scale","user_id":2}
{"create":{"_index":"us-tweet","_id":"12"}}
{"date":"2014-09-22","name":"John Smith","tweet":"Elasticsearch and I have left the honeymoon stage, and I still love her.","user_id":1}
{"create":{"_index":"gb-tweet","_id":"13"}}
{"date":"2014-09-23","name":"Mary Jones","tweet":"So yes, I am an Elasticsearch fanboy","user_id":2}
{"create":{"_index":"us-tweet","_id":"14"}}
{"date":"2014-09-24","name":"John Smith","tweet":"How many more cheesy tweets do I have to write?","user_id":1}
# Don't Repeat Yourself
# 出错,从 7.0 开始,一个索引下一个类型
POST /website/_bulk
{ "index": {"_type": "blog" } }
{ "title": "User logged in" }

GET /website/
# 不要其他的元数据
GET /website/blog/123/_source

# 检索文档的一部分 
GET /website/blog/123?_source=title,text

GET /website/blog/123?pretty

POST /website/blog/
{
  "title": "My second Blog entry"  , 
  "text": "still tying this out .... ", 
  "date": "2014/01/02"
  
}

PUT /website/blog/123
{
  "title": "My First Blog entry"  , 
  "text": "just tying this out .... ", 
  "date": "2014/01/01"
  
}

PUT /website

GET _search
{
  "query": {
    "match_all": {}
  }
}

PUT /megacorp

PUT /megacorp/employee/1 
{     "first_name" : "John",     "last_name" :  "Smith",     "age" :        25,     "about" :      "I love to go rock climbing",     "interests": [ "sports", "music" ] 
  
}

PUT /megacorp/employee/2 
{     "first_name" :  "Jane",     "last_name" :   "Smith",     "age" :         32,     "about" :       "I like to collect rock albums",     "interests":  [ "music" ] }

PUT /megacorp/employee/3 
{     "first_name" :  "Douglas",     "last_name" :   "Fir",     "age" :         35,     "about":        "I like to build cabinets",     "interests":  [ "forestry" ] }

GET /megacorp/employee/1

GET /megacorp/employee/_search 

GET /megacorp/employee/_search?q=last_name:Smith 

# DSL 查询
GET /megacorp/employee/_search 
{
  "query": {
    "match": {
      "last_name": "Smitch"
    }
  }
}


# 年龄大于30岁的员工。

GET /megacorp/employee/_search 
{
  "query": {
    "bool":{
      "filter": {
        "range": {
          "age": { "gt": 30 }
        }
      },
      "must": {
        "match": {
          "last_name": "smitch"
        }
      }
    }
  }
}

GET /megacorp/employee/_search 
{
  "query": {
    "match": {
      "about": "rock climbing"
    }
  }
}


GET /megacorp/employee/_search 
{
  "query": {
    "match_phrase": {
      "about": "rock climbing"
    }
  }
}

# 因为我要聚合的字段 「interests」没有进行优化,也类似没有加索引 
# 没有优化的字段 es 默认是禁止聚合/排序操作的。 
PUT /megacorp/_mapping?pretty
{
  "properties": {
    "interests": {
      "type": "text", 
      "fielddata": true
    }
  }
}

# 让我们找到所有职员中最大的共同点是什么?
GET /megacorp/employee/_search
{
  "aggs":{
    "all_interests": {
      "terms": {"field": "interests" }
    }
  }
}


GET /megacorp/employee/_search 
{
  "query": {
    "match": {
      "last_name": "smith"
    }
  }, 
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}

GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }, 
      "aggs": {
        "avg_age": {
          "avg": {"field": "age"} 
        }
      }
    }
  }
}


PUT /blogs
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}


GET /_cluster/health

nginx配置

(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)
更多详情

tornado

sqlalchemy 和 tornado的结合: session管理放在了每次的request的请求中处理为最佳,以及每次请求经来时,实例化session, 请求结束后, 将session关闭
scoped_session session 注册表,从中取用和还取,并保证多次取用的为统一session
此处的sqlalchemy的数据库查询,并不是异步,当使用tornado 的异步特性时,遇到查询数据库慢时,还是会阻塞的,此时我们更多的需要考虑的

我心中的 tornado 最佳实践

handle blocking tasks in Tornado
其中Ben Darnell回复的,

A ThreadPoolExecutor is the recommended way to use blocking functions that cannot be easily rewritten as non-blocking. When you call yield self._exe(n), that handler will be suspended and the main thread will return to the HTTPServer so it is free to handle other requests. The suspended handler will wake up when the task is completed and the IOLoop is not busy. The new thread pool is created by the main thread but is not “in” the thread. Thread pools should generally be either global or class variables; not instance variables. It is a good practice to have one thread pool for each kind of resource: e.g. one thread pool for database queries and second pool for image processing. This lets you set and monitor separate limits for each one.

import tornado.web
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
import time

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world %s" % time.time())


class SleepHandler(tornado.web.RequestHandler):
    @property
    def executor(self):
        return self.application.executor

    @tornado.gen.coroutine
    def get(self, n):
        n = yield self._exe(n)
        self.write("Awake! %s" % time.time())
        self.finish()

    @run_on_executor
    def _exe(self, n):
        """
        This is a long time job and may block the server,such as a complex DB query or Http request.
        """
        time.sleep(float(n))
        return n


class App(tornado.web.Application):
    def __init__(self):
        handlers = [
                        (r"/", MainHandler),
                        (r"/sleep/(\d+)", SleepHandler),
                    ]
        tornado.web.Application.__init__(self, handlers)
        self.executor = ThreadPoolExecutor(max_workers=60)


if __name__ == "__main__":
    application = App()
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

python

MD,最喜欢的还是贴好文章的链接
PYTHON中YIELD的解释: 这个代码解释详细了,什么是“鸭子类型" (duck typing)

再来一个链接: Iterables vs. Iterators vs. Generators 原来generators还有两种类型(Type): generator functions and generator expressions

这真是一个很长的story啊

futrue使用
Futrue模式的主要使用场景: 当前线程需要依赖另一线程的返回数据并且处理数据的线程又相当耗时,那么Futrue模式就可以使主线程提交数据请求给另一线程处理业务逻辑,等需要时将另一线程返回,很好的利用了等待时间
Python concurrent.future 使用教程及源码初剖

yield 协程
yield并没有指定当前进程要将执行权利移交给谁,只是放弃运行权利,至于下面由谁来运行,完全看进程调度schedule();多用于I/O等待时,进程短暂wait,但是并没有退出运行队列。
进程管理之yield
[ Yield 和 Coroutine ] (http://wsfdl.com/python/2016/11/13/yield_and_croutine.html)

Python (at least in the CPython implementation) has a Global Interpreter Lock which prevents multiple threads from executing Python code at the same time. In particular, anything which runs in a single Python opcode is uninterruptible unless it calls a C function which explicitly releases the GIL. A large exponentation with ** holds the GIL the whole time and thus blocks all other python threads, while a call to bcrypt() will release the GIL so other threads can continue to work.

深入理解 GIL:如何写出高性能及线程安全的 Python 代码 介绍了GIL

参考

[1] Clinton Gormley and Zachary Tong: Elasticsearch: The Definitive Guide

8 - Daily 0607

python import

Python导入模块的几种姿势 文中介绍了如下几种导入:

  • 常规导入(regular imports)
  • 使用from语句导入
  • 相对导入(relative imports)
  • 可选导入(optional imports)
  • 本地/局部导入(local imports)
  • 导入注意事项 : 循环导入(circular imports) 和 覆盖导入(shadowed imports)

9 - Daily 0612

使用pip packege拆分项目

pip 安装git仓库

pip install from git repo branch 介绍几种导入安装方式

为什么不使用git submodule方式来拆分项目

更新子项目的方式使运维工作变得麻烦。

10 - Daily 0813

区块链

参考资料

区块链和 HyperLedger 系列课程(共十讲

11 - Daily 0821 chrome app/extension

入门

深入

扩展

参考

app 创建第一个应用
disable cookies

13 - Daily 10/15 配置https

阿里云免费签发的CA证书,然后下载到服务器,配置nginx

  ssl_certificate   cert/213970811020013.pem;
  ssl_certificate_key  cert/213970811020013.key;

对80端口的域名访问做好跳转

server {
	listen 80;
    server_name server.com www.server.com;
    return 301 https://www.server.com$request_uri;
}

14 - Daily 10/16

学习

UUID

How to create a GUID / UUID in Javascript? 很全面的UUID资料

VUE 统一的数据请求接口

shop.js 接口案例 项目结构

Web

html5 控制 andorid端 input输入框 不弹出输入法? 前端input 不弹输入框

1onfocus='this.blur();'

2readOnly='readOnly'

Dynamic component click event in Vue 动态组件添加click事件,使用@click.native

所不知的 CSS ::before 和 ::after 伪元素用法 多看几次TODO

去除inline-block元素间间距的N种方 两个元素之间没有任何元素,却有空格的解决办法,是inline-block本身存在的问题

postcss postcss-px-to-viewport 解决设计稿到代码的像素的转化 TODO没有webpack加入方式

再聊移动端页面的适配 移动页面的适配最新解决方式

如何和何时使用CSS的!important 解释了为什么使用 !important

light7 优秀的移动端框架

cubic 很酷 TODO

purifycss 去掉无用的css

vue select 下拉选项vue集成

vue demo 结构清晰,耦合很小

团队编码规范 参考学习

Vtiger

vtiger Webservice tutorials api修改crm数据

15 - Daily 10/18

学习

Eslint

enforce the consistent use of either backticks, double, or single quotes 禁用quotes规则,在文件头

/* eslint-disable quotes */

16 - Daily 10/19 三个月

学习

webpack express 配置proxy (http -> https), 修改header参数

webpack dev环境下使用中间件http=proxy-middleware
通过配置参数option.onProxyReq来设置

function onProxyReq(proxyReq, req, res) {
    // add custom header to request
    proxyReq.setHeader('x-added', 'foobar');
    // or log the req
}

node-http-proxy 很多代理的示例,参考用

httpProxy.createProxyServer({
  target: 'https://google.com',
  agent  : https.globalAgent,
  headers: {
    host: 'google.com'
  }
}).listen(8011);

https->http 或者 https->https 配示例

Qs

qs 处理http参数的库,用上了很方便

Vue

编程式的导航

router.push({ path: 'home' })

自定义指令

// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  // 当绑定元素插入到 DOM 中。
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

ESLint

Rules

CSS 切图

页面制作(切图)第一章 从sketch切图

从视觉到App:网易有钱iOS项目切图与适配实践 这个项目过程,谁做什么事情很清楚

为何sketch预置画布尺寸比真实分辨率小? md再看

Retina屏的移动设备如何实现真正1px的线? TODO

中华人民共和国行政区划:省份、城市、区县、乡镇(街道) 很齐全呀

17 - Daily 10/24

学习

Vue

[form validation表单验证](https://www.zhihu.com/question/37099220) 使用va.js 方便验证

自定义指令 各种参数说明

CSS+HTML

HTML5页面滑动到最底部触发内容加载 javascript实现

文档高度 这是整个页面的高度 可视窗口高度 这是你看到的浏览器可视屏幕高度 滚动条滚动高度 滚动条下滑过的高度

CSS: 解决Div float后,父Div无法高度自适应的问题 使用clear:both解决

js

箭头函数没有它自己的this值,箭头函数内的this值继承自外围作用域。
深入浅出ES6(七):箭头函数 Arrow Functions

18 - Daily 10/30

学习

Vue

vue中input绑定回车事件

@keyup.13="search"

javascript 验证身份的有效性

CSS

:first-child 使用:first-child伪类时一定要保证前面没有兄弟节点,把h1去掉就可以;或者使用div包住article,然后css:div article:first-child

移动端高清、多屏适配方案 1)Retina下图片高清问题, 2)retina下,border: 1px问题,3)多屏适配布局问题,

python

python 命令行传参,避免敏感信息硬编码在代码中

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
args = parser.parse_args()

split 第一个参数默认值、所有的空字符(空格、换行(\n)、制表符(\t), 第二个参数表示分隔次数

str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );

   多行匹配模式
这个问题很典型的出现在当你用点(.)去匹配任意字符的时候,忘记了点(.)不能匹配换行符的事实。
re.compile() 函数接受一个标志参数叫 re.DOTALL

comment = re.compile(r'/\*(.*?)\*/', re.DOTALL)

Gerrit

Gerrit代码审核服务器 详细的文章介绍 Gerrit代码审查-简介

git仓库导入到gerrit

I imported many GIT projects to gerrit, the easiest way I found was to copy the xy.git Directory of the git repository to the directory where gerrit deposits the git repos. After restart of gerrit process the new project is in the list of new projects and you can edit description and access rights.

Gerrit内置数据库H2访问权限修改 修改project.config文件

[capability]
       accessDatabase = group Administrators

Gerrit工作流程及使用手册 介绍gerrit安装http

Gerrit英文学习资料

GIT

修改远程仓库地址:

git remote set-url origin [url]

19 - Daily 1018 vim go + Ycm

记录配置vim+go开发环境de折腾过程.

输入".“点号后没有任何提示,不知所措,甚至怀疑就到这里了。

当没有日志,我无从下手解决问题。
我更新了所有的go库,重装了go-code/vim-go,依然没有解决,没有给我任何错误提示。
开始怀疑“人生苦短,我用python”,
不服输,爱折腾。

我重装了vim-go/ gocode之后,我开始怀疑ycm这个玩意。

原来真的是需要升级,而且安装时要注意go

""" /.vim/bundle/YouCompleteMe$ ../install.sh –clang-completer –go-completer

""" 安装时,加上go-completer的参数

最后重启了 ycm服务器
大功告成!!!

参考

Autocomplete stopped working 当我看完这个时,我确定了gocode没有问题。问题可能在ycm;

YouCompleteMe 支持 golang vim 自动补全

用VIM写GOLANG踩坑 这里提到为什么go自动提示的那么慢,原因就在go而非ycm, 最后autobuild的操作置为false

20 - Daily 11.08 Docker安装

环境

Distributor ID:	Ubuntu
Description:	Ubuntu 14.04.5 LTS
Release:	14.04
Codename:	trusty

Install

Get Docker CE for Ubuntu 官方教程

安装前

sudo apt-get install \
  linux-image-extra-$(uname -r) \
  linux-image-extra-virtual

docker

docker中文教程 初学者必看,很有用呀

21 - Daily 11/03

学习

command-t

mac 上command-t 依赖的ruby 的版本与vim的版本不一样:

  • vim安装通过brew来安装的,依赖的brew中的ruby
  • command-t生成Makefile文件的时候依赖系统环境下ruby
  • 系统环境下ruby根据$path路径查找:/usr/local/bin;/usr/bin等等
  • 通过软链接brew下的ruby版本号到/usr/local/bin目录下即可,修改系统环境下ruby版本
  • 重新编译,开始享受vim下查找文件的便利吧

Gerrit

Gerrit 权限控制详细介绍 forge author,和 forge committer这个有用

22 - Daily 1104

学习

Gerrit

5、Gerrit权限控制 详细的权限控制
Gerrit code review - Tutorial 留着慢慢看吧

Python

python xml pretty print not working 配置xml字符解析


mport StringIO
import lxml.etree as etree

def prettify(xml_text):
    """Pretty prints xml."""
    parser = etree.XMLParser(remove_blank_text=True)
    file_obj = StringIO.StringIO(xml_text)
    tree = etree.parse(file_obj, parser)
    return etree.tostring(tree, pretty_print=True)

Web

页面anchor随着内容变化 这个很有必要,当内容太长的时候

23 - Daily 1110 DOCKER部署实践总结

学习

总算把docker整完了

Dockerfile

镜像构建文件,

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

docker_practice github 上dockerfile中文介绍 讲的很详细

查看别人是怎么写Dockerfile:上docker hub上搜索官方的镜像,对应有github仓库地址,查看构建文件.
比如redis构建文件Dockerfile: Dockerfile

看完就知道redis的数据库文件放在什么位置,redis配置文件在哪里,然后可以数据迁移了

redis

redis 数据迁移笔记

docker-compose

为什么容器服务器启动了,docker-compose ps 查看端口也打开,为什么连接的时候出现connect refused.

docker rm 容器

然后build过程中加上 –no-cache

Docker

为了检查构建的镜像是否成功,需要进入容器检查文件 问题是如何进Docker容器了:

几种访问Docker容器的方法

attach 居然卡死,不知道为何/

换种方式,

//查看已经在运行的容器ID
docker ps -a
//通过exec命令对指定的容器执行bash
docker exec -it 31ced27e1684 /bin/bash

深入了解DOCKER 深入,TODO

Docker nginx

需要知道nginx默认配置文件,将自己的配置文件复制粘贴进去

Docker mysql

在docker中运行sql文件

还有个问题,mysql密码怎么设置,免密码失效

RROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2

解决办法是指定
mysql -h localhost -P 3306 –protocol=tcp -u root

导入mysql数据的脚本 直接的学习 TODO

Tornado redis

怎么在Tornado中写redis tornado-redis

24 - Daily 1116

学习

Docker

Build, Ship, and Run Any App, Anywhere

Use a restart policy 重启规则:

1) no\no-failure\unless-stopped\always TODO on-failure\always 有什么区别

docker 使用 supervisor 配置supervisor在前台运行

[supervisord]
nodaemon=true

第一段 supervsord 配置软件本身,使用 nodaemon 参数来运行

Run multiple services in a container 借助了supervisor

Howto: ssh automatically add new hosts to the list of known hosts 配置ssh 解决首次登录时候需要加入known hosts的问题

Host 10.*
   StrictHostKeyChecking no

Compose file 文档

如何告诉git哪个私钥要使用? 最终还是直接使用.ssh/id_rsa默认的私钥了

25 - Daily 1127 MYSQL

选择性复制表数据 这个可, 数据库批量处理必备

亿级数据库设计

详细见 千万级汇总查询优化

基于Mysql数据库亿级数据的设计

Mysql 单标可以存储10亿级的数据,但这个时候性能非常,项目中大量的实验证明,Mysql单表容量在500万左右,性能处于最佳状态。

一张表无法搞定,那么

解决办法

分区

根据查询索引列将单表进行分区,当然这些变化对应用层是无法感知的。

分区类型 说明 使用频率
Range 分区 根据数值范围,根据时间区间或 ID 区间来切分 较多
List 分区 离散值集合 较少
Hash 分区 根据数值取模 较多
KEY 分区 KEY 分区支持 text 和 BLOB, KEY 分区不允许用用户自定义的表达式分区。 较少
  • Hash 分区,基于给定的分区个数,将数据分配到不同的分区。例如会员表的这种表。 HASH 分区只能针对整数进 HASH,对于非整形的字段只能通过表达式将其转换为整数。

如果基于绑定编号(ID)来做range或者list分区,绑定编号没有实际的业务含义,无法通过它进行查询, 因此,我们剩下了HASH分区和Key分区,HASH分区仅支持int类型的列的分区,且是其中的一列。 如果基于绑定的时间列进行分区,查询依然很慢。基于搜索列来进行分区,可以保证查询的速度。

分库

垂直分库:根据业务的耦合性,将关联度低的不同表存储在不同的数据库,以达到资源的饱和利用率。这样每个微服务系统使用独立的一个数据库。

分表

分表分为水平分表和垂直分表(也能避免跨页问题)[7]

MySQL 底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。另外数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。

在业务层增加一张业务和数据存储的表之间的关系表,比如在此方案[4]中增加了 设备-动态数据关系表(表名t_device_table_map) 来存储设备和动态数据表的关系。

最后,梳理下分表 VS 分区

  • 分区就是水平分表的数据库实现版本,水平分表的优点是可以将单张表的数据切分到多个服务器上,每个服务器具有相应的库和子表。
  • 分区只是一张表中的数据和索引的存储位置发生变化,分表是真实的有多套表的配置文件
  • 分区没法突破数据库层面,而分表可以将子表分配在同一个库中,也可以分配在不同的库中。

NoSql/NewSql #TODO

Index scan vs Bitmap scan vs Sequuentianl scan

PostgreSQL will first scan the index and compile those rows / blocks, which are needed at the end of the scan. Then PostgreSQL will take this list and go to the table to really fetch those rows. The beauty is that this mechanism even works if you are using more than just one index.[1]

PostgreSQL Bitmap-scan

联合索引

回表,在执行计划中,table access by index rowid 代表是回表动作。

联合索引的理解[6]: 联合索引结构也是 B+Tree,即按照第一个关键字进行索引,然后在叶子节点上按照第一个关键字、第二个关键字、第三个关键字…进行排序。

最左原则。

如何设计之一: 等值查询中,查询条件a返回的条目比较多,查询条件b返回的条目比较多,而同时查询a、b返回的条目比较少,那么适合建立联合索引;

如何设计之二: 等值查询、范围查询,等值查询的列建在前、范围查询的列建在后。

其他

导出数据库

mysqldump -u root -p news > news.sql

sqlalchemy session 详细介绍sqlalchemy session 几种状态,以及最佳实践。

Docker

docker 使用 docker 命令使用

Docker: Are you trying to connect to a TLS-enabled daemon without TLS?

sudo docker images

export save 区别

docker export Export a container’s filesystem as a tar archive
Docker images导出和导入 实践

BASH

tar 压缩文件夹,exclude排除文件

tar --exclude='./folder1'--exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

VUE 渲染函数

参考

[1] Hans-Jürgen Schönig: POSTGRESQL INDEXING: INDEX SCAN VS. BITMAP SCAN VS. SEQUENTIAL SCAN (BASICS)

[2] zhanlijun 的博客园: 位图索引:原理(BitMap index)

[3] Markus Winand: Pagination Done the Right Way(PPT)

[4] Chaexsy 掘金: MySql 数据库分表分区实践

[5] 茶谪仙 掘金: 数据库分区一篇就透了

[6] houbb: 数据库索引-07-联合索引

[7] PHP 架构师布乐: Mysql 的分区/分库/分表总结

26 - Daily 1208

这段时间太忙了,忙不是理由,chrome tab 都推挤密密麻麻了

学习

Docker

docker 网络 得仔细学习~,使用自定义的网络,–link不生效,有依赖的docker容器启动时 提示没办法找到服务

Setting mac address for container docker还可以固定mac地址,mac地址都有了安全很重要

How To Get Docker Container Ip and Mac Address 查询ip地址与mac地址

docker 下部署gerrit 这个非常方便,一键搞定

积累

几十个tab下来都是docker的内容,最近被docker折腾的死去活来,要固定ip,要固定mac地址, 最后还是因为网络无办法访问取消了。

开始改bug

感情

压力山大

27 - Daily 1215

学习

Understanding REST

Principles of REST:

  • Resources expose easily understood directory structure URIs.
  • Representations transfer JSON or XML to represent data objects and attributes.
  • Messages use HTTP methods explicitly (for example, GET, POST, PUT, and DELETE).
  • Stateless interactions store no client context on the server between requests. State dependencies limit and restrict scalability. The client holds session state.

Idempotency 新词,中文翻译过来是:冪等, 这是put与post的最大的区别

idempotent 的意思是如果相同的操作再執行第二遍第三遍,結果還是跟第一遍的結果一樣 (也就是說不管執行幾次,結果都跟只有執行一次一樣)。

Vue

Vue Async Components 异步加载组件

Vue.component('async-webpack-example', function (resolve) {
  // This special require syntax will instruct Webpack to
  // automatically split your built code into bundles which
  // are loaded over Ajax requests.
  require(['./my-async-component'], resolve)
})

但是,如下webpack 2 + ES2015代码却不行了

Vue.component(
  'async-webpack-example',
  // The `import` function returns a `Promise`.
  () => import('./my-async-component')
)

TODO

vim

YCM vue不支持 打开vue文件导致ycm server挂了,没找到合适的办法解决
目前手动启动ycm server:YcmRestartServer

28 - Daily 1229

Django zip files (create dynamic in-memory archives with Python’s zipfile) 动态打包文件 并输出到浏览器端


from StringIO import StringIO
from zipfile import ZipFile
from django.http import HttpResponse

def download(request, company_id):

    in_memory = StringIO()
    zip = ZipFile(in_memory, "a")

    zip.writestr("file1.txt", "some text contents")
    zip.writestr("file2.csv", "csv,data,here")

    # fix for Linux zip files read in Windows
    for file in zip.filelist:
        file.create_system = 0

    zip.close()

    response = HttpResponse(mimetype="application/zip")
    response["Content-Disposition"] = "attachment; filename=two_files.zip"

    in_memory.seek(0)
    response.write(in_memory.read())

    return response

Using the Forwarded header

proxy_set_header Forwarded $proxy_add_forwarded;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

获取真实的地址: How do I get the client IP of a Tornado request?

x_real_ip = self.request.headers.get("X-Real-IP")
remote_ip = x_real_ip or self.request.remote_ip

29 - Daily 2021/11/01 Postive Discipline

正面管教的原则

正面管教构成的要素

  • 相互尊重
  • 理解行为背后的信念
  • 理解孩子的发展和适龄行为。
  • 有效的沟通
  • 能教给孩子技能的管教
  • 专注于解决方案,而非惩罚
  • 鼓励
  • 孩子在感觉更好时才会做的更好。

应当避免的管教方式

如果你在对孩子大声喊叫或说教,请停下来。如果你在孩子的屁股或打手心,请停下来。如果你在试图通过威胁、警告、贿赂或说教让孩子顺从,请停下来。 所有这些方式都是不尊重的,并且会导致孩子的怀疑、羞愧、内疚,不仅在当时,而且包括未来。

孩子真正需要的是什么?

  1. 归属感(情感联结)
  2. 个人的力量和自主(有能力)
  3. 社会和人生技能(有贡献)
  4. 和善而坚定的指导,教给孩子的技能的管教(以尊严和尊重的方式)

30 - Daily 2022/01/13

PPT 养成日记

写PPT还是非常耗时的, 一张 PPT 已经修改了100多个版本了。

那如何写好每一张 PPT 呢? 就是如何制作一张漂亮的网页一样。

配色

内容框架

每一张 PPT 的构图

这里有很多模版可以参考,比如 slide team 上虽然是收费的,但是上面的画图思路很值得学习。

参考

[1] PPT 作图思路 https://www.slideteam.net/

31 - Daily 5/31

此时

今天是2017年前半年最后一天了,时间真快,过年前大家还在说2017年要实现什么目标,可是我真的没离目标靠近了多少,真伤感。偶尔我真的大叫一声释放下此时的压力。

此事

事业:1、办公家具事情在开年出现几次问题,其中最大问题是工厂发出的货是次品,让我产生想退出办公家具贸易,做自己的产品,从而把控生产质量与包装,减少售后;2、做外贸树脂产品、现在一个月出几单实在让人头疼,接下来走多平台多流量;3、WISH一个店铺因为发货太慢每况愈下,其他店铺正在审核或在上架产品。4、 偶尔又想去上班、今天试着让微信朋友投了一份简历出去。5、每天工作到6-7点就感觉要去跑步锻炼了,不然头晕。
感情:事业压力大,偶尔不想去碰感情的事情,回头一想年纪也算大了,得抓紧时间了

以后

选产品上架出单,不断学习,或工作或继续外贸内贸,感觉后者几率大一些,加油呀!

32 - Daily 6/1

流水账

今天上午完成30个产品上传,舒爽!明天坚持30个…
下午胡思乱想网络传真服务的事情:是否进入做:

  1. 一个月销售额4万,成本一万,月赚3万。
  2. 传真是个没落行业,市场需要就那么大,再进去做顶多做到一半的市场,2万!才两万!除去成本没剩多少了
  3. 以最低的成本找人一起做这个服务。

打包发货开关贴,包装跟产品一样重量,要减重减重减重
晚上加班制作视频,还是不太熟练Ulead Video Studio 11,摸索摸索。明天正确把视频做出来,接下来拍照开关贴 回来俯卧撑,涡轮推,倒立,洗澡睡觉
嘴角上火,吃粽子吃多了,饮食乱了。

六一快乐,一去不复返的时间 | 看了别人上川岛的露营照片,景真是美,等着,忙完就去

多年以后回想此时此情此事

33 - Daily 6/3

Ulead Video Studio 视频中音频处理

今天抽空对视频的声音进行优化:整个视频由图片以及拍摄的视频组成,当播放从图片到录制视频之间, 声音是突然地从无到有过程,感觉很不协调,正常应该是从无开始、声音慢慢变大、到最大持续、最后随着结束慢慢变小、最后没有声音的过程。而Ulead Video Studio中fade in & fade out 很好的处理这个需求,而且可以调整声音变化的快慢
总算认真学习了《会声会影 11 教学影片大纲:第三单元 影片剪接与素材调整》 这个课程真的很实用, 台湾课程,非常赞,再学习其他单元(为了打开MDF、MDS文件,也是找遍了大半个百度,也算值了,教程这么好)
视频制作告一段落!

计划

亚马逊平台:开2-3款树脂产品
WISH平台: 继续每天30款产品上架(MD今天偷懒了,明天继续)
淘宝平台:家具产品

34 - Daily 9/11

学习

NERDTree

隐藏指定后缀名的文件

let NERDTreeIgnore = ['\.pyc$']

Ctrlsf

In CtrlSF Window:

  • O - Like Enter but always leave CtrlSF window opening.
  • t - Like Enter but open file in a new tab.
nnoremap <C-F>t :CtrlSFToggle<CR>
inoremap <C-F>t <Esc>:CtrlSFToggle<CR>

Command-t

检索出文件,需要在新的split window打开文件

<C-CR>      open the selected file in a new split window
<C-s>       open the selected file in a new split window
<C-v>       open the selected file in a new vertical split window
<C-t>       open the selected file in a new tab

vim

split

  • Ctrl-w = resize 所有的窗口一样大小
  • Ctrl-w | 宽度最大化
  • Ctrl-w _ 高度最大化
:noh

turn off highlighting util the next search

ycm

选择快捷键

let g:ycm_key_list_select_completion = ['<TAB>', '<Down>']

SQLachemy

atmcraft model 目录下的meta是做什么用的

Tornado

selene 案例学习,集成数据库monogoDB异步查询 代码阅读
ohmyrepo 简单的案例,集成了Cache。 代码阅读

35 - Daily 9/12

学习

Bash History

修改命令记录数量

export HISTFILESIZE=10000
export HISTSIZE=1000

MAC Terminal TAB

tab切换快捷键 Command + shit + {Command + Shit + ← 向左切换
Command + shit + }Command + Shit + → 向左切换

Gerrit

gerrit query Query the change database gerrit query
gerrit query : Obtain the latest refspec on a Gerrit Change 详细讲解gerrit query
gerrit stream-events 提交事件
gerrit stream-events Provides a portal into the major events occurring on the server, outputting activity data in real-time to the client. Events are filtered by the caller’s access permissions, ensuring the caller only receives events for changes they can view on the web, or in the project repository.

GIT

GIT_SSH_COMMAND

用于git ssh链接访问仓库时,默认设置
GIT_SSH_COMMAND $GIT_SSH_COMMAND takes precedence over $GIT_SSH, and is interpreted by the shell, which allows additional arguments to be included.

GIT_SSH_COMMAND='ssh -i %s' git fetch 

FETCH_HEAD

FETCH_HEAD 指的是: 某个branch在服务器上的最新状态'. 每一个执行过fetch操作的项目’都会存在一个FETCH_HEAD列表, 这个列表保存在 .git/FETCH_HEAD 文件中, 其中每一行对应于远程服务器的一个分支. 当前分支指向的FETCH_HEAD, 就是这个文件第一行对应的那个分支.

Vim

:set wrap "设置自动换行
:set nowrap "设置不自动换行

Python

rfind returns the last index whre the substring is found, or -1 if no such index exists

str.rfind(str, beg=0 end=len(string))

获取当前时间的时间戳

int(time.time())

36 - Daily 9/13

学习

Python

super

理解 Python super 不要一说到 super 就想到父类!super 指的是 MRO 中的下一个类!

class Root(object):
    def __init__(self):
        print("this is Root")

class B(Root):
    def __init__(self):
        print("enter B")
        # print(self)  # this will print <__main__.D object at 0x...>
        super(B, self).__init__()
        print("leave B")

class C(Root):
    def __init__(self):
        print("enter C")
        super(C, self).__init__()
        print("leave C")

class D(B, C):
    pass

d = D()
print(d.__class__.__mro__)

mixin

Python mixin模式 Python的Mixin模式可以通过多继承的方式来实现

Vim

let g:UltiSnipsExpandTrigger="<c-j>"

ultisnips 自动完成跟YCM的<tab>快捷键冲突
UltiSnips 让 Vim 飞起来 vim snippets详细设置过程

Andoid

Compile gradle project with another project as a dependency 编译两个独立的项目,需要制定依赖的路径
Dependency Management Gradle依赖

37 - Daily 9/14

学习

Vue

vue-history-api-fallback 解决url中包含句的问题

history({
  router,
  disableDotRule: true
});

webpack

利用historyApiFallback选项,可以重写url

historyApiFallback: {
    rewrites: [
        // shows views/landing.html as the landing page
        { from: /^\/$/, to: '/views/landing.html' },
        // shows views/subpage.html for all routes starting with /subpage
        { from: /^\/subpage/, to: '/views/subpage.html' },
        // shows views/404.html on all other pages
        { from: /./, to: '/views/404.html' },
    ],
},

Javascript

import 用法 used to import functions, objects, or primitives which are defined in and exported by an external module, script, or the like.

import defaultMember from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as name from "module-name";
import "module-name";

Tornado

Python与Tornado 一个系列 抽时间通读 #TODO

Python

Differences between isinstance() and type() in python isinstance与type

Correct way to write line to file in Python print也可以写入文件里

38 - Daily 9/18

学习

redis

Redis持久化-RDB与AOF 同一个redis实例可以配置两种持久化方案
Redis 查询所有的key 查询所有的key
Redis持久化 redis持久化两种方式的对比

python 重命令

os.rename How to change folder names in python?

Vim

mac vim 配置文件 mac vim 记住上次打开的位置

set viminfo='10,\"100,:20,%,n~/.viminfo
au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif

vim 语法高亮 对于大文件,语法高亮

syn sync fromstart

vim YCM插件自动补全比较慢的解决办法 第三个字母开始自动完成提示

vim YCM跳转到定义跳转到申明 使用往前跳和往后跳的快捷键为Ctrl+O以及Ctrl+I。

nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>
nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR>

vim bookmark 字母书签的功能

[vim recording] What is vim recording and how can it be disabled? 偶尔按错键,导致左下角出现’recording @q’等字样

javascript

IOS webview 与js通信方案 跟java代码有点区别,不能统一吗

Server can’t be accessed via IP webpack-server如何配置通过IP访问

python 序列化与反序列化

pickle — Python object serialization¶ 用于redis cache 缓存

confluence

这个跟jira如何协作的?

39 - Daily 9/21

学习

python unittest tornado

test_handlers.py 案例代码 selene项目测试案例

request_handler_test.py 案例代码 设置项目根目录、父类构建

tornado.testing —单元测试支持异步代码 支持异步测试

How to use a test tornado server handler that authenticates a user via a secure cookie mock cookie

命令行下执行单个unittest 更多的参数

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

setup 使用,初始化数据 TODO

tornado sample 有接口测试的项目

python unittest文档

python unittest执行顺序问题 字母的顺序执行

python mock handler

class MyUT(tornado.testing.AsyncHTTPTestCase):
  def get_app(self):
    settings = {
      "template_path": '../../../templates',
      "cookie_secret": 'secret',
      "login_url": '/admin/login',
      "debug": True
    }

    return Application([
      (r'/admin/create/super', handlers.CreateSuperUserHandler)
    ], **settings)


  def testGet(self):
    with mock.patch.object(handlers.CreateSuperUserHandler, 'get_current_user') as m:
      m.return_value = {}
      response = self.fetch('/admin/create/super')

    print(response.body)
    self.assertGreater(response.body.index('create'), 0)

mock handler更详细的例子 patch和patch.object 使用

Python

操作dict时避免出现KeyError的几种方法 使用get方法更好
How to get name of exception that was caught in Python? 获取异常的的类名

try:
    foo = bar
except Exception as exception:
    assert type(exception).__name__ == 'NameError'
    assert exception.__class__.__name__ == 'NameError'

删除dict里面的元素 use del

>>> from collections import OrderedDict
>>> dct = OrderedDict()
>>> dct['a'] = 1
>>> dct['b'] = 2
>>> dct['c'] = 3
>>> dct
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> del dct['b']
>>> dct
OrderedDict([('a', 1), ('c', 3)])
>>>

python面向对象 入门级介绍 TODO

python set 集合操做 比如删除某个元素 set.remove(key)

subprocess returncode 什么时候为0

import subprocess as sp
child = sp.Popen(openRTSP + opts.split(), stdout=sp.PIPE)
streamdata = child.communicate()[0]
rc = child.returncode

Tornado

Tornado异步与延迟任务 Tornado异步通俗易懂的教程
协程 官方文档 难懂
tornado.gen源码解析 TODO

GIT

*
!.gitignore

git中如何提交空目录 空文件

git 提交撤销

git reset HEAD~2

40 - Daily 9/22

学习

项目

项目周报的编写参考confluence里面的优秀的周报日志,TODO
模版如下:

### 本周工作
---
1. 学习vue
2. 完成登录页面开发
...

### 下周计划
---
1. 继续学习vue
2. 继续完成登录页面开发

### issues
---
- 我觉得我们团队棒棒哒,就是女生少了一点
- webpack的打包时间越来越长,我们可以考虑优化它

VUE

合作的同事去了其他部门,我开始接口VUE开发工作,然后问题来了 Watch 对比更改前的值oldValue

a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },

Vim

vim-vue 下vue文件居然高亮了前部分

autocmd FileType vue syntax sync fromstart

加上上面的配置就可以了

支持NERDCommenter的解决办法。

let g:ft = ''
function! NERDCommenter_before()
  if &ft == 'vue'
    let g:ft = 'vue'
    let stack = synstack(line('.'), col('.'))
    if len(stack) > 0
      let syn = synIDattr((stack)[0], 'name')
      if len(syn) > 0
        exe 'setf ' . substitute(tolower(syn), '^vue_', '', '')
      endif
    endif
  endif
endfunction
function! NERDCommenter_after()
  if g:ft == 'vue'
    setf vue
    let g:ft = ''
  endif
endfunction

Codepen.io

在线编辑代码,可见即可得,学习的好工具,支持zencoding
login in by github

CSS

布局 40个教程、技巧、例子和最佳实践

css Flex flex布局,项目中用到比较多

javascript

Monad 这是个什么鬼,第一次听说 还是无意中看到 TODO

processon

流程图的好工具在线的
已经开始使用了,简简单单画了三个图,太强大了。

41 - Daily 9/25 #vpn

学习

Supervisor

Supervisor 是一个用 Python 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。
Supervisor 中文文档

Screen

在标题和状态栏中显示Screen的窗口名称

caption always "%{= kw}%-w%{= kG}%{+b}[%n %t]%{-b}%{= kw}%+w %=%d %M %0c %{g}%H%{-}"

Vpn

今天vpn可以看720P视频奇怪,接下来要做的事情是测试vpn速度,保证vpn24小时速度稳定

42 - Daily 9/27 Git 相关知识点

学习

Bash history

编辑文件.bash_profile

HISTFILESIZE=100000

重启下终端,看看~/.bash_history 是不是就可以存储更多的历史命令了。

Git tag

补打标签

git tag -a v1.2 9fceb02

分享标签

git push origin [tagname]

Git stash

多个分支共享 stash list, 为什么git stash apply时不区分分支。

今天碰到的一问题,git stash完美解决问题: 我在 dev 分支上更改了一个小 bug,我需要把这个升级到线上,但是 dev 分支上正在进行项目 A 的开发很久了,没办法直接把 dev 上线,怎么办? 只有先git stash储藏起来,然后切换分支,通过git stash apply 应用到切换后的分支即可,然后把提交,上线新分支。切换回 dev 继续开发项目 A

Git checkout revert reset

代码回滚:Reset、Checkout、Revert 的选择 好详细的介绍

代码合并:Merge、Rebase 的选择 git rebase 黄金法则

有没有别人正在这个分支上工作?

Git rebase

Git-rebase 小筆記 介绍各种 rebase 详细技巧

修正 commit 過的版本歷史紀錄 Part 5 实战 Rebase 能做的事

Git tree

show a Git tree in terminal

git log --graph --oneline --all

配置 git tree

git config --global alias.tree "log --graph --decorate --pretty=oneline --abbrev-commit"

Git push -f

Git 回滚远程版本 真的想不到这个都可以,太强大了

git log
git reset --soft ${commit-id}
git stash
git push -f

Git log

一直以来对于 git log –graph 有一种似懂非懂的感觉。 来自 Git Community Book 中文版 - 查看历史 - Git 日志 提到日志排序的几种

  • 逆时间顺序 (reverse chronological): 默认情况下为这种方式
  • 拓扑顺序 (–topo-order): 子提交在他们的福提交前显示,这种方式会看到”开发线“(development lines) 都会集合在一起
  • 提交日期顺序

Talk is cheap,Show me the code or money~

43 - Daily 9/5

一直要做的事情:知识的系统化梳理
LP生气了,换了微信头像,发了朋友圈,哽咽几下,而我说了一堆话,不知道有没有用

  • vue+webpack重构了整个项目,明天上线新系统,工作上事情很多,做不完的工作,学不完的知识(系统化多重要)
    • 工作上的发展方向是怎样的,这个问题一直不想,TMCD!
  • 贸易上的事情进展太慢了
    • Amazon上产品
    • 开模新产品
    • 产品包装:产品尺寸定做包装
    • 发货还是个问题,FBA

说了一句话:“我对自己也不满意” ,英文翻译过去应该是’fuck yourself, or What'.
睡觉,长叹一口气!

44 - Daily 9/6

感情

关进了小黑(la)屋(hei)

过了2个小时,出来了!上次也是关了几个小时。
生气了一会就自我恢复了。

工作

新系统顺利上线了

学习

Curry 编程 Currying is the process of turning a function that expects multiple parameters into one that, when supplied fewer parameters, returns a new function that awaits the remaining ones.

Ramda.js A practical functional library for JavaScript programmers.

45 - Daily 9/8

学习


#### Python时间处理 [Python dateutil](https://dateutil.readthedocs.io/en/stable/index.html) 非常强大的时间处理,对这种数据'Fri, 21 Jul 2017 14:42:50 +0800'轻易解析 [strftime](http://strftime.org/) 最详细的时间格式说明 [3.15 字符串转换为日期](http://python3-cookbook.readthedocs.io/zh_CN/latest/c03/p15_convert_strings_into_datetimes.html)官网文档datetime.strptime ```python date.today().strftime(u'%Y年%m月%d日'.encode('utf-8')).decode('utf-8') ```
#### EMAIL收发邮件 [官网email](https://docs.python.org/2/library/email-examples.html)发送邮件的详细例子 [POP3收取邮件](https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001408244819215430d726128bf4fa78afe2890bec57736000) 详细教程 [Reply to email using python 3.4](https://stackoverflow.com/questions/31433633/reply-to-email-using-python-3-4)回复邮件的代码 [邮件解析](http://blog.donews.com/limodou/archive/2004/12/30/220588.aspx) 编码问题 [邮件详细解析](http://www.cnblogs.com/zixuan-zhang/p/3402821.html) 这个更详细

#### PYTHON GIT [pygit2](http://www.pygit2.org/merge.html) python api for git
### 生活 周日去香港徒步,16公里

46 - 又是一年最长假-国庆 Daily 9/29

生活

国庆长假对于工作的人真是长假! 回!

学习

Vim

Switching case of characters 还是官网文档比较给力

Javascript

Is object empty? JS中如何判断一个空的对象

Array最后一个元素

var args=new Array(['www'],['phpernote'],['com']);
alert(args.pop());//com

正则表达式

不匹配的问题

^((?!hede).)*$

Webpack

修改dev server的根目录

devServer: {
  contentBase: path.join(__dirname, "dist"),
  compress: true,
  port: 9000
}

当js文件名webpack打包生成的时候,不能写死在html中,如何让js文件自动加入到html文件中

HtmlWebpackPlugin 插件解决了这个问题

var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
  entry: 'index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'index_bundle.js'
  },
  plugins: [new HtmlWebpackPlugin()]
};

github 项目地址

VUE

Vue.js 带来的良好的开发模式:模板,数据绑定,组件化,自动化,资源统一化

vue-mobile - 一个基于VUE的UI框架