win10 很强大,但 wsl 还是用起来不如纯 linux,1 个 netstat 命令不能用,让我觉得还是拥抱双系统…

u 盘安装即可,现在 3 个引导: win10, ubuntu18, 外界硬盘的 ubuntu16(原工作内容全在里面了),需要用boot-repair神器修复下,最后还要修改下/boot/grub/grub.cfg,去掉多余的选项.

软件配置

  • 字体

字体安装

windows 字体挪到 unbuntu 上

另外需下一个 gnome-trweak-tool 来调整下系统

  • vim vim-gnome 默认 python3+
sudo apt-get install vim-gnonme

什么 vundle BundleInstalll 都是老套路了.

核心自然是youcompleteme了,基于 python3 编译,先用update-alternatives管理下 python 版本:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6  36 --slave /usr/bin/python3m python3m /usr/bin/python3.6m --slave /usr/bin/pip pip /usr/bin/pip3
  • shadowsocks

ss 大杀器,前面配好了 python3,这个才能顺利

pip install shadowsocks

用 systemctl 配置为开机 Unit 服务,添加到shadowsocks.service/lib/systemd/system

[Unit]
Description=Shadowsocks Client Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/sslocal -qc /etc/shadowsocks/config.json

[Install]
WantedBy=multi-user.target
sudo systemctrl restart shadowsocks.service

就在刚配置这个玩意的时候,bwg 被 ddos 攻击了..我这破 vps 还有人攻击…最后的解决方案是重装 centos

  • jekyll

blog 必须的配置好

sudo apt-get install nodejs
sudo apt-get ruby ruby-dev
# not neccessary
gem sources --add https://ruby.taobao.org/ --remove https://rubygems.org/

sudo gem install jekyll --verbose
sudo gem install bundle
cd axx.github.io
bundle install
bundle exec jekyll server
  • wechat 还真有 Electron 写的 wechat,666.直接到 ubuntu software 中心下

  • pycharm vscode 都纳入 ubuntu software 下了,很方便安装和升级,vscode 直接官网下 deb 包更快. ubuntu18 还用到新的 snap 管理包的方式,中间下载 pycharm 出了点问题,通过下面的命令才解决:

参考

snap change  // 查看snap 状态
sudo snap abort no.x  //终止某个snap的过程

另 vscode 用setgins sync将自己的配置同步下,截屏+七牛相关的记得复制粘贴下.

  • capslock 提示

Thinkpad 的老毛病了,解决方案

  • email 尝试了 hiri,很强大但是要收费,还是老实的 thunderbird 好了.
sudo apt-get install thunderbird
  • cisco vpn any connect sudo apt-get install network-manager-openconnect-gnome

Read More

中介者模式

没有中介者时, A B 相互影响: A<-------->B

通过中介类隔离影响,解耦 A,B : A<----Meditor---->B

Meditor 可以更多的 ABCDEFG 之间的中介,避免同事类之间的过度耦合.

中介者维护两端的关系,具体两端谁和谁来通信,中介者说了算.

使用中介者模式可以将对象间多对多的关联转变为一对一的关联,使对象间的关系易于理解和维护, 也可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。

典型的例子就是即时通讯,比如 qq 联系人这种.

中介者模式解决的问题: 2018-08-10-13-01-34

具体例子:

#include <iostream>
#include <string.h>
#include <memory.h>
#include <memory>
#include <string>



#define MAX_TYPE_LEN (100)
typedef void *(func)(const std::shared_ptr<std::string> &);

class Base {
	public:
		Base(const char* type){
			 m_type = new char[MAX_TYPE_LEN];
			 strcat(m_type,type);
		}
		virtual ~Base() {
			if(m_type)
				delete m_type;
		}
		void set_type(const char* type){
			 memset(m_type,0,MAX_TYPE_LEN);
			 strcat(m_type,type);
		}
		char* get_type(){
			return m_type;
		}
	private:
		char *m_type;

};
class Sender;
class Receiver;
class Mediator {
	public:
		Mediator() = default;
		virtual ~Mediator(){}
		void set_inter(Sender * sender, Receiver * recv){
			m_sender = sender;
			m_recv = recv;
		}
		virtual void interaction() {
			std::cout << "interaction not implemented." << std::endl;
		}
	protected:
		Sender * m_sender;
		Receiver * m_recv;
};

class Sender : public Base {
	public:
		Sender(std::shared_ptr<std::string> & data, int len ,const char * type): Base(type) {
			m_data = data;
			m_len = len;
		}
		~Sender() = default;
		void set_mediator(Mediator * m){
			m_med = m;
		}
		void send() {
			if (m_med) m_med->interaction();
		}
		const std::shared_ptr<std::string> & get_data(){
			return m_data;
	   	}
	private:
		std::shared_ptr<std::string>  m_data;
		int m_len;
		Mediator * m_med;
};

