/images/avatar.png

《去月球》

悲伤。 逆序的故事,抽丝剥茧式的把一个人的人生整个展现在你的面前。 明明在一起的两个人,却由于种种心相隔很远。 丽芙的一生都在通过各种暗示,希望主人公能够找回过去。 主人公终于在临终前的愿望中,抓到那么一个记忆碎片,无来由的想要去月球。 当,记忆被重新排列,故事里的两人有了圆满的结局。 回过头来看,这不过是程序的重新编排。而现实中的两人,却一生都没能找到最初相遇的那个瞬间。

gitlab workflow

建立一个长期分支,就是master,master分支上的版本都是能够编译运行的版本。 整个工作流程如下。 第一步:根据需求,从master拉出新分支,不区分功能分支或补丁分支。 第二步:新分支开发完成后,或者需要讨论的时候,先从master合并到分支,解决冲突,然后向master发起一个pull request(简称PR)。 第三步:Pull Request既是一个通知,让别人注意到你的请求,又是一种对话机制,大家一起评审和讨论你的代码。对话过程中,你还可以不断提交代码。 第四步:你的Pull Request被接受,合并进master,重新部署后,原来你拉出来的那个分支就被删除。(先部署再合并也可。)

建立测试项目

新建一个项目用于测试工作流。 演示项目地址:http://10.10.10.98/MekaYangyi/workflow

设置分支保护

新建项目默认master用户才能够push和merge。 其余用户只能新建分支,在分支测试完毕后,再发起Merge Requests。发起后,由master进行审核后合并。

第一次使用gitlab

安装git

版本差别不大,目前使用的版本git2.11.0.3。 一路下一步,不修改安装位置,直接使用默认设置。

安装TortoiseGit

一路下一步,不修改安装位置,直接使用默认设置。

登录账户

管理员创建账户

Admin→New User。新建账户、并设置密码。同时设置该用户所属Group。

name:上传显示的名字,可以经常更改,使用中文名好。

username:登陆的用户名,不可修改,用于账户登陆。

email:账户email,内网联系email。

password:密码,牢记,root用户可修改。

登录

登陆内网gitlab,目前网址:10.10.10.98。

[读书笔记] stl源码剖析 总结

大致上是将STL源码剖析看过了一篇。 前三章看到比较认真,后面几章就看到比较粗略了。 我想STL的精髓正是在内存配置、迭代器、容器中。 至于后面的一些关联式容器,用的红黑树稍复杂,不过在之前的数据结构的基础上和前几章对stl的一些常用方法是熟悉下,其实也就简单了。算法,利用迭代器,同时特化不同的版本。仿函数则是模仿函数效果的对象。整体上都算简单了。 我的计划是在未来的一小段日子里实现一个小型的stl,所谓实现,可能也不过是重新将sgi的代码打一遍罢了。不过对于整个stl的理解,我相信会更好一些。 之后我应该会更新一些写小型stl遇到的问题和解决方案。 项目的地址: https://github.com/MekaYangyi/STL/

[读书笔记] stl源码剖析 第四章 序列式容器

容器分类

vector

vector还是比较简单,也就是一个动态数组,提供了些操作,带三个指针,start/finish/end 核心就是动态调整内存的方法,也就是满了开大一倍空间,拷贝过去。 push_back等操作都是值语义的,拷贝传进来的内容放入到vector中。 因为是连续的空间,所有元素连续存储在一整块内存上,迭代器直接用的原始指针。

list

list复杂些. 模型和常见的list是一致的,动态创建节点,插入。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
struct _List_node_base {
  _List_node_base* _M_next;
  _List_node_base* _M_prev;
};

template <class _Tp>
struct _List_node : public _List_node_base {
  _Tp _M_data;
};

//迭代器base
struct _List_iterator_base {
  typedef size_t                     size_type;
  typedef ptrdiff_t                  difference_type;
  typedef bidirectional_iterator_tag iterator_category;

