0%

使用make给slice初始化时,不建议在一开始就分配很大空间,除非特别清楚slice的变化过程。

比如如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"fmt"
)

func main() {
s := make([]byte, 0, 32)
println(s)
s1 := append(s, 'a')
println(s1)
s2 := append(s, 'b')
println(s2)

fmt.Println(string(s1), string(s2))
}

代码输出:

[0/32]0xc000072f30
[1/32]0xc000072f30
[1/32]0xc000072f30
b b
阅读全文 »

一、8瓶药里1瓶毒药,至少需要多少老鼠

老鼠找出毒药的一般问题类型是m瓶药,其中一瓶是毒药,用n只老鼠来检测,求n最小多少。

问题的最小规模是8瓶药,3只老鼠。明面和暗含的条件有

  • m瓶药里只有一瓶毒药;
  • 毒药立马发作;
  • 所有老鼠同时喝药;

答案是2^3=8,故3只老鼠即可。具体方案是:瓶子0-7号(0号瓶所有老鼠都不喝。如果M1 M2 M3都没死,那0号就是毒药):

阅读全文 »

了解B+树前,先了解一下二叉查找树和平衡二叉树。二叉查找树规定(非严谨定义)左子树键值小于根键值,根键值小于右子树键值。
//二叉树查找树图片

平衡二叉树在二叉查找树的基础上,还要求任意节点的左右子树高度差不超过1,目的是通过降低树的高度来减少查询次数。

//平衡二叉树图片

B+树的定义较为复杂,先看一个高度为2的B+树:

//B+树图片

阅读全文 »

Git是一套内容寻址(content-addressable)文件系统

  1. 通过执行docker-compose所在的shell环境注入

    1
    2
    web:
    image: "webapp:${TAG}"
  2. 通过文件注入
    2.1 默认使用.env中的变量

    1
    2
       $ cat .env
    TAG=v1.5
    1
    2
    3
    4
    5
    $ cat docker-compose.yml
    version: '2.0'
    services:
    web:
    image: "webapp:${TAG}"

    2.2 指定环境变量文件

    1
    2
    3
    4
    5
    //同docker run –env-file=web-variables.env
    //docker-compose -f web-variables.env
    web:
    env_file:
    - web-variables.env
  3. 通过docker-compose.yml注入

    1
    2
    3
    4
    //同docker run -e DEBUG=1
    web:
    environment:
    - DEBUG=1
    1
    2
    3
    4
    //同docker run -e DEBUG
    web:
    environment:
    - DEBUG //无赋值的环境变量
  4. 通过启动命令注入

    1
    2
    3
    docker run
    docker run -e DEBUG=1
    docker run -e DEBUG // VARIABLE从shell环境变量中获取,同第1条
    1
    2
    3
    docker-compose run
    docker-compose run -e DEBUG=1
    docker-compose run -e DEBUG // VARIABLE从shell环境变量中获取,同第1条
  5. 优先级从大到小

    1
    2
    3
    4
    5
    Shell 
    Compose file
    Environment file
    Dockerfile
    Variable is not defined

BUG出现的原因是未正确使用钩子——至少没有按Codeigniter的要求来使用:我们的钩子类继承了CI_Controller,但阅读源码后发现不能这么干。

当我们 new 一个自己定义的 Controller 的时候(发生在 system/core/Codeigniter.php),CI_Controller 的构造方法会被执行,存储于静态变量$_is_loaded(可以通过is_loaded()调用)里的类都会被传入load_class()加载一遍,而 load_class 方法在引入文件后,不会直接 new 一个传入的类,它会先给传入的类名加上 CI_ 前缀再创建对象。即 new “CI_{$class}”。问题就出现在这里。

load_class给传入的类名自动加 CI_ 前缀是写死在代码里的,不能通过传入其他参数改变它的行为。个人猜测这样做是为了防止开发者滥用 load_class:框架维护人员通过 load_class 加载框架核心类,开发者使用 Loader 来加载业务相关的类。

解决问题的方法就是,保证每次用户访问最多执行一次 CI_Controller 的构造方法。如果要在钩子里使用 Loader(例如 load->model()、load->database()),可以使用全局的 &get_instance() 得到的 CI_Controller全局静态实例来加载。

1
2
3
4
5
6
//使用CI_Controller的全局静态实例
$this->ci =& get_instance();
$this->ci->load =& load_class('Loader', 'core');
$this->ci->load->model('api_model');
$this->ci->api_model->setCaller($this->appid);
//model里正常连接数据库
阅读全文 »

一、基本

  • 模块化适用

    • 对象创建

    • model模板

二、后端交互

  • 和后端的交互就是数据的变换过程:收集、传输、展示 (目前只有少量处理数据)

三、数据、操作的验证:触发-反馈

阅读全文 »

使用rabbitmq和redis有一段时间了,有一些心得体会:
rabbitmq使用的php-amqplib,exchange使用的direct,消息持久化,1h后过期;队列自动删除,7天后过期;

监听消息时的优缺点:
rabbitmq:

缺点:
    1. 一个消费者只能监听一个消息,遇到【消息:动作 = N:1】的时候,要多开几个进程;
    2. 为了在控制面板查看进程有没有启动,需要给每个队列指定一个名字;
    3. 必须显式ack/nack;

优点:
    1. 可以先publish后subscribe。对于publish、subscribe分开上线的情形,可以先上线publish部分;
    2. 允许一定的消息累积;
    3. 消息丢失风险可以控制到很低;
    4. 用来发送需要延时的消息(微信模板/短信/邮件);
    5. 消息太多的时候,可以开多个进程,轮流接收处理消息;

redis:

缺点:
    1. sub端断开的时候会丢失消息(crontab五个星号不是常驻的意思,仅仅表示每分钟都会执行);
    2. 进程容易自动结束(1分钟左右);
    3. 必须先开sub端,再pub消息,否则会丢失;
优点:
    1. 可以同时监听多个队列的消息;
    2. 使用很方便,不需要关注消息过期,队列名字之类的;
阅读全文 »