class Receiver : public Base {
	public:
		Receiver(const char * type): Base(type) {}
		~Receiver()= default;
		void set_mediator(Mediator * m){
			m_med = m;
		}
		void set_recv_callback(func * f){
			m_fun = f;
		}
		std::shared_ptr<std::string> get_message(Base * b) {
          auto s  = dynamic_cast<Sender *>(b);
			if ( s != NULL)
				std::cout << this->get_type() <<  " got message from " << s->get_type() <<  std::endl;
				if (m_fun) (*m_fun)(s->get_data());
				else std::cout << "cb null" << std::endl;
			return 0;
	   	}

	private:
		Mediator * m_med;
		func *  m_fun ;
};


class ProtocolMediator: public Mediator{
	public:
		ProtocolMediator() = default;
		~ProtocolMediator() = default;
		void interaction() {
			if(m_sender && m_recv) {
				m_recv->get_message(m_sender);
			}
		}
	private:

};

void some_cbs(const std::shared_ptr<std::string> & data)
{
	std::cout <<"on yeah use_counts " << data.use_count() <<  std::endl;

	std::cout << "Got: " << *data << std::endl;
}

/*
 *sender通过mediator连接recver,sender->send最终调用了recv里注册的callback
 *sender和recver不直接打交道,而是通过meditor
 *meditor通过set_inter绑定不同的sender和recver,并且定义交互interaction
 *meditor 可实现 1对多 多对1 多对多 多种mapping方式
 */
int main(int argc , char* argv[])
{
	auto flag = std::make_shared<std::string>("bliblibliblablabla I love you");

	std::cout << "Mediator pattern mode" << std::endl;

	Sender * sender = new Sender(flag,1,"Girl");
	Receiver* recver = new Receiver("Boy");
	ProtocolMediator * meditor = new ProtocolMediator();

	sender->set_mediator(meditor);
	recver->set_mediator(meditor);

	recver->set_recv_callback((func*)(&some_cbs));

	meditor->set_inter(sender,recver);

	sender->send();
	return 0;
}

结果:

Mediator pattern mode
Boy got message from Girl
on yeah use_counts 2
Got: bliblibliblablabla I love you

Read More

访问者模式

一个处方单(Accepter),可能被不同的人(Visitor)拿去做不同的事,有的拿去划价,有的拿去拿药.

一个员工列表(Accepter),人力资源(Visitor)要统计考勤,财务部(Visitor)要结算工资…

所以访问者的场景还的真的挺多的.

2018-08-11-17-26-13

被访问者或者叫元素类提供一个方法 accept,接受所谓的访问者 visit,实际又是调用visit->visit(this).即把自己的信息给访问者,访问者再调用自己的某些方法。

这个某些方法是封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,才需要改变访问者来改变操作.

对 Element 来说,就是主人. 如果需要增加新的操作,就增加新的 Visitor,间接实现对 Element 的操作

核心就是来自 Element 的 accept 方法,间接把自己通过 this 给了 visitor,visitor 在 visit 方法里可以实现新的操作.

Element 对与 Visitor 是可控的,也就是只有 accept 的,才可以,其余的不可以.

void accept(Visitor* v) {
        v->visit(this); //执行访问者的动作,一般是this传入,也就是访问者来访时,是携带了自己的信息的
    }

比如:数据结构(Element)与数据操作(Visitor)的分离. 跟 stl 的思路还不太像的.

具体例子:

#include <iostream>

using namespace std;
//定义两种访问者,分别访问不同的元素

class Element;
class Visitor {
	public:
		//定义可能要访问哪些元素
		virtual void visit(Element * v) = 0;
		virtual ~Visitor(){}
};
class Element {
	public:
		virtual ~Element(){}
		//定义可能有哪些访问者来访
		virtual void accept(Visitor* v) {
			v->visit(this);}
		virtual void jobA() = 0;
		virtual void jobB() = 0;
		virtual void jobC() = 0;
		//这是模板模式,叫框架模式更好
		void job_process1() { jobA();jobB();jobC();}
		void job_process2() { jobC();jobB();jobA();}
};



/** @brief ElementA
 * 某个元素的具体类,
 * 有3个工作,但是不想直接调用.通过访问者来间接使用,这样改变访问者,也改变了功能
 * */
class ElementA :public Element {

	void jobA() {cout << __func__ << endl;}
	void jobB() {cout << __func__ << endl;}
	void jobC() {cout << __func__ << endl;}
};

class ElementB :public Element {

	void jobA() {cout << __func__ << "for ElementB\n" << endl;}
	void jobB() {cout << __func__ << "for ElementB\n" << endl;}
	void jobC() {cout << __func__ << "for ElementB\n" << endl;}
};


