精华内容
下载资源
问答
  • Java多线程(一)

    千次阅读 多人点赞 2019-12-02 13:15:43
    目录 Java多线程(一) 前言 线程与进程 概念 并发 并行 进程 线程 多进程与多线程 ...之所以一上来就选多线程来讲,也有些考验自己的意思,毕竟多线程可是Java里扛把子的存在之一,算是与诸君共勉啦。 下一篇...

    Java多线程(一)

    前言

    自学Java也有几个月了,刚学也接触不到啥项目,每天敲代码输出实在是有点厌倦,偶然发现写博客也是种输出的好方式。第一次写博客,如果入得了各位看官们的眼,还请不吝点赞;如果有不足或谬误之处,希望各位看官们能够在评论区批评斧正。好了,废话不多说,接下来进入正文,免得各位看官们觉得笔者有拖笔之嫌。

    线程与进程

    概念

    在讲相关概念前,先引入并发和并行的概念。

    并发

    指多个事件在同一时间段交替发生。
    咱可以把这个时间段看成是一条线,每个事件都能在这条线上占有一段位置,但是一个事件不可能占有一整条线。也就是说这些事件是在同一时间段内“同时”发生的,但每个时间点上只有一个事件发生。用图描述如下:

    再来看看并行。

    并行

    指多个事件在同一个时间点同时发生。
    相当于是每个事件都占有相同的时间点,这可就是真正意义上地同时了。用图描述如下:
    在这里插入图片描述
    各位看官们清楚了并发和并行的概念后,接下来咱就来看看进程和线程。

    进程

    指一个程序从代码加载、运行到运行结束的一次动态执行的过程。

    线程

    在进程的基础上划分的更小的程序单元,是在进程的基础上建立并使用的。

    多进程与多线程

    相信各位看官们看了上述概念后,大概能明白进程与线程的关系,无非就是:进程是线程的容器。但跟并发和并行有啥子关系哟。还请各位看官们别急,看笔者娓娓分解。
    为了能够充分压榨CPU,人们捣鼓出了多进程,利用CPU的分时机制,每个进程都能抢占到一定的CPU时间,而CPU的处理速度是极快的,于是乎就给咱反应不过来的大脑造成了许多进程任务“同时”执行的假象,也就是咱上面提到的并发。
    后面人们发现,进程的启动和销毁需要浪费大量的系统性能,导致程序执行性能下降。为了提升并发处理的操作性能,进一步压榨CPU,人们又搞出了个多线程。
    因为线程足够“小”,所以启动速度和并发处理效果非常好,只要再加上够好的硬件设备,抗住千万级的并发访问也不是啥问题,想想双十一凌晨几千万的访问量,没把阿里服务器搞垮,咱多线程那可是功不可没的。
    至于并行,由于多个任务在同一时刻执行,所以依赖于多处理器系统,但大部分情况下有多个任务执行时间差距不大的并发处理就够用了,镭射炮自有镭射炮的用处。

    创建多线程

    看完笔者前面关于多线程的介绍,相信各位看官都对多线程有所心动,那接下来就让咱一起来创建个多线程。创建多线程的方式有三种,继承Thread类、实现Runnable接口、实现Callable接口,下面一 一讲解。

    继承Thread类

    Thread核心方法有两个:run()(这个run()是对资源描述的run()方法,暂且认为是Thread的方法,Runnable处再解释)和start(),其定义代码如下:

    public void run(){}
    public synchronized void start(){……}
    

    (synchronized同步先不用管,后续篇章会讲解)
    run()方法覆写后用于线程的具体操作,而start()方法用于启动线程。
    相信各位看官们早就等得火急火燎了,话不多说,代码如下:
    (这里就不用包了,下面代码也一样,太懒了……)

    class MyThread extends Thread{
    	private String name;
    	public MyThread(String name) {
    		this.name = name;
    	}
    	@Override
    	public void run() {
    		for(int x = 0; x < 3; x++) {
    			System.out.println(this.name + "执行" + x);
    		}
    	}
    }
    public class JavaThread{
    	public static void main(String[] args) {
    		new MyThread("线程一").start();
    		new MyThread("线程二").start();
    		new MyThread("线程三").start();
    	}
    }
    

    以下是随机抽取的一次运行结果:

    线程三执行0
    线程一执行0
    线程二执行0
    线程一执行1
    线程三执行1
    线程一执行2
    线程二执行1
    线程三执行2
    线程二执行2
    

    各位看官们也看到了,三个线程的执行都是看CPU心情,爱先执行谁就先执行谁,也就是随机执行(先不考虑优先级的问题)。但是相信有的看官也有疑惑:用start()方法启动最后不还是调用run()方法么,为啥还要用start()方法启动呢?看官别急,咱这就来好好探讨探讨这个问题。
    咱把start()方法换成run()方法,来看看运行结果:

    线程一执行0
    线程一执行1
    线程一执行2
    线程二执行0
    线程二执行1
    线程二执行2
    线程三执行0
    线程三执行1
    线程三执行2
    

    这就奇了怪了,咋就变成了顺序执行了呢?看官们别急,咱先打开API文档,找到Thread中的start()方法,发现里面有个start0()方法,这方法可不得了。
    咱知道Java为了保证其可移植性,就弄了个虚拟机(JVM)出来,程序都是在JVM上先运行的。但是多线程的操作是需要调用系统资源的,咋办呢?于是就有了start0()方法啦。start0()方法由JVM实现,然后调用本地系统函数进行资源调度操作。
    所以说start()方法起到了启动多线程的作用。
    还有咱先前提到的多线程并发操作带来的优势——效率高,总得拿出点证据来是吧,咱这就来试验试验到底有没有这回事。
    为了让效果更明显,咱把“x<3”改为“x<1000”,再在多线程启动操作前后获取时间戳,最后做差,代码如下:

    ……
    long start = System.currentTimeMillis();
    ……
    long end = System.currentTimeMillis();
    System.out.println(end - start + "ms");
    

    结果为1ms;
    再来看看没有用多线程,也就是用run()方法启动,结果如下:
    32ms(平均值)
    所以说啊,利用多线程进行并发处理的确是可以提高效率的。
    看完Thread后咱再来看看Runnable。

    实现Runnable接口

    咱先打开API文档,找到Runnable,其定义代码如下:

    @FunctionalInterface
    public interface Runnable{
    	public void run();
    }
    

    诶,看到这里相信各位看官们都会纳闷了,咋Runnable里也冒出了个run()方法呢?让咱打开API文档,找到Thread,其定义代码如下:

    public class Thread extends Object implements Runnable{……}
    

    哦,原来Thread是Runnable的子类啊,敢情Thread里面的run()方法原来是Runnable的呀。
    这时眼尖的看官就发现问题了,这Runnable里面咋没有start()方法呢,那多线程可该怎么启动?看官别急,咱再打开文档,找到Thread,发现里面有个构造方法可有趣了,其定义代码如下:

    public Thread(Runnable target){……}
    

    原来这Thread还能接收Runnable的子类啊,于是乎这Runnable的子类被这么一包装,也能调用start()方法来启动多线程了。
    说到这里,干脆把另外几个方法也给拎出来,其定义代码如下:

    public Thread(Runnable target, String name) {……}
    

    有了这个构造方法以后,咱就可以不用多此一举设定一个“name”属性了,直接利用这个构造方法在传入Runnable子类的时候就可以给线程命名啦;

    public final String getName()
    

    有了这个方法后,就可以取得线程名称啦;

    public static Thread currentThread(){……} 
    

    有了这个方法之后就可以取得线程对象啦。
    清楚了以上关系和方法后,咱再来看Runnable是怎样实现多线程的,代码如下:

    class MyThread implements Runnable{
    	@Override
    	public void run() {
    		for(int x = 0; x <3; x++) {
    			System.out.println(Thread.currentThread().getName() + "执行" + x);
    		}
    	}
    }
    public class JavaRunnable{
    	public static void main(String[] args) {
    		new Thread(new MyThread(), "线程一").start();
    		new Thread(new MyThread(), "线程二").start();
    		new Thread(new MyThread(), "线程三").start();
    	}
    }
    

    以下是随机抽取的一次运行结果:

    线程一执行0
    线程二执行0
    线程二执行1
    线程二执行2
    线程三执行0
    线程一执行1
    线程三执行1
    线程一执行2
    线程三执行2
    

    看完了Runnable之后咱再来看看Callable。

    实现Callable接口

    咱还是先打开API文档看看Callable,其定义如下:

    @FunctionalInterface
    public interface Callable<V>{
    	public V call() throws Exceptioin;
    }
    

    (泛型V的类型就是返回值的类型)
    一看这代码就有意思了,start()方法没有也就算了,连run()方法都没有,那还弄啥多线程哦。但咱也别过早下结论,先来看看API文档里是怎么描述的。
    咱先找到RunnableFuture接口,发现其一个父接口是Runnable,这没什么;咱再找到FutureTask类,发现其实现了RunnableFuture接口,这也没什么,关键是FutureTask类里面有个构造方法不得了了,代码如下:

    public FutureTask(Callable<V> callable){……}
    

    哦,原来是接收了Callable的子类对象啊。
    这样以来Callable也跟Runnable也算是沾亲带故了,这关系可真够复杂的……不管怎样,这下子Callable只需要通过FutureTask进行接收,剩下的流程就跟Runnable一样了。
    不过这Callable既然有返回值,咱就来看看如何获得这个返回值,打开文档,找到FutureTask,方法代码如下:

    public V get() throws InterruptedException, ExecutionException{……} 
    

    清楚了以上关系和方法后,咱一起来看看Callable是如何实现多线程的,代码如下:

    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    class MyThread implements Callable<String>{
    	@Override
    	public String call() throws Exception {
    		for(int x = 0; x<3; x++) {
    			System.out.println(Thread.currentThread().getName() + "执行" + x);
    		}
    		return Thread.currentThread().getName() + "执行完毕";
    	}
    }
    public class JavaCallable{
    	public static void main(String[] args) throws Exception{
    		FutureTask<String> taskA = new FutureTask<String>(new MyThread());
    		new Thread(taskA, "线程一").start();
    		new Thread(new FutureTask<String>(new MyThread()), "线程二").start();
    		System.out.println(taskA.get());       //获取线程taskA的返回值
    	}
    }
    

    随机抽取一次运行结果如下:

    线程二执行0
    线程一执行0
    线程二执行1
    线程二执行2
    线程一执行1
    线程一执行2
    线程一执行完毕
    

    总结

    看完以上三种实现多线程的方法后,相信看官们早就一肚子的疑问了,既然上面三种方式都可以实现多线程,那为什么要搞这么多花样呢?实现方式这么多,实际开发中该怎么选取呢……各位看官别急,笔者这就为看官们解惑。

    实现多线程为什么要弄这么多的花样呢

    咱知道,Thread中的start()作为启动方法是必不可少的啦,而Thread和Runnable的子类都可以利用run()方法进行资源描述,但run()方法可是有个致命缺陷的呢,相信心细的看官早已发现,那就是——run()方法是没有返回值的。有时候就是需要线程中有返回值咋办呢?于是Callable就诞生啦,利用FutureTask中的get()方法就能够获取线程的返回值。
    但是Thread之后为什么还要弄个Runnable呢?因为Thread类只能够单继承,而Runnable接口可以克服单继承的局限性。

    实际开发中如何选择实现方式

    清楚了三种方式产生的实际背景后,就不难选择了。利用Runnable或Callable的子类进行资源的描述,然后利用Thread中的start()方法进行线程的启动。
    以买票的为例,代码如下所示:
    (暂时不管同步问题)

    class MyThread implements Runnable{
    	private int ticket = 5;
    	@Override
    	public void run() {
    		for(int x = 0; x<1000; x++) {
    			if(ticket > 0)
    				System.out.println(Thread.currentThread().getName() + "买票,剩余票数:" + --this.ticket);
    		}
    	}
    }
    public class JavaDemo{
    	public static void main(String[] args) {
    		Runnable source = new MyThread();        //资源类
    		new Thread(source, "线程一").start();
    		new Thread(source, "线程二").start();
    		new Thread(source, "线程三").start();
    	}
    }
    

    随机抽取一次运行结果如所示:

    线程一买票,剩余票数:3
    线程三买票,剩余票数:2
    线程三买票,剩余票数:0
    线程二买票,剩余票数:4
    线程一买票,剩余票数:1
    

    这时有些天马行空的看官就会想了,能不能用Thread的子类来进行资源的描述呢?
    从可行性来讲,当然是可以的啦。用Thread的子类来进行资源的描述也是可以创建多线程的,效果是一样的。但笔者委实不推荐这种方式,因为这种方式不太合理。Thread的子类进行资源的描述,则这个资源类本身就是一个线程对象,然后又用其它线程来启动这个线程对象,实在是不合理。
    所以啊,以后创建多线程的时候就用Runnable(Callable)的子类进行资源的描述,再用Thread中的start()方法来启动线程。

    后记

    感谢各位看官能看到最后,第一次写博客实在是忐忑。
    笔者专业是信息安全,学Java难免被人说不伦不类,但还是想多尝试尝试,趁年轻多走走。之所以一上来就选多线程来讲,也有些考验自己的意思,毕竟多线程可是Java里扛把子的存在之一,算是与诸君共勉啦。
    下一篇多线程(二)应该会在下周三推出。大一除了课程多一点以外,时间还算充裕,但总是有各种各样的突发事件打断既定安排,着实无奈,笔者也希望能够养成写博客的习惯。
    再次感谢各位看官们能够看到最后,下周见啦。

    展开全文
  • 而面试的内容大概就是问问你学过什么计算机专业课,然后问计算机专业课的一些基础知识,导师的意思是找到优秀的同学,同时剔除完全没有代码能力的人。(其实跟宣讲会那个面试差不多,也就是常规的银行面试套路,喜欢...

    已offer
    中信银行总行信息科技部今年在成都设立研发中心,而且今年总部也在扩招,听说一共招1000+(宣讲会说的),其中成都这边招400+,目前来看,估计今年比较好进
    ·········································分割线···············································
    2020.01.17更新:
    看群里HR说的,估计真的会招1000个人,因为第一批北京+成都实习的,HR说一共发了500封左右的签约邮件。后面还有几批实习签约的,估计没有一千也有七八百?
    2020.04.15更新:(以下内容全部来自脉脉查询)
    关于薪资,在脉脉上看了一下,总包应该会给到,年终奖会发12个月及以上。
    关于职级,校招统一定级T1(社招也是T1,但是校招和社招是两条线,没可比性),半年试用期+2年锁定期,再过半年开始第一次晋升期(第一次晋升基本都能从T1升到T2,也就是说校招最快三年可以升级到T2),之后每半年一次晋升的机会,听说T6属于高级职位,一般来讲T6之前升级都比较好升

    一、 校招时间线

    1. 网申(10月25截止)+ 行测
    2. 宣讲会+提前批面试 10月14日
    3. 笔试(11月7日)
    4. 邮件通知实习(11月28日),正式批的同学大概也是这两天发的面试通知。
    5. 实习(2019年12月2日-12月5日(原计划3天,改成了4天)),成都场第一批实习,实习会刷人,实习过程中和实习导师进行了一个简单的面谈,最后一天有一个4对1的专业面试,后面还会有一个现场的HR面谈。
    6. 发二次面谈邮件(12月6日),需要的资料是真的多,,,,
    7. 二次面谈(12月7日)
    8. 体检:12月20日 发52人体检邮件,共500人左右会收到体检通知,分批发送(不知道是不是按照实习的批次发送的),可能持续两周之久,本人体检(12月23日已通知)
    9. 背调(12月23日已通知)
    10. 签约,可以签两方:2020年1月9日邮件通知签约时间,北京10号签约会,成都11号签约会。

    附:2019校招时间线
    10月18日 笔试,
    两周后发面试邮件,
    11月21日 现场面试,
    11月22日 发体检背调邮件,
    12月14日 发邮件offer,
    12月19日 签约会
    实习(持续两到三周)

    注:去年和今年的流程有些不同,今年增加了提前批预面试(宣讲会面试),没有参加宣讲会面试的同学则是按照正常笔试面试实习的流程进行(流程会慢一些),并且今年实习日期也减少到了3天,可能是因为扩招,人太多的原因。并且今年是先实习再签约,而邮件中也说了,实习可能会刷人。(也有一种说法是,去年有两种流程,一种是笔试成绩高,直接签约,签约后再实习,另一种是笔试成绩不高,所以先实习,实习通过再签约)

    二、 笔试

    11月7日,线上笔试形式,题型:英语,行测,计算机知识(就是银行信息科技岗笔试常见题型),据说笔试会刷人,想来中信的,手里没offer的,还是刷刷题,认真准备一下。

    三、 面试

    1. 10月14日,电子科技大学,宣讲会后现场面试(因为四川场只有电子科技大学和四川大学,所以面试的时候有成电的,交大的,西华的等等),将近200号人(根据宣讲会签到的先后顺序领取面试号码),面试分为两部分,一面技术面,二面HR面。可能因为人数太多的原因,面试很水,一面和二面基本都是三分钟,自我介绍30秒左右,超过了会被打断,一面面试官按照简历问,因为我是做算法的,项目也写的是算法的项目,然而面试官没有问,打断我的自我介绍直接问SQL,数据结构与算法(我简历里简单写了一下),根据现场询问其他小伙伴,数据结构与算法必问,其他的还是按照简历来问(开发相关的)。一面会进行打分(1,2,3,4,5),低于3分的不能进入二面,我被打了3分(没有开发项目,而且问的问题回答的一般),侥幸进入二面,马上就去另一个教室门口等二面,二面也是进去大概30秒自我介绍,然后被打断,问我四六级成绩,想去北京还是成都,为什么想留成都(我不是四川人),奖学金情况,成绩排名情况,问我专业问题(我是非科班的),看我是做算法的,问我会不会java,说这边是要做开发的。然后结束。听说二面也有一个打分,但是我没看到,不知道是不是确实有。最后面试官问我有没有网申,测评有没有做,让我等着参加笔试。
    2. 没有进行宣讲会预面试的则是顺延到了正式批,所以实习的日期应该也会更慢一些。

    四、 实习

    实习是在下周,目前还没有开始,北京第一批实习的同学们在28日已经开始了第一天的工作(人数太多,实习每批次进行,通知邮件也是分批次的,)。实习的大概内容就是第一天HR会把这一批实习的人分到不同的部门(这个部门大概率就是你以后入职的部门),然后拉入不同的微信群,有些部门划分了5个人,有些则划分了20个人,期间如果觉得自己不适合这个部门,可以申请调换。
    实习内容的话,应该是做一些简单的工作,然后做汇报。
    实习要求自备笔记本电脑,据说实习的最后一天还会有一次面试。
    目前**中信银行总行信息科技部有两个研发中心,一个北京,一个成都,**目前两个地点的第一批实习通知应该已经发送完毕,看样子是按照就近原则,北京的发了北京高校的学生,成都的发了成都高校的学生。路费,住宿费都要自己掏腰包,不管饭。。。(北京那边管饭)。北京那边有两个实习地点,成都这边则是在中信银行四川分行,成都研发中心地点在兴隆湖,可能还没有建好。
    今年的实习可能一直会持续到12月下旬(估计每次实习人数也就100人左右?)
    后续实习情况等实习完毕再更新。。。。。。。
    ·········································分割线···············································
    12.02更新:
    今天实习第一天,地点在中信银行四川分行,第一批成都实习一共180人左右,被分为了8个小组,每组十几个人(应该有一些人放弃了实习,实际来了125人,中午还走了一些人,估计今晚还会有一些人放弃,,,一群人在一个会议室敲代码,讨论项目,感觉很闷热,没有wifi,需要自己手机开热点,讲道理,实习体验有点点差)。一个老师带两组成员,每组的题目都是一样的,每组合作完成这个题目。和北京那边有些不同,这边没有分科室,就是分了几组人员,老师是北京那边调过来的。
    实习的同学去了之后没有工位,大家都挤在一个会议室里,HR看人太多了,后面分成了三个会议室,实习时间由3天改为4天(这4天都要在这个会议室度过。)
    实习日期: 12.02——12.05,上午9点到12点,下午1点到5点半。最后一天需要小组答辩展示成果,这个实习就类似于软件工程实验课吧。。。
    在这里插入图片描述
    在这里插入图片描述

    上午: 主要是分了一下组,简单的介绍了一下实习,题目:某银行自营或代销某产品,半开放式题目,具体题目自拟,做出一套系统。可加入一些自己的特色内容。目的是考察大家的合作能力,项目能力,以及了解一下银行在这方面的业务知识。分组后小组讨论题目。

    中午: 实习地点在高新区,出门就是奥克斯商场,负一楼有很多吃的,但是人也很多,需要排队。

    下午: 导师补充说明:因为这次实习大部分小组都使用的java+sql,对于不会这两种语言的同学来说,不必担心,可以写一些文档类或者资料搜集类的工作,答辩的时候我们看的是综合能力,以及小组整体的完成度,不是只看代码能力。我们中信银行不只有开发岗,也有一些其他的岗位,看各位的岗位匹配度。
    导师介绍成都研发中心的情况:地点在兴隆湖,2019年12月23日开始运营,组织了一些社招人员,并且从某地调来了一些中信的员工(没听清是哪里调来的),今年第一批校招,往年招的很少,对于大家来说可能是一次机遇。

    小记: 导师上午说的是原计划5天的实习内容,后来听说邮件通知的是3天,所以说时间会比较紧,任务之前安排的是5天的,后面他们又商量了一下,改为了4天,第四天下午答辩。在周五或者周末会有HR进行一次两三分钟的面谈(类似于一次HR面吧,估计是聊聊这次实习的收获)。在我看来,这次成都的实习,其实就相当于一个软件工程实验课,只是周期由一学期改成了4天,小组成员由几位变成了十几位。类似于那种马拉松编程大赛,24小时编程大赛之类的,个人感觉目的是让实习整个系统开发流程,了解银行理财购买系统的相关知识,团结合作能力,创新能力等,4天时间,应该不会主要考察代码能力,大家应该都是在现有开源代码中进行修改加以利用。

    ·········································分割线···············································
    12.3更新:
    上午: 每组出两位成员去进行一个简单的答辩,讲一下自己的项目思路,设计思路,技术使用等。由导师指导一下,看看是否偏题,是否能按期完成等。
    课余活动: 12.3日午休时间,搜集资料,任务:宣传自己的队伍,设计logo,队名,口号,做PPT,介绍每一位成员和各自特点等。12.4日中午午休时间答辩
    其他没什么说的了。

    ·········································分割线···············································
    12.4更新:
    上午: 早上签到后去导师那补充信息:本科学校,本科专业,代码量,学没学过计算机基础课等。
    明天答辩形式: 每组半小时,PPT的形式,组内生成的各种代码,需求文档,设计文档,测试文档等所有文件统一发送给老师。
    中午: 13:30的时候有一个小组宣传活动的答辩,一共8个组,每个组以PPT的形式进行展示,前两组太过牛批,当然了,只是展示了一下,老师们也没说什么,就结束了。
    下午: 每个人找导师面谈几分钟,问你在这次实习中负责哪部分,然后问一个相关部分的很基础的问题;对996的看法愿不愿意做开发,问了手中offer的情况,简单介绍中信在成都新成立的研发中心的情况(据老师说,今年招聘可能较去年严格一些,可能会考察代码能力)。下午快下班的时候,有一位老师拿着一张打印的名单叫人去面试(每组人员中,在这份表单上的人,随便去4个)。去的同学回来后表示,这是一次多对1的技术面,没有自我介绍,上来就是问技术问题(数据库,java,数据结构与算法相关)。因为名单上也就几十个人,猜测是统计了非计算机专业的人员, 然后组织一个简单的面试,问问计算机基础情况。明天其他人应该陆陆续续会去面试。
    晚上: 群里老师通知带一份简历,实习这几天自己做的东西以及成果写成一段话上交。(估计明天又要面试了,,)
    注: 据老师讲,成都新成立的研发中心是北京研发中心那边的某一两个处+其他处的一些员工,搬迁到成都这边,又组织了一批社招人员。 成都这边预计会拆分成五个处/科室,做分行的一些业务,还有其他的任务,后续根据总部的安排进行扩充,目前成都这边只有开发岗,没有其他岗位,后续可能会招聘(所以会问愿不愿意做开发,可能有些同学想做算法,有些想做产品之类的)。

    ·········································分割线···············································
    12.5更新:
    上午: 导师陆续叫名单上的人去面试(4对1,专业面试),名单上大概有四五十人?,原以为是统计了非计算机专业的同学,后面得知,有些计算机专业的同学也进行了面试,而导师在实习结束后说只是随机抽取了几十位同学进行了面试。而面试的内容大概就是问问你学过什么计算机专业课,然后问计算机专业课的一些基础知识,导师的意思是找到优秀的同学,同时剔除完全没有代码能力的人。(其实跟宣讲会那个面试差不多,也就是常规的银行面试套路,喜欢问计算机专业基础课)
    下午: 抽出了一两位导师继续面试,剩下的导师参与实习答辩,下午两点开始,一直持续到下午六点,共8组,预计每组30分钟(20分钟PPT讲解+项目展示,10分钟提问),最终参与实习答辩的导师应该是6位。答辩重点: 需求分析,银行业务了解,业务逻辑,前端页面展示,没有看具体代码。后续导师针对展示的页面与系统进行简单的提问。下午6点,导师宣布实习结束,在下周末之前会有一次现场HR面谈
    小记: 通过网上的了解,结合此次实习的体验,基本可以验证两个点,第一,中信内部会有加班时长排名,第二,每个月会有代码量的要求作为绩效考核的一项标准,第三,没有加班费,加班长短看科室,但是995我觉得没跑,甚至996。

    五、 二次面谈

    5号下午6点实习结束,6号晚上发了二次面谈邮件,7号现场面谈,需要准备的资料非常多,像是一次背调。去了现场之后按照签到顺序叫号依次面谈,面谈形式1对1,旁边有一位工作人员进行信息录入。面试官应该是HR,问的问题基本和宣讲会之后的二面一样:自我介绍,想留哪个地区,为什么想留这个地区,能不能接受996,为什么想来中信,拿了哪些offer,还有三方吗等等,就是基本问题,照实回答就可以。然后就结束了。最后说了一句:回去等通知吧。

    小记:此次实习应该是刷了一些人(有些人没有被通知过来二次面谈),但是应该刷的人应该很少, 银行面试不同于互联网纯看技术,有很多不确定性因素,可能你的表现力,你的态度,也是一个考核的点。另外二次面谈不知道刷不刷人,接着等通知吧。

    六、 建议

    1. 简历与自我介绍:

    简单说一下,给明年准备签银行的小伙伴们一些建议,银行还是比较看重学校和专业的,相比之下,更看重专业,也就是计算机专业的,如果你不是计算机专业的,但是你所在的学院和计算机专业有相关点,那么在你的简历中一定要标清楚你的学院;如果你研究生的研究方向也是计算机相关的,那么你也要在简历中突出;另外如果本科课程中有学过计算机相关基础课的,也要在简历中标明。

    除了上面要在简历中标明的东西外,自我介绍中也要重点体现,可能你那些和银行不匹配的项目,在面试官那里还不如计算机基础课入耳。如果专业和计算机无关,那么建议提前一两个月学一学(去银行信科岗,,起码要会一点SQL,数据结构,一门语言吧,这些提前学一学,写到简历中,自我介绍时重点说一下)。

    还有就是四六级和奖学金,这是HR比较看重的点

    2. 技术积累:

    银行最看重的技术是java和SQL。其次是数据结构
    刷一下银行信科的笔试题。

    3. 宝洁八大问:

    类似这种问题,自己想想怎么回答,不需要背别人的答案,根据自己的性格和特点,自己总结一下。
    还有就是必问问题:
    为什么想来银行?
    为什么想来我们银行?
    我们银行和XX银行的区别?
    你怎样看待私企与国企?

    七、 签约

    可以两方入职
    北京户口的话中信肯定不稳,今年又扩招,更不稳了。当然我报的成都岗,不需要户口。。。
    ·········································分割线···············································
    12.14更新:
    实习群内工作人员说目前成都第一批实习通过的签报名单已经于12月12日递交给总部了,各位同学的资料审核通过并且领导签批通过后会邮件通知后续的签约和体检。个人估计12月底或者下月初。(不知道是先体检还是先签约,工作人员没说,反正这个时间节点肯定会有结果,体检or签约,收到后续邮件之后,后面应该就不会刷人了)。
    另外,工作人员说这次面谈的人员中,可能还会刷人。

    ·········································分割线···············································
    12.20更新:
    实习群内人资说体检已经发了52个人,分批发送,一共500人左右,有可能持续两周之久。

    ·········································分割线···············································
    12.23更新:
    收到背调邮件+短信,群内人资说今天和明天大概会发400封体检和背调的邮件,目前收到了背调邮件,等待明天的体检邮件。
    随后收到了体检短信,免费体检,自行预约时间。

    ·········································分割线···············································
    2020.01.09更新:
    2020年1月9日邮件通知签约时间,北京10号签约会,成都11号签约会。

    ·········································分割线···············································
    2020.01.11更新:
    成都地区现场签约会:
    以下内容均为HR所说,括号中内容为博主补充。

    1. 可签两方走改派入职;
    2. 六险三金:企业年金,补充医疗保险,终身重疾险,(说以后生大病基本不用花钱了)
    3. 公积金: 第一年正常缴纳,以后按照上一年的总收入(总月薪+年终)*12%的比例来缴纳
    4. 试用期六个月,理论上无年终奖
    5. 第一次签约4年,第二次3年,第三次签3年或者签“终身”合同。(或者是第四次签“终身”合同)
    6. **两年锁定期:**实习期结束后,还有两年的锁定期,这两年不会晋升
    7. 快速成长期:锁定期结束后,每年两次晋升的机会。(看脉脉上说每次晋升可以涨4,5W的年薪)
    8. 定级T1,硕士研究生好像都是一样的,HR说本科和硕士薪资差不多;社招一般定级也是T1,但是社招和校招是两条不同的线
    9. 996:HR说封顶996,说目前经济不景气,而且公司正在转型,加班是必然。HR自称已经一年没有过过周六了。周六的话一般九点十点来上班,下午三四点就下班了。
    10. 上班时间早晨8点半,11点半下班,下午1点半上班,5点半下班。(网上很多人说每周124八点半下班,周356正常下班,其中周三是健身日,周五是家庭日。)
    11. 上班地点,兴隆湖这边的一个科创中心租了几层,未来两三年要搬到附近其他的楼(说要自己买一栋楼)
    12. 与总行签约,总行编制
    13. 福利部分: 饭补(据说每个月1400),交通补,话费补(据说交通补和话费补已经没了),过节费(估计几千块),高温费(HR说只有北京有,成都没有);还有一些隐形福利,包括购物卡,电影票等非现金;没有房补,国家不允许发房补了
    14. 薪资: 试用期税前7000-8000,转正后,年终占年薪将近50%,具体薪资,HR说是机密,不能说,打了个比方:去中南大学/东南大学校招的某石油企业,给本科开10W,硕士15W,博士20W,去非洲的话25W,然后说在中信的薪资是肯定比这个企业开出最高档的薪资要高的。(不知道加没加福利补贴,我猜肯定是加了的);年终奖一般人都能拿到将近年薪的50%,也就是将近12个月的月薪(这句话是HR说的,不知道是不是画饼)
    15. 违约金:2W
    16. 理论上是3月1号之前都可以签约,因为三月份就要开始启动春招了。但是后面的情况说不准,最好是尽快签约。
    17. 有两周的入职培训
    18. 专业培训:入职后有很多培训可以参加和学习
    19. 优选计划:(具体名字记不清了),从校招生里选出大概10%的优秀应届生,去省分行或其他机构进行学习之类的。

    博主补充说明:
    20. 1月10号是北京的签约会,不管是交流群里还是牛客还是offershow,都有人说了薪资,说北京签约会,透露出的薪资是本科26W起,不包含福利补贴,硕士比本科要高一点; 成都薪资是北京的85折(按照这个说法的话,成都就是22W起)
    21. 如果真如HR所说的,一般人都能拿到12个月的年终的话,这个成都22W的年薪感觉还是比较可靠的,但是福利补贴肯定是缩水了的,听说有些福利已经没了,也有人说以其他形式进行补发了的。
    22. 毕竟两万块钱的违约金,签了肯定就是要去的,所以博主也还没签,趁着这个周末,好好思考一下,还是蛮心动的。

    ·········································分割线···············································
    2020.01.12更新:
    因为我是成都地区的,北京那边的签约会不太了解,成都这边HR简单说了一下关于去北京的问题,主要就是户口。
    中信这边每年的户口指标不是很多,而且今年又扩招,所以只能给一部分人京户:
    第一,签三方的,两方同学应该是没戏;HR说大概每年四月份左右会出来今年的户口指标,到时候拿着各位的 三方协议 去给各位办理北京户口(听说必须拿三方协议才能办户口,而不是中信要求的),然后HR的意思是,在这之前只要和我们签三方的同学都有可能拿到京户
    第二,排名靠前的,实习的时候听说有个打分,然后出一个排名。

    八、 加班与薪资情况(道听途说)

    offershow和脉脉上可查,
    北京那边校招税前20W+5W福利补贴,平时与年终各一半(绩效A应该可以拿更多) 。 (我觉得薪资依然是个谜,北京25W是网上查到比较可靠的,也有说其他的,并且说今年要降薪,,搞不懂,如果有了解的,欢迎留言补充)。如果成都也是这个薪资的话,那么在成都这边的银行中,还是很有竞争力的。
    中信据说有代码量考核,每个月要完成多少行的代码量,作为绩效考评。
    听说北京那边社招的有申请转到成都的,然后降薪了,北京的员工转到成都,薪资打85折(5W的福利不打折,但是福利不清楚都有什么,竟然有5W,,,不知道包不包含企业缴纳的五险一金),所以不清楚,校招的话成都这边会不会打折。。如果打折的话感觉性价比不高了。
    据说995 996是日常,忙的时候可能9106,项目上线的时候可能要通宵?每周124,早晨8点半上班,晚上8点半下班。周35一般正常点下班。(都是道听途说,无法考证)
    成都这边工作地点应该就是兴隆湖,属于天府新区,成都市重点发展区域,但是。。。那边现在很荒凉,而且很远,,从兴隆湖到春熙路/天府广场的话坐地铁估计要一个小时吧。

    九、 个人感受

    在校招开始前打算去银行,所以有过还算深入的了解,银行软开的话,只看这些比较大型的银行中的总行信息科技部,中信银行可能是加班最多也是工资最高的,银行软开这边基本就是加班多的钱就多,加班少的钱就少。面试的话,有了解过去年的,也是相对比较简单,今年面试也是如此(不知道实习难不难),而且今年又扩招,所以从发展上来讲,也不能有一个确定的感受,不清楚这次扩招是不是一个机遇。

    十、 相关截图

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • 啥?看冬至这天的天气就能预测出过年时候是晴是雨?这也太怪了,天气预报也不能提前预报这么多天啊,这个事到底准还是不准呢?...我们且不说这句俗语准不准,先来看看说的是什么意思吧。阴过冬至晴...

    啥?看冬至这天的天气就能预测出过年时候是晴是雨?这也太怪了,天气预报也不能提前预报这么多天啊,这个事到底准还是不准呢?

    不知大家有没有听说“阴过冬至晴过年,一年雨水看冬至”这句民谚,过去农民们可没有天气预报来预测天气情况,靠的就是这些老俗语。其实讲真的,现在由于气候变化莫测,很多过去的老话在现在都没有那么精准了,当然在过去还是挺有准头的。我们且不说这句俗语准不准,先来看看说的是什么意思吧。

    aea7d9bdbba8c103edf3ceb609f3d971.png

    阴过冬至晴过年。意思就是说冬至这一天如果是阴天,或者是大雪天气,那么五十多天后的春节将会是晴天,大家出门拜年不会盯着大风雪了。下周也就是12月21日就是冬至了,天气预报显示那天阴天,从这一点来看,根据老话我们可以大胆的预测出,今年过年的时候应该会是个大晴天。

    不过冬至时到底天还会不会放晴,是不是阴天,我们还得到下周看,可以好好记一下,冬至时到底有没有阴天,然后对比过年时的天气,看看老话还靠谱不。

    45fcb95493744d3d7bc45ca258ed52c6.png

    一年雨水看冬至,这个乍一看就让人有些懵了,冬至应该是下雪的日子,在冰天雪地的日子里,怎么会跟这一年的雨水多少有关系呢?其实这是农民们根据多年的经验总结出来的,通过冬至时的降水情况来推断明年的雨水多少,是旱年还是雨水丰沛。如果冬至节气当天降雨,当然冬季北方一般到冬至时都是降雪了,那来年雨水就会比较充足;而如果冬至节气当天是晴天,没有任何雨雪降下,那么来年的雨水可能就会比较少了,农民们也要提前做好防旱准备。

    从如今的降雪情况来看,今年冬天的降雪量肯定是比去年要多了,大烟台的“雪窝”称号又回来了,前天周天下了一场大暴雪,差点让城市交通都瘫痪了,如今为了环境保护也都尽量不撒融雪剂,所以冰雪的融化就会比较慢,路上积雪不少。

    e52074e27a12a8b4186aadc9aec69261.png

    相比较去年来看,今年的庄稼应该可以“盖着雪被子过冬”了,气温也比较低,接下来冬至过后,气温应该是越来越低的,而且降雪量也会随之增多。虽然大雪过后,上班的人们又要堵在路上了,不过想想冷冬的好处,我认为还是值得的。

    冬天就应该有个冬天的样子,进入冬至开始数九,那么就应该有冻得“伸不出手”和“冰上走”的日子,天天艳阳高照气温较高,恐怕病毒还要肆虐,谁都不希望去年过年时的疫情重演。希望今年一切都好,至于2021年春节是晴还是阴,没那么重要,只要是个健康年就好。

    展开全文
  • 什么是 Docker ?

    2020-02-14 17:33:20
    3、什么是docker   docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。 docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux...

    一、简介

    1、了解Docker的前生LXC

     

    LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。相当于C++中的NameSpace。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。

     

    与传统虚拟化技术相比,它的优势在于:

     

    (1)与宿主机使用同一个内核,性能损耗小;

    (2)不需要指令级模拟;

    (3)不需要即时(Just-in-time)编译;

    (4)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;

    (5)避免了准虚拟化和系统调用替换中的复杂性;

    (6)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。

    总结:Linux Container是一种轻量级的虚拟化的手段。

     

    Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。

     

    2、LXC与docker什么关系?

     

    docker并不是LXC替代品,docker底层使用了LXC来实现,LXC将linux进程沙盒化,使得进程之间相互隔离,并且能够课哦内阁制各进程的资源分配。

    在LXC的基础之上,docker提供了一系列更强大的功能。

     

    3、什么是docker

     

    docker是一个开源的应用容器引擎,基于go语言开发并遵循了apache2.0协议开源。

    docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux服务器,也可以实现虚拟化。

    容器是完全使用沙箱机制,相互之间不会有任何接口(类iphone的app),并且容器开销极其低。

     

    4、docker官方文档

     

    https://docs.docker.com/

     

    5、为什么docker越来越受欢迎

     

    官方话语:

     

    • 容器化越来越受欢迎,因为容器是:

     

      • 灵活:即使是最复杂的应用也可以集装箱化。

      • 轻量级:容器利用并共享主机内核。

      • 可互换:您可以即时部署更新和升级。

      • 便携式:您可以在本地构建,部署到云,并在任何地方运行。

      • 可扩展:您可以增加并自动分发容器副本。

      • 可堆叠:您可以垂直和即时堆叠服务。

     

    • 镜像和容器(contalners)

     

    通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括运行应用程序所需要的所有内容包含代码,运行时间,库、环境变量、和配置文件。

    容器是镜像的运行实例,当被运行时有镜像状态和用户进程,可以使用docker ps 查看。

     

    • 容器和虚拟机

     

    容器时在linux上本机运行,并与其他容器共享主机的内核,它运行的一个独立的进程,不占用其他任何可执行文件的内存,非常轻量。

     

    虚拟机运行的是一个完成的操作系统,通过虚拟机管理程序对主机资源进行虚拟访问,相比之下需要的资源更多。

     

     

    6、docker版本

     

    Docker Community Edition(CE)社区版

    Enterprise Edition(EE) 商业版

     

    7、docker和openstack的几项对比

     

     

    8、容器在内核中支持2种重要技术

     

    docker本质就是宿主机的一个进程,docker是通过namespace实现资源隔离,通过cgroup实现资源限制,通过写时复制技术(copy-on-write)实现了高效的文件操作(类似虚拟机的磁盘比如分配500g并不是实际占用物理磁盘500g)

     

    1)namespaces 名称空间

     

     

     2)control Group 控制组

     

    cgroup的特点是:      

    • cgroup的api以一个伪文件系统的实现方式,用户的程序可以通过文件系统实现cgroup的组件管理

    • cgroup的组件管理操作单元可以细粒度到线程级别,另外用户可以创建和销毁cgroup,从而实现资源载分配和再利用

    • 所有资源管理的功能都以子系统的方式实现,接口统一子任务创建之初与其父任务处于同一个cgroup的控制组

     

    四大功能:

     

    • 资源限制:可以对任务使用的资源总额进行限制

    • 优先级分配:通过分配的cpu时间片数量以及磁盘IO带宽大小,实际上相当于控制了任务运行优先级

    • 资源统计:可以统计系统的资源使用量,如cpu时长,内存用量等

    • 任务控制:cgroup可以对任务执行挂起、恢复等操作

     

    9、了解docker三个重要概念

     

    1)image镜像

     

    docker镜像就是一个只读模板,比如,一个镜像可以包含一个完整的centos,里面仅安装apache或用户的其他应用,镜像可以用来创建docker容器,另外docker提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下周一个已经做好的镜像来直接使用

     

    2)container容器

     

    docker利用容器来运行应用,容器是从镜像创建的运行实例,它可以被启动,开始、停止、删除、每个容器都是互相隔离的,保证安全的平台,可以吧容器看做是要给简易版的linux环境(包括root用户权限、镜像空间、用户空间和网络空间等)和运行再其中的应用程序

     

    3)repostory仓库

     

    仓库是集中存储镜像文件的沧桑,registry是仓库主从服务器,实际上参考注册服务器上存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)

     

    仓库分为两种,公有参考,和私有仓库,最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下周,国内的docker pool,这里仓库的概念与Git类似,registry可以理解为github这样的托管服务。

     

    10、docker的主要用途

     

    官方就是Bulid 、ship、run any app/any where,编译、装载、运行、任何app/在任意地放都能运行。

    就是实现了应用的封装、部署、运行的生命周期管理只要在glibc的环境下,都可以运行。

    运维生成环境中:docker化。

     

    • 发布服务不用担心服务器的运行环境,所有的服务器都是自动分配docker,自动部署,自动安装,自动运行

    • 再不用担心其他服务引擎的磁盘问题,cpu问题,系统问题了

    • 资源利用更出色

    • 自动迁移,可以制作镜像,迁移使用自定义的镜像即可迁移,不会出现什么问题

    • 管理更加方便了

     

    11、docker改变了什么

     

    • 面向产品:产品交付

    • 面向开发:简化环境配置

    • 面向测试:多版本测试

    • 面向运维:环境一致性

    • 面向架构:自动化扩容(微服务)

     

    二、docker架构

    1、总体架构

     

     

    • distribution 负责与docker registry交互,上传洗澡镜像以及v2 registry 有关的源数据

    • registry负责docker registry有关的身份认证、镜像查找、镜像验证以及管理registry mirror等交互操作

    • image 负责与镜像源数据有关的存储、查找,镜像层的索引、查找以及镜像tar包有关的导入、导出操作

    • reference负责存储本地所有镜像的repository和tag名,并维护与镜像id之间的映射关系

    • layer模块负责与镜像层和容器层源数据有关的增删改查,并负责将镜像层的增删改查映射到实际存储镜像层文件的graphdriver模块

    • graghdriver是所有与容器镜像相关操作的执行者

     

    2、docker架构2

     

    如果觉得上面架构图比较乱可以看这个架构:

     

     

     

    从上图不难看出,用户是使用Docker Client与Docker Daemon建立通信,并发送请求给后者。

     

    而Docker Daemon作为Docker架构中的主体部分,首先提供Server的功能使其可以接受Docker Client的请求;而后Engine执行Docker内部的一系列工作,每一项工作都是以一个Job的形式的存在。

     

    Job的运行过程中,当需要容器镜像时,则从Docker Registry中下载镜像,并通过镜像管理驱动graphdriver将下载镜像以Graph的形式存储;当需要为Docker创建网络环境时,通过网络管理驱动networkdriver创建并配置Docker容器网络环境;当需要限制Docker容器运行资源或执行用户指令等操作时,则通过execdriver来完成。

     

    而libcontainer是一项独立的容器管理包,networkdriver以及execdriver都是通过libcontainer来实现具体对容器进行的操作。当执行完运行容器的命令后,一个实际的Docker容器就处于运行状态,该容器拥有独立的文件系统,独立并且安全的运行环境等。

     

    3、docker架构3

     

    再来看看另外一个架构,这个个架构就简单清晰指明了server/client交互,容器和镜像、数据之间的一些联系。

     

     

    这个架构图更加清晰了架构

     

    docker daemon就是docker的守护进程即server端,可以是远程的,也可以是本地的,这个不是C/S架构吗,客户端Docker client 是通过rest api进行通信。

     

    docker cli 用来管理容器和镜像,客户端提供一个只读镜像,然后通过镜像可以创建多个容器,这些容器可以只是一个RFS(Root file system根文件系统),也可以ishi一个包含了用户应用的RFS,容器再docker client中只是要给进程,两个进程之间互不可见。

     

    用户不能与server直接交互,但可以通过与容器这个桥梁来交互,由于是操作系统级别的虚拟技术,中间的损耗几乎可以不计。

    三、docker架构2各个模块的功能(带完善)

    主要的模块有:Docker Client、Docker Daemon、Docker Registry、Graph、Driver、libcontainer以及Docker container。   

     

    1、docker client

     

    docker client 是docker架构中用户用来和docker daemon建立通信的客户端,用户使用的可执行文件为docker,通过docker命令行工具可以发起众多管理container的请求。

     

    docker client可以通过一下三宗方式和docker daemon建立通信:tcp://host:port;unix:path_to_socket;fd://socketfd。,docker client可以通过设置命令行flag参数的形式设置安全传输层协议(TLS)的有关参数,保证传输的安全性。

     

    docker client发送容器管理请求后,由docker daemon接受并处理请求,当docker client 接收到返回的请求相应并简单处理后,docker client 一次完整的生命周期就结束了,当需要继续发送容器管理请求时,用户必须再次通过docker可以执行文件创建docker client。

     

    2、docker daemon

     

    docker daemon 是docker架构中一个常驻在后台的系统进程,功能是:接收处理docker client发送的请求。该守护进程在后台启动一个server,server负载接受docker client发送的请求;接受请求后,server通过路由与分发调度,找到相应的handler来执行请求。

     

    docker daemon启动所使用的可执行文件也为docker,与docker client启动所使用的可执行文件docker相同,在docker命令执行时,通过传入的参数来判别docker daemon与docker client。

     

    docker daemon的架构可以分为:docker server、engine、job。daemon

     

    3、docker server

     

    docker server在docker架构中时专门服务于docker client的server,该server的功能时:接受并调度分发docker client发送的请求,架构图如下:

        

     

    在Docker的启动过程中,通过包gorilla/mux(golang的类库解析),创建了一个mux.Router,提供请求的路由功能。在Golang中,gorilla/mux是一个强大的URL路由器以及调度分发器。该mux.Router中添加了众多的路由项,每一个路由项由HTTP请求方法(PUT、POST、GET或DELETE)、URL、Handler三部分组成。

     

    若Docker Client通过HTTP的形式访问Docker Daemon,创建完mux.Router之后,Docker将Server的监听地址以及mux.Router作为参数,创建一个httpSrv=http.Server{},最终执行httpSrv.Serve()为请求服务。

     

    在Server的服务过程中,Server在listener上接受Docker Client的访问请求,并创建一个全新的goroutine来服务该请求。在goroutine中,首先读取请求内容,然后做解析工作,接着找到相应的路由项,随后调用相应的Handler来处理该请求,最后Handler处理完请求之后回复该请求。

     

    需要注意的是:Docker Server的运行在Docker的启动过程中,是靠一个名为”serveapi”的job的运行来完成的。原则上,Docker Server的运行是众多job中的一个,但是为了强调Docker Server的重要性以及为后续job服务的重要特性,将该”serveapi”的job单独抽离出来分析,理解为Docker Server。

     

    4、engine

     

    Engine是Docker架构中的运行引擎,同时也Docker运行的核心模块。它扮演Docker container存储仓库的角色,并且通过执行job的方式来操纵管理这些容器。

     

    在Engine数据结构的设计与实现过程中,有一个handler对象。该handler对象存储的都是关于众多特定job的handler处理访问。举例说明,Engine的handler对象中有一项为:{“create”: daemon.ContainerCreate,},则说明当名为”create”的job在运行时,执行的是daemon.ContainerCreate的handler。

     

    5、job

     

    一个Job可以认为是Docker架构中Engine内部最基本的工作执行单元。Docker可以做的每一项工作,都可以抽象为一个job。例如:在容器内部运行一个进程,这是一个job;创建一个新的容器,这是一个job,从Internet上下载一个文档,这是一个job;包括之前在Docker Server部分说过的,创建Server服务于HTTP的API,这也是一个job,等等。

     

    Job的设计者,把Job设计得与Unix进程相仿。比如说:Job有一个名称,有参数,有环境变量,有标准的输入输出,有错误处理,有返回状态等。

     

    6、docker registry

     

    Docker Registry是一个存储容器镜像的仓库。而容器镜像是在容器被创建时,被加载用来初始化容器的文件架构与目录。

     

    在Docker的运行过程中,Docker Daemon会与Docker Registry通信,并实现搜索镜像、下载镜像、上传镜像三个功能,这三个功能对应的job名称分别为”search”,”pull” 与 “push”。

     

    其中,在Docker架构中,Docker可以使用公有的Docker Registry,即大家熟知的Docker Hub,如此一来,Docker获取容器镜像文件时,必须通过互联网访问Docker Hub;同时Docker也允许用户构建本地私有的Docker Registry,这样可以保证容器镜像的获取在内网完成。

     

    7、Graph

     

    Graph在Docker架构中扮演已下载容器镜像的保管者,以及已下载容器镜像之间关系的记录者。一方面,Graph存储着本地具有版本信息的文件系统镜像,另一方面也通过GraphDB记录着所有文件系统镜像彼此之间的关系。

     

    Graph的架构如下:

     

     

    其中,GraphDB是一个构建在SQLite之上的小型图数据库,实现了节点的命名以及节点之间关联关系的记录。它仅仅实现了大多数图数据库所拥有的一个小的子集,但是提供了简单的接口表示节点之间的关系。

     

    同时在Graph的本地目录中,关于每一个的容器镜像,具体存储的信息有:该容器镜像的元数据,容器镜像的大小信息,以及该容器镜像所代表的具体rootfs。

     

    8、driver

     

    Driver是Docker架构中的驱动模块。通过Driver驱动,Docker可以实现对Docker容器执行环境的定制。由于Docker运行的生命周期中,并非用户所有的操作都是针对Docker容器的管理,另外还有关于Docker运行信息的获取,Graph的存储与记录等。因此,为了将Docker容器的管理从Docker Daemon内部业务逻辑中区分开来,设计了Driver层驱动来接管所有这部分请求。

     

    在Docker Driver的实现中,可以分为以下三类驱动:graphdriver、networkdriver和execdriver。

     

    graphdriver主要用于完成容器镜像的管理,包括存储与获取。即当用户需要下载指定的容器镜像时,graphdriver将容器镜像存储在本地的指定目录;同时当用户需要使用指定的容器镜像来创建容器的rootfs时,graphdriver从本地镜像存储目录中获取指定的容器镜像。

     

    在graphdriver的初始化过程之前,有4种文件系统或类文件系统在其内部注册,它们分别是aufs、btrfs、vfs和devmapper。而Docker在初始化之时,通过获取系统环境变量”DOCKER_DRIVER”来提取所使用driver的指定类型。而之后所有的graph操作,都使用该driver来执行。

     

    graphdriver的架构如下:

     

     

    networkdriver的用途是完成Docker容器网络环境的配置,其中包括Docker启动时为Docker环境创建网桥;Docker容器创建时为其创建专属虚拟网卡设备;以及为Docker容器分配IP、端口并与宿主机做端口映射,设置容器防火墙策略等。networkdriver的架构如下:

     

     

    execdriver作为Docker容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。在execdriver的实现过程中,原先可以使用LXC驱动调用LXC的接口,来操纵容器的配置以及生命周期,而现在execdriver默认使用native驱动,不依赖于LXC。

     

    具体体现在Daemon启动过程中加载的ExecDriverflag参数,该参数在配置文件已经被设为”native”。这可以认为是Docker在1.2版本上一个很大的改变,或者说Docker实现跨平台的一个先兆。execdriver架构如下:

     

     

    9、libcontainer

     

    libcontainer是Docker架构中一个使用Go语言设计实现的库,设计初衷是希望该库可以不依靠任何依赖,直接访问内核中与容器相关的API。

     

    正是由于libcontainer的存在,Docker可以直接调用libcontainer,而最终操纵容器的namespace、cgroups、apparmor、网络设备以及防火墙规则等。这一系列操作的完成都不需要依赖LXC或者其他包。libcontainer架构如下:

     

    另外,libcontainer提供了一整套标准的接口来满足上层对容器管理的需求。或者说,libcontainer屏蔽了Docker上层对容器的直接管理。又由于libcontainer使用Go这种跨平台的语言开发实现,且本身又可以被上层多种不同的编程语言访问,因此很难说,未来的Docker就一定会紧紧地和Linux捆绑在一起。而于此同时,Microsoft在其著名云计算平台Azure中,也添加了对Docker的支持,可见Docker的开放程度与业界的火热度。

     

    暂不谈Docker,由于libcontainer的功能以及其本身与系统的松耦合特性,很有可能会在其他以容器为原型的平台出现,同时也很有可能催生出云计算领域全新的项目。

     

    10、docker container

     

    Docker container(Docker容器)是Docker架构中服务交付的最终体现形式。

     

    Docker按照用户的需求与指令,订制相应的Docker容器:

     

    • 用户通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统;

    • 用户通过指定计算资源的配额,使得Docker容器使用指定的计算资源;

    • 用户通过配置网络及其安全策略,使得Docker容器拥有独立且安全的网络环境;

    • 用户通过指定运行的命令,使得Docker容器执行指定的工作。

      

    四、docker简单使用

    推荐:Docker 核心概念、安装、端口映射及常用操作命令,详细到令人发指。

     

    1、安装

     

    yum install docker -y 
    systemctl enable docker
    systemctl start docker

     

    注意:启动前应当设置源

     

    vim /usr/lib/systemd/system/docker.service

     

    这里设置阿里的,注册阿里云账户号每个用户都有:

     

    [root@web1 ~]# vim /usr/lib/systemd/system/docker.service 
    
    [Unit]
    Description=Docker Application Container Engine
    Documentation=http://docs.docker.com
    After=network.target
    Wants=docker-storage-setup.service
    Requires=docker-cleanup.timer
    
    [Service]
    Type=notify
    NotifyAccess=main
    EnvironmentFile=-/run/containers/registries.conf
    EnvironmentFile=-/etc/sysconfig/docker
    EnvironmentFile=-/etc/sysconfig/docker-storage
    EnvironmentFile=-/etc/sysconfig/docker-network
    Environment=GOTRACEBACK=crash
    Environment=DOCKER_HTTP_HOST_COMPAT=1
    Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
    ExecStart=/usr/bin/dockerd-current --registry-mirror=https://rfcod7oz.mirror.aliyuncs.com \ #这个值可以登陆阿里云账号请参考下图
              --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
              --default-runtime=docker-runc \
              --exec-opt native.cgroupdriver=systemd \
              --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
              --init-path=/usr/libexec/docker/docker-init-current \
              --seccomp-profile=/etc/docker/seccomp.json \
              $OPTIONS \
              $DOCKER_STORAGE_OPTIONS \
              $DOCKER_NETWORK_OPTIONS \
              $ADD_REGISTRY \
              $BLOCK_REGISTRY \
              $INSECURE_REGISTRY \
              $REGISTRIES
    ExecReload=/bin/kill -s HUP $MAINPID
    LimitNOFILE=1048576
    LimitNPROC=1048576
    LimitCORE=infinity
    TimeoutStartSec=0
    Restart=on-abnormal
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
     

      

     

    2、docker版本查询

     

    [root@web1 ~]# docker version
    Client:
     Version:         1.13.1
     API version:     1.26
     Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64
     Go version:      go1.10.3
     Git commit:      b2f74b2/1.13.1
     Built:           Wed May  1 14:55:20 2019
     OS/Arch:         linux/amd64
    
    Server:
     Version:         1.13.1
     API version:     1.26 (minimum version 1.12)
     Package version: docker-1.13.1-96.gitb2f74b2.el7.centos.x86_64
     Go version:      go1.10.3
     Git commit:      b2f74b2/1.13.1
     Built:           Wed May  1 14:55:20 2019
     OS/Arch:         linux/amd64
     Experimental:    false
     

     

    3、搜索下载镜像

     

    docker pull alpine          #下载镜像
    docker search nginx          #查看镜像
    docker pull nginx
     

     

    4、查看已经下载的镜像

     

     
    [root@web1 ~]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    zxg/my_nginx        v1                  b164f4c07c64        8 days ago          126 MB
    zxg/my_nginx        latest              f07837869dfc        8 days ago          126 MB
    docker.io/nginx     latest              e445ab08b2be        2 weeks ago         126 MB
    docker.io/alpine    latest              b7b28af77ffe        3 weeks ago         5.58 MB
    docker.io/centos    latest              9f38484d220f        4 months ago        202 MB
    [root@web1 ~]# 

     

    5、导出镜像

     

     
    docker  save nginx >/tmp/nginx.tar.gz

     

    6、删除镜像

     

     
    docker rmi -f nginx

     

    7、导入镜像

     

    docker load </tmp/nginx.tar.gz

     

    8、默认配置文件

     

    vim /usr/lib/systemd/system/docker.service 

     

    [Unit]
    Description=Docker Application Container Engine
    Documentation=http://docs.docker.com
    After=network.target
    Wants=docker-storage-setup.service
    Requires=docker-cleanup.timer
    
    [Service]
    Type=notify
    NotifyAccess=main
    EnvironmentFile=-/run/containers/registries.conf
    EnvironmentFile=-/etc/sysconfig/docker
    EnvironmentFile=-/etc/sysconfig/docker-storage
    EnvironmentFile=-/etc/sysconfig/docker-network
    Environment=GOTRACEBACK=crash
    Environment=DOCKER_HTTP_HOST_COMPAT=1
    Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
    ExecStart=/usr/bin/dockerd-current --registry-mirror=https://rfcod7oz.mirror.aliyuncs.com \
              --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
              --default-runtime=docker-runc \
              --exec-opt native.cgroupdriver=systemd \
              --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
              --init-path=/usr/libexec/docker/docker-init-current \
              --seccomp-profile=/etc/docker/seccomp.json \
              $OPTIONS \
              $DOCKER_STORAGE_OPTIONS \
              $DOCKER_NETWORK_OPTIONS \
              $ADD_REGISTRY \
              $BLOCK_REGISTRY \
              $INSECURE_REGISTRY \
              $REGISTRIES
    ExecReload=/bin/kill -s HUP $MAINPID
    LimitNOFILE=1048576
    LimitNPROC=1048576
    LimitCORE=infinity
    TimeoutStartSec=0
    Restart=on-abnormal
    KillMode=process
    
    [Install]
    WantedBy=multi-user.target
    ~                                                                                                                   
    ~                                                                                                                   
    ~                                                                                                                   
    ~       

     

    如果更改存储目录就添加 

     

    --graph=/opt/docker      

     

    如果更改DNS——默认采用宿主机的dns

     

    --dns=xxxx的方式指定

     

    9、运行hello world

     

    这里用centos镜像echo一个hello word

     

     

    [root@web1 overlay2]#  docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    zxg/my_nginx        v1                  b164f4c07c64        8 days ago          126 MB
    zxg/my_nginx        latest              f07837869dfc        8 days ago          126 MB
    docker.io/nginx     latest              e445ab08b2be        2 weeks ago         126 MB
    docker.io/alpine    latest              b7b28af77ffe        3 weeks ago         5.58 MB
    docker.io/centos    latest              9f38484d220f        4 months ago        202 MB
    [root@web1 overlay2]# docker run centos echo "hello world"
    hello world
    [root@web1 overlay2]#

     

    10、运行一个容器-run

     

    [root@web1 overlay2]# docker run -it alpine sh   #运行并进入alpine  
    / # 
    / # 
    / # 
    / # 
    / # 
    / # ls
    bin    etc    lib    mnt    proc   run    srv    tmp    var
    dev    home   media  opt    root   sbin   sys    usr
    / # cd tmp
    /tmp # exit 
     

     

    后台运行(-d后台运行)(--name添加一个名字)

     

    [root@web1 overlay2]# docker run -it -d --name test1 alpine
    ac46c019b800d34c37d4f9dcd56c974cb82eca3acf185e5f8f80c8a60075e343
    [root@web1 overlay2]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    ac46c019b800        alpine              "/bin/sh"           5 seconds ago       Up 3 seconds                            test1
    [root@web1 overlay2]#  
     

     

    还有一种-rm参数,ctrl+c后就删除,可以测试环境用,生成环境用的少

     

    [root@web1 overlay2]# docker run -it  --rm --name centos nginx 
    ^C[root@web1 overlay2]# 
    ##另开一个窗口
    [root@web1 ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    3397b96ea7bd        nginx               "nginx -g 'daemon ..."   27 seconds ago      Up 25 seconds       80/tcp              centos
    ac46c019b800        alpine              "/bin/sh"                4 minutes ago       Up 4 minutes                            test1
    [root@web1 ~]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    ac46c019b800        alpine              "/bin/sh"           4 minutes ago       Up 4 minutes                            test1
    [root@web1 ~]# 
     

     

    11、如何进入容器

     

    三种方法,上面已经演示了一种

    第一种,需要容器本身的pid及util-linux,不推荐,暂时不演示了

    第二种,不分配bash终端的一种实施操作,不推荐,这种操作如果在开一个窗口也能看到操作的指令,所有人都能看到。

     

    [root@web1 overlay2]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    9fc796e928d7        nginx               "sh"                2 minutes ago       Up 8 seconds        80/tcp              mynginx
    ac46c019b800        alpine              "/bin/sh"           12 minutes ago      Up 12 minutes                           test1
    [root@web1 overlay2]# docker attach mynginx
    
    # 
    # 
    # 
    # 
    # ls
    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    # exit  
    [root@web1 overlay2]# docker attach mynginx
    You cannot attach to a stopped container, start it first
    [root@web1 overlay2]# docker ps 
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    ac46c019b800        alpine              "/bin/sh"           13 minutes ago      Up 13 minutes                           test1
    [root@web1 overlay2]# 
     

     

    第三种:exec方式,终端时分开的,推荐

     

    [root@web1 overlay2]# docker exec -it mynginx sh
    # 
    # 
    # 
    # ls 
    bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    # exit
    [root@web1 overlay2]# 
    [root@web1 overlay2]# 
    [root@web1 overlay2]# 
    [root@web1 overlay2]# docker pa
    docker: 'pa' is not a docker command.
    See 'docker --help'
    [root@web1 overlay2]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    6fc2d091cfe9        nginx               "nginx -g 'daemon ..."   45 seconds ago      Up 43 seconds       80/tcp              mynginx
    ac46c019b800        alpine              "/bin/sh"                16 minutes ago      Up 16 minutes                           test1

     

    12、查看docker进程及删除容器

     

    上面已经演示:

     

    [root@web1 overlay2]# docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    9fc796e928d7        nginx               "sh"                2 minutes ago       Up 8 seconds        80/tcp              mynginx
    ac46c019b800        alpine              "/bin/sh"           12 minutes ago      Up 12 minutes                           test1
    

     

    [root@web1 overlay2]# docker ps -a       #-a :显示所有的容器,包括未运行的
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS               NAMES
    9fc796e928d7        nginx               "sh"                     4 minutes ago       Exited (0) About a minute ago                       mynginx
    ac46c019b800        alpine              "/bin/sh"                15 minutes ago      Up 15 minutes                                       test1
    3bf234febeaa        alpine              "sh"                     17 minutes ago      Exited (0) 16 minutes ago                           youthful_lumiere
    ab113c63f0b4        centos              "echo 'hello world'"     31 minutes ago      Exited (0) 31 minutes ago                           infallible_torvalds
    b326027dcf42        zxg/my_nginx        "nginx"                  8 days ago          Exited (0) 8 days ago                               my_nginx
    4f1f1ca319f2        centos              "bash"                   8 days ago          Exited (137) 8 days ago                             musing_lichterman
    64b4e32991c7        nginx               "nginx -g 'daemon ..."   12 days ago         Exited (0) 12 days ago                              mynginx1
    aee506fe7b5a        alpine              "sh"                     12 days ago         Created                                             infallible_haibt
    70620c73b9a0        alpine              "sh"                     12 days ago         Created                                             gallant_volhard
    7655cbf87bb0        alpine              "sh"                     12 days ago         Created                                             agitated_brahmagupta
    33fb949372e8        fce289e99eb9        "/hello"                 12 days ago         Created                                             elastic_dijkstra
    9de47616aea4        fce289e99eb9        "/hello"                 13 days ago         Created                                             confident_fermi
    [root@web1 overlay2]# docker rm 9fc796e928d7 #rm时删除一个或多个容器   
    9fc796e928d7

     

    13、查看容器详细信息

     

    并不需要进入到容器里面,通过查看详细信息看到了刚才运行的nginx,宿主机curl ip地址访问一下运行情况。

     

    [root@web1 overlay2]#  docker inspect mynginx
    [
        {
            "Id": "6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010",
            "Created": "2019-08-07T08:57:48.864538933Z",
            "Path": "nginx",
            "Args": [
                "-g",
                "daemon off;"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 119948,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2019-08-07T08:57:49.417992182Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
            "Image": "sha256:e445ab08b2be8b178655b714f89e5db9504f67defd5c7408a00bade679a50d44",
            "ResolvConfPath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/resolv.conf",
            "HostnamePath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/hostname",
            "HostsPath": "/var/lib/docker/containers/6fc2d091cfe9b0484da3e70db842446bbdfeb7f5e5409c2e40ae21b99498d010/hosts",
            "LogPath": "",
            "Name": "/mynginx",
            "RestartCount": 0,
            "Driver": "overlay2",
            "MountLabel": "",
            "ProcessLabel": "",
            "AppArmorProfile": "",
            "ExecIDs": null,
            "HostConfig": {
                "Binds": null,
                "ContainerIDFile": "",
                "LogConfig": {
                    "Type": "journald",
                    "Config": {}
                },
                "NetworkMode": "default",
                "PortBindings": {},
                "RestartPolicy": {
                    "Name": "no",
                    "MaximumRetryCount": 0
                },
                "AutoRemove": false,
                "VolumeDriver": "",
                "VolumesFrom": null,
                "CapAdd": null,
                "CapDrop": null,
                "Dns": [],
                "DnsOptions": [],
                "DnsSearch": [],
                "ExtraHosts": null,
                "GroupAdd": null,
                "IpcMode": "",
                "Cgroup": "",
                "Links": null,
                "OomScoreAdj": 0,
                "PidMode": "",
                "Privileged": false,
                "PublishAllPorts": false,
                "ReadonlyRootfs": false,
                "SecurityOpt": null,
                "UTSMode": "",
                "UsernsMode": "",
                "ShmSize": 67108864,
                "Runtime": "docker-runc",
                "ConsoleSize": [
                    0,
                    0
                ],
                "Isolation": "",
                "CpuShares": 0,
                "Memory": 0,
                "NanoCpus": 0,
                "CgroupParent": "",
                "BlkioWeight": 0,
                "BlkioWeightDevice": null,
                "BlkioDeviceReadBps": null,
                "BlkioDeviceWriteBps": null,
                "BlkioDeviceReadIOps": null,
                "BlkioDeviceWriteIOps": null,
                "CpuPeriod": 0,
                "CpuQuota": 0,
                "CpuRealtimePeriod": 0,
                "CpuRealtimeRuntime": 0,
                "CpusetCpus": "",
                "CpusetMems": "",
                "Devices": [],
                "DiskQuota": 0,
                "KernelMemory": 0,
                "MemoryReservation": 0,
                "MemorySwap": 0,
                "MemorySwappiness": -1,
                "OomKillDisable": false,
                "PidsLimit": 0,
                "Ulimits": null,
                "CpuCount": 0,
                "CpuPercent": 0,
                "IOMaximumIOps": 0,
                "IOMaximumBandwidth": 0
            },
            "GraphDriver": {
                "Name": "overlay2",
                "Data": {
                    "LowerDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a-init/diff:/var/lib/docker/overlay2/d8e95505fc3894eb30b48e4b0f48ab5e89d99c09a07c79c0b057c611621e31eb/diff:/var/lib/docker/overlay2/b2a6a25974bf17398b698a27208711574be3c69a2cd06658bbe838359f373a27/diff:/var/lib/docker/overlay2/d4610bc89b3ba8ad6ab30ea895fc3a06efff15db493d86ac9bc100e04abbab67/diff",
                    "MergedDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/merged",
                    "UpperDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/diff",
                    "WorkDir": "/var/lib/docker/overlay2/937140af0aee6c43f04c2d7b72e6b5451a44fef921417e8236d9fe01e9286c7a/work"
                }
            },
            "Mounts": [],
            "Config": {
                "Hostname": "6fc2d091cfe9",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "80/tcp": {}
                },
                "Tty": true,
                "OpenStdin": true,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "NGINX_VERSION=1.17.2",
                    "NJS_VERSION=0.3.3",
                    "PKG_RELEASE=1~buster"
                ],
                "Cmd": [
                    "nginx",
                    "-g",
                    "daemon off;"
                ],
                "ArgsEscaped": true,
                "Image": "nginx",
                "Volumes": null,
                "WorkingDir": "",
                "Entrypoint": null,
                "OnBuild": null,
                "Labels": {
                    "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
                },
                "StopSignal": "SIGTERM"
            },
            "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "3ece36008fbc5f3f46d3d251cf803c1478cc14032d74a36747e4ed8a115b81df",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": {
                    "80/tcp": null
                },
                "SandboxKey": "/var/run/docker/netns/3ece36008fbc",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "898de81d97d54d2b60aeb6cc77ef1b4f9b481d1b72f542faa496494594024eac",
                "Gateway": "172.17.0.1",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.3",        #看到ip地址
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:11:00:03",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "2edae9131e77500a56d251b94ab2cdf0bc86f8df9f2453fa46bf4bab2f7be99f",
                        "EndpointID": "898de81d97d54d2b60aeb6cc77ef1b4f9b481d1b72f542faa496494594024eac",
                        "Gateway": "172.17.0.1",
                        "IPAddress": "172.17.0.3",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:11:00:03"
                    }
                }
            }
        }
    ]
    [root@web1 overlay2]# curl 172.17.0.1      #访问一下
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
        <head>
            <title>Test Page for the Nginx HTTP Server on Fedora</title>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <style type="text/css">
                /*<![CDATA[*/
                body {
                    background-color: #fff;
                    color: #000;
                    font-size: 0.9em;
                    font-family: sans-serif,helvetica;
                    margin: 0;
                    padding: 0;
                }
                :link {
                    color: #c00;
                }
                :visited {
                    color: #c00;
                }
                a:hover {
                    color: #f50;
                }
                h1 {
                    text-align: center;
                    margin: 0;
                    padding: 0.6em 2em 0.4em;
                    background-color: #294172;
                    color: #fff;
                    font-weight: normal;
                    font-size: 1.75em;
                    border-bottom: 2px solid #000;
                }
                h1 strong {
                    font-weight: bold;
                    font-size: 1.5em;
                }
                h2 {
                    text-align: center;
                    background-color: #3C6EB4;
                    font-size: 1.1em;
                    font-weight: bold;
                    color: #fff;
                    margin: 0;
                    padding: 0.5em;
                    border-bottom: 2px solid #294172;
                }
                hr {
                    display: none;
                }
                .content {
                    padding: 1em 5em;
                }
                .alert {
                    border: 2px solid #000;
                }
    
                img {
                    border: 2px solid #fff;
                    padding: 2px;
                    margin: 2px;
                }
                a:hover img {
                    border: 2px solid #294172;
                }
                .logos {
                    margin: 1em;
                    text-align: center;
                }
                /*]]>*/
            </style>
        </head>
    
        <body>
            <h1>Welcome to <strong>nginx</strong> on Fedora!</h1>
    
            <div class="content">
                <p>This page is used to test the proper operation of the
                <strong>nginx</strong> HTTP server after it has been
                installed. If you can read this page, it means that the
                web server installed at this site is working
                properly.</p>
    
                <div class="alert">
                    <h2>Website Administrator</h2>
                    <div class="content">
                        <p>This is the default <tt>index.html</tt> page that
                        is distributed with <strong>nginx</strong> on
                        Fedora.  It is located in
                        <tt>/usr/share/nginx/html</tt>.</p>
    
                        <p>You should now put your content in a location of
                        your choice and edit the <tt>root</tt> configuration
                        directive in the <strong>nginx</strong>
                        configuration file
                        <tt>/etc/nginx/nginx.conf</tt>.</p>
    
                    </div>
                </div>
    
                <div class="logos">
                    <a href="http://nginx.net/"><img
                        src="nginx-logo.png" 
                        alt="[ Powered by nginx ]"
                        width="121" height="32" /></a>
    
                    <a href="http://fedoraproject.org/"><img 
                        src="poweredby.png" 
                        alt="[ Powered by Fedora ]" 
                        width="88" height="31" /></a>
                </div>
            </div>
        </body>
    </html>
    [root@web1 overlay2]# 
     

     

    14、查看日志

     

    -f  挂起这个终端,动态查看日志

     

    [root@web1 ~]# docker logs  -f mynginx
    展开全文
  • cf16-1代码什么意思…posted by davidjmedlock: …由 davidjmedlock 发布 : Well, in about 7 hours I’m going to be on a plane to Salt Lake City, Utah for my first snowboarding trip. I’ve never been ...
  • 智课雅思词汇---十、pend是什么意思 一、总结 一句话总结:【词根含义】:悬挂,垂;称量;支付 词根:-pend-, -pens- 【词根含义】:悬挂,垂;称量;支付 【词根来源】:来源于拉丁语动词pendeo, pendere, pependi,...
  • 大二下周总结

    千次阅读 2019-03-03 21:34:45
    我还发现了一个绝妙的对视表情,哈哈哈 星期天的比赛我一定要说一下,我真的以前从没参加过什么和编程有关的比赛,本来是把战线拉的很长很重视这个比赛但是居然也没怎么去准备,寒假断断续续写了几个题,赛前两个...
  • 自然语言处理中的Attention Model:是什么及为什么

    万次阅读 多人点赞 2016-01-20 18:26:02
    让我们来直观地体会一下什么是人脑中的注意力模型。首先,请您睁开眼并确认自己处于意识清醒状态;第二步,请找到本文最近出现的一个“Attention Model”字眼(就是“字眼”前面的两个英文单词,…^@@^)并盯住看三...
  • 这就是三层和两层的意思,如果只要两层的接口的话,您就写workers/list就好 然后刚刚一直提示路径错误,我们请教了公司前辈,他说是因为后台忘记添加app这个单词了,因为这里涉及到一个权限问题,小程序只有加了...
  • 等项目完了再来看,看看两次的心情的差别。
  • 以软件开发为例,质量数据显性化是个不错的方法,啥意思呢,就是管理者关注软件开发中质量相关的数据,将过程质量数据定期公布给整个团队,并激励和引导开发人员进行自我检查,这样才能最大程度的消除安全隐患,...
  • 前言 面试:如果不准备充分的面试,完全是...有几家已经面了几轮,下周还要面,挂了几家,不过目前已经选择了华为。 这期间很多面试经验,正直现在面试季节,分享给大家。有想法和问题的欢迎在评论区留言。 一.view渲
  • 先卖个关子,不说什么事情比游戏还有意思,先说下我有多爱玩游戏把。 说起个人玩游戏,那么就是始于高中,盛于大学,延续至今,衰于上一秒。 高中高中高中 高中休息时间是周六中午12点放假到周日晚自习。中午一下课...
  • 少儿编程到底是什么

    千次阅读 多人点赞 2020-09-19 19:55:32
    那么,什么是编程,少儿编程又是什么呢?对于前者,我期望从开发者的角度作出我的解读,对于后者,我希望以编程老师的视角与大家分享。 编程是什么 编程,对于大众来说,最普遍的理解可能就是写代码,可能再深入一点...
  • 每晚下晚自习对当天学习情况进行汇报,对于学习态度有问题的同学,第二天进行处理,这个下周还需加大管理措施,成绩好与坏那只是一时的结果,主要看的是学习态度。 对于周考,以成绩为参照物,从下周考试增加奖惩...
  • 什么是embedding?

    万次阅读 多人点赞 2019-07-10 16:31:13
     那么到底什么是我们通常意义上所说的词向量 v w v_{w} v w ​ 呢?  其实就是我们上面所说的输入向量矩阵 W V × N W_{V\times N} W V × N ​ 中每一行对应的权重向量。于是这个权重矩阵自然转换成了word2...
  • 什么是“月结30天”?(轉)

    千次阅读 2019-06-15 05:29:27
    那么A单位就必须在25号前开好正确的发票,结算日在11月25号,月结60天,即明年1月25号到期,所以25号付款给供应商(遇到周末顺延到下周一付款)。 如果验收单B单位有货款RMB金额为50000元,验收日期为11月26号。...
  • 这又是为什么?(在引起共鸣的因素章节中,将会得到你要的答案) 每一篇文章,每一本书只要涉及到生活相关的,作为读者的我们都会觉得似乎在讲的都是废话。心理会有一句鄙视语,本来就是这样的嘛。 当你试着去...
  • 总结这周,展望下周

    2011-03-27 23:04:00
    当然,我一般是不会挑题目这么长的去写的,可喜的是,我上午看题虽然个别词不懂,不过意思还是很明白的。想想我找这题的BUG还真不容易,自己坚定的建图是不对的,幸运吧,或许,自己做的数据找到了这个BUG。如果要是...
  • sql面试经典50题练习笔记二

    千次阅读 2019-10-10 14:38:05
    什么意思: @i:=@i+1 的意思可以理解为,定义了一个变量,然后每次 叠加一,在这里的作用是 生成排名序列号 from后面的 @k:=0,@i:=0,@score:=0 这些为初始化变量 其次需要理解 case when 条件A then 结果...
  • 评完 PRD 以后,产品问我这个需求下周能上线不。其实这个需求并不急,只是得让你有点事干。 评完 PRD 以后,预估了一个开发时间给产品,产品却说这个需求要做那么久?此时的潜台词就是:你这人技术真垃圾,那么简单...
  • 这种错误的认知是因为人们不了解什么是独立事件。 常见的错误行为有:研究彩票中奖,短期看K线图预测股价。 2.什么是独立事件? 独立事件是不受过去事件影响的...
  • 什么是用户故事

    2021-03-01 22:06:34
    # 一、 什么是用户故事? ## 一、用户故事的概念 概念这种东西我喜欢说文解字的方式去理解和阐述;用户故事=用户+故事=人+故+事,那就是一个人因为什么原因要做什么事,提炼出来三要素就是who、why、what。从需求...
  • 什么近期这么多的人涌入这个市场,因为它有价值。我是比较看好这个市场,不管它的未来趋势还是市场价值,通过不断的完善调整,会更容易受众大众。好了,接下来老马带大家看下行情,首先看日线均线走平代表的意思多...
  • 我可以请你吃一千块钱的饭,也可以请你喝两千块钱的酒,但是你欠我的一百块钱你得还,不为什么,这是规矩,做人最起码的原则。 目录 借钱之惆怅,感慨万千 有些人,总喜欢从门缝里看人,“容易把人看扁了...
  • 如果T日是周五,T+1就是下周一。当日发生的交易均延顺到下一个工作日进行结算。 2、T+0 所谓的T+0结算,是当天所有成功交易,于工作当日将POS机结算资金划入指定的结算账户,目前市场上也比较流行的T+0 。 ...
  • 1001-什么是RPA?(上)

    千次阅读 2019-02-21 21:44:27
    本着“一篇文章只说一件事儿”的原则,今天只回答一个问题:什么是RPA? RPA是Robotic Process Automation的缩写,翻译为:流程自动化机器人。 一、我们的理解: 传统场景下,员工的工作绝大部分是通过电脑...
  • 等等党们别等了,AirPods Pro拼多多都1399了,我看爆料贴下面还是各种值友们留言,大家真是人才啊,各种打油诗,什么:你不买我不买,下周还能降200。什么999交个朋友这类的! 数码产品,早买早享受啊,再说了你的...
  • 大厂程序员的一天是如何度过的?

    千次阅读 多人点赞 2019-08-06 01:03:51
    好不容易熬到晚上,本想吃个饭就走人的,结果同事们不约而同地都回到工位上,似乎没有要走的意思。   于是小李只好返回工位。继续兢兢业业的写代码,总不能自己一个人先走吧,多不合群呀,实在不合适呀。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,470
精华内容 2,588
关键字:

下周的意思是什么