  _List_node_base* _M_node;//节点指针

  _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
  _List_iterator_base() {}

  void _M_incr() { _M_node = _M_node->_M_next; }
  void _M_decr() { _M_node = _M_node->_M_prev; }

  bool operator==(const _List_iterator_base& __x) const {
    return _M_node == __x._M_node;
  }
  bool operator!=(const _List_iterator_base& __x) const {
    return _M_node != __x._M_node;
  }
};  

//迭代器,重载了++ -- == * ->等操作
template<class _Tp, class _Ref, class _Ptr>
struct _List_iterator : public _List_iterator_base {
  typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
  typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;

  typedef _Tp value_type;
  typedef _Ptr pointer;
  typedef _Ref reference;
  typedef _List_node<_Tp> _Node;

  _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
  _List_iterator() {}
  _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}

  reference operator*() const { return ((_Node*) _M_node)->_M_data; }

#ifndef __SGI_STL_NO_ARROW_OPERATOR
  pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */

  _Self& operator++() { 
    this->_M_incr();
    return *this;
  }
  _Self operator++(int) { 
    _Self __tmp = *this;
    this->_M_incr();
    return __tmp;
  }
  _Self& operator--() { 
    this->_M_decr();
    return *this;
  }
  _Self operator--(int) { 
    _Self __tmp = *this;
    this->_M_decr();
    return __tmp;
  }
};

[读书笔记] stl源码剖析 第三章 迭代器

迭代器是一种抽象的设计概念。iterator模式:提供一种方法,使能够依序寻访某个聚合物所含的各个元素,而又无需暴露该聚合物的内部表述方式。

迭代器的设计思维-stl关键所在

STL的中心思想在于:将数据容器和算法分开,彼此独立设计。容器和算法的泛型化。 迭代器就是扮演着粘胶角色。

迭代器是一种smart pointer

list迭代器stl的实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
//listnode的基础类
struct _List_node_base {
  _List_node_base* _M_next;
  _List_node_base* _M_prev;
};
//listnode
template <class _Tp>
struct _List_node : public _List_node_base {
  _Tp _M_data;
};

//迭代器基础类
struct _List_iterator_base {
  typedef size_t                     size_type;
  typedef ptrdiff_t                  difference_type;
  typedef bidirectional_iterator_tag iterator_category;

  _List_node_base* _M_node;//包含一个node

  _List_iterator_base(_List_node_base* __x) : _M_node(__x) {}
  _List_iterator_base() {}

  void _M_incr() { _M_node = _M_node->_M_next; }
  void _M_decr() { _M_node = _M_node->_M_prev; }

  bool operator==(const _List_iterator_base& __x) const {
    return _M_node == __x._M_node;
  }
  bool operator!=(const _List_iterator_base& __x) const {
    return _M_node != __x._M_node;
  }
};  
//迭代器
template<class _Tp, class _Ref, class _Ptr>
struct _List_iterator : public _List_iterator_base {
  typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
  typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  typedef _List_iterator<_Tp,_Ref,_Ptr>             _Self;

  typedef _Tp value_type;
  typedef _Ptr pointer;
  typedef _Ref reference;
  typedef _List_node<_Tp> _Node;

  _List_iterator(_Node* __x) : _List_iterator_base(__x) {}
  _List_iterator() {}
  _List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {}

  reference operator*() const { return ((_Node*) _M_node)->_M_data; }

#ifndef __SGI_STL_NO_ARROW_OPERATOR
  pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */
  //重载了几个操作实现了迭代器,不是很复杂
  //++i
  _Self& operator++() { 
    this->_M_incr();
    return *this;
  }
  //i++
  _Self operator++(int) { 
    _Self __tmp = *this;
    this->_M_incr();
    return __tmp;
  }
  _Self& operator--() { 
    this->_M_decr();
    return *this;
  }
  _Self operator--(int) { 
    _Self __tmp = *this;
    this->_M_decr();
    return __tmp;
  }
};