class VisitorA :public Visitor{
	void visit(Element* e) {
		e->job_process1();
	}
};

class VisitorB :public Visitor{
	void visit(Element* e) {
		e->job_process2();
	}
};

int main(int argc , char* argv[])
{
	Element* ea = new ElementA();
	Element* eb = new ElementB();
	Visitor* va = new VisitorA();
	Visitor* vb = new VisitorB();
	ea->accept(va); //实际调用了继承的job_process1,用访问者做了一层封装
	ea->accept(vb);

	eb->accept(va);
	eb->accept(vb);
	return 0;
}

结果:

jobA
jobB
jobC
jobC
jobB
jobA
jobAfor ElementB

jobBfor ElementB

jobCfor ElementB

jobCfor ElementB

jobBfor ElementB

jobAfor ElementB

Read More

观察者模式

直观的理解,就是发布-订阅模式.

Subject 对应 Publisher, Observer 对应 Subscriber.

但是其实发布-订阅只是观察者模式的一种特殊情况,它更强调的是:

一个对象或行为的变化导致其他对象状态的改变,或者通知其他对象的改变状态.他们之间将产生联动,一个对象的改动将影响其他对象.

2018-08-13-10-57-35

书中用了某成员被攻击, 同时通知其他所有成员的例子.这就是典型的对象联动.

//典型的订阅行为,有改变可以通过notifyAll通知所有订阅者
Subject::notifyAll() {

    for(auto i : this->members) {
        i->notify(this->status);
    }
}

//核心就是参数传进来的sub,实现对象联动
Observer::beAttacked(Subject * sub) {
    sub->notifyAll();
}

subject 可以添加 observer,反过来,用一个 observer 也应该可以添加不同的 subject.

MVC也是典型的观测者模式设计. 2018-08-13-11-22-29

用一个典型的文章订阅作为例子:

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <memory>
#include <set>
#include <list>

/**
 *
 *
 * 博客分不同主题,
 * 不同主题下有不同的订阅者.实现以下几个目标
 *
 * 1. 订阅者本身也是文章的发布者,可以发布一篇多个主题的文章;
 * 2. 当某个主题的文章更新时,通知所有相关订阅者有新的文章;
 * 3. 订阅者 也可以 订阅多个主题的文章.
 * 4. 订阅者可以关注其他订阅者, 当其他人发表新文章时,通知自己.
 *
 *
 * */



class Observer;
class Subject;

class Article {
	public:

		void setId(int id) {article_id = id;}
		int getId() {return article_id;}

		void setTitle(std::string t) {title = t;}
		const std::string & getTitle() {return title;}

		void setAuthor(std::shared_ptr<Observer> ob) {author = ob;}
		std::shared_ptr<Observer> getAuthor() {return author;}

		void addSubjects(std::shared_ptr<Subject> subject) {
			subjects.insert(subject);
		}
		std::set<std::shared_ptr<Subject>> getSubjects() {
			return subjects;
		}

	private:
		//id
		int article_id;
		//标题
		std::string title;
		// 作者
		std::shared_ptr<Observer> author;
		//文章可以属于多个不同主题
		std::set<std::shared_ptr<Subject>> subjects;
};

class Observer;
class Subject {
	public :
		Subject(const std::string & topic): m_topic(topic){}
		virtual ~Subject(){}
		void setTopic(const std::string &  topic){
			m_topic =  topic;
		}
		//通知订阅者消息
		virtual void notifyAll() {}
		//在主题下添加了新文章
		virtual void addArticle(std::shared_ptr<Article> art) {
			m_articles.insert(
					std::make_pair(art->getId(),art)
					);
		}
		//在主题下去掉文章
		virtual void removeArticle(std::shared_ptr<Article> art) {
			auto found = m_articles.find(art->getId());
			if (found != m_articles.end()) {
				m_articles.erase(found);
			}
		}
		void addSubscriber(const Observer & ob){
			m_obs.push_back(ob);
		}
		//void removeSubscriber(const Observer & ob){
			//m_obs.remove(ob);
		//}
		const std::string & getTopic() {return m_topic;}
		std::list<Observer> getObservers() {
			return m_obs;
		}
	private:
		//谁订阅了该主题
		std::list<Observer> m_obs;
		//什么主题
		std::string m_topic;
		//发表在该主题下的文章
		std::map<int, std::shared_ptr<Article>> m_articles;
};

class Observer {
	public:
		Observer(std::string name):m_name(name) {}
		virtual ~Observer(){}
		//收到通知
		virtual void notified(std::shared_ptr<Article> art) {
			std::cout << m_name << " got new articles:(" <<
				art->getTitle() << ")" << std::endl;
		}
		//个人订阅什么主题
		virtual void subsTopic(std::shared_ptr<Subject> sub) {
			sub->addSubscriber(*this);

		}
		//个人关注的其他人
		virtual void watchSomebody(const std::shared_ptr<Observer>  & ob) {
			//把关注对象保存
			watch_objs.push_back(*ob);

			//还要把自己添加到别人的bewatched list里
			//auto & f  =  ob->getFollowLists();
			//这两个就是不同的东西, 所以并没有改变ob的followers
			auto & f = ob->followers;
			//std::cout << & ob->followers << std::endl;
			//std::cout << &f << std::endl;
			f.push_back(
					//std::shared_ptr<Observer>(this)
					std::make_shared<Observer>(*this)
					//*this
					);
			std::cout << ob->getName() << " add followers:" <<
				this->getName() << std::endl;
			std::cout << f.size() << std::endl;
		}

		void setName(const std::string & name) {m_name = name;}
		const std::string & getName() {return m_name;}

		//个人被哪些人关注.
		std::list<std::shared_ptr<Observer>> followers;
		//个人关注的其他作者
		std::list<Observer> watch_objs;
	private:
		std::string m_name;
};

//一个write, 可以发布文章到主题上
class Writer : public Observer {
	public: Writer(std::string name) : Observer(name) {}
		void pubNewArticle(std::shared_ptr<Article> article) {
			std::cout << getName() << " published a new article." << std::endl;
			std::cout << "title:
			std::cout << "===============" <<std::endl;
			auto subjects = article->getSubjects();
			//遍历文章主题
			for (auto s : subjects) {
				auto obs = s->getObservers();
				//遍历主题下对应的订阅者
				for (auto o : obs) {
					//逐个通知
					o.notified(article);
				}
			}
			//遍历我的粉丝
			std::cout << "followers size:" << followers.size() << std::endl;
			if (followers.size()) {
				std::cout << getName() <<  " has followers.." << std::endl;
			}
			for (auto f: followers) {
				f->notified(article);
			}

		}

};

//一个reader,只订阅主题,
class Reader : public Observer {
	public:
		Reader(std::string name) : Observer(name) {}
};

int main(int argc , char* argv[])
{

	auto topic_adventure =  std::make_shared<Subject>("Adventure");
	auto topic_love =  std::make_shared<Subject>("Love story");
	auto topic_travel =  std::make_shared<Subject>("Travel");

	auto hans = std::make_shared<Writer>("Mr Hans");

	auto tommy = std::make_shared<Reader>("Mr Tommy");
	tommy->subsTopic(topic_adventure);

	auto derk = std::make_shared<Reader>("Mr Derk");
	derk->subsTopic(topic_adventure);

	auto handsome = std::make_shared<Writer>("Mr Handsome");
	handsome->subsTopic(topic_adventure);
	handsome->subsTopic(topic_love);

	auto zombie = std::make_shared<Reader>("Miss Zombie");
	zombie->subsTopic(topic_adventure);
	zombie->subsTopic(topic_love);

	//僵尸小姐关注了handsome先生, 无论handsome的什么主题的文章都感兴趣..
	zombie->watchSomebody(handsome);

	auto a = std::make_shared<Article>();
	a->setId(0);
	a->setTitle("Time travel to Mars");
	a->setAuthor(hans);
	a->addSubjects(topic_adventure);


	auto b = std::make_shared<Article>();
	b->setId(1);
	b->setTitle("A black hole in sky");
	b->setAuthor(hans);
	b->addSubjects(topic_adventure);

	hans->pubNewArticle(a);
	std::cout << std::endl;
	hans->pubNewArticle(b);

	auto c = std::make_shared<Article>();
	c->setId(1);
	c->setTitle("Senven days in Chengdu");
	c->setAuthor(handsome);
	c->addSubjects(topic_travel);

	std::cout << std::endl;
	handsome->pubNewArticle(c);

	return 0;
}

结果

Mr Handsome add followers:Miss Zombie
1
Mr Hans published a new article.
Title: Time travel to Mars
===============
Mr Tommy got new articles:(Time travel to Mars)
Mr Derk got new articles:(Time travel to Mars)
Mr Handsome got new articles:(Time travel to Mars)
Miss Zombie got new articles:(Time travel to Mars)
followers size:0

Mr Hans published a new article.
Title: A black hole in sky
===============
Mr Tommy got new articles:(A black hole in sky)
Mr Derk got new articles:(A black hole in sky)
Mr Handsome got new articles:(A black hole in sky)
Miss Zombie got new articles:(A black hole in sky)
followers size:0

Mr Handsome published a new article.
Title: Senven days in Chengdu
===============
followers size:1
Mr Handsome has followers..
Miss Zombie got new articles:(Senven days in Chengdu)

Read More