COW

MIT6.0002 笔记,LECTURE1&2 Optimization

一个人想着一个人 提交于 2020-04-06 14:49:17
Lecture1&2 Optimization 最优化问题 贪心算法(greedy algorithm) 优点 缺点 暴力算法(brute force algorithm) 优点 缺点 动态规划(dynamic programming) Lecture1&2 总结 动态规划 作业 贪心算法 暴力算法 动态规划 最优化问题 这是MIT课程MIT60002 Computational thinking and data science 的第一二课,主要内容是最优化,包括贪心算法,暴力算法和动态编程(dynamic programming)。 贪心算法(greedy algorithm) 贪心算法的优缺点 优点 容易实现 效率很高 缺点 不一定能找到全局最优,往往找到的是局部最优。 暴力算法(brute force algorithm) 优点 一定能找到全局最优 缺点 运算复杂度很高 动态规划(dynamic programming) 综合了以上两者的优点,一定能找到全局最优,复杂度介于两者之间。 Lecture1&2 总结 大部分的实际问题都能转化为最优化问题 贪心算法能提供最够优秀的解(虽然不是最优解) 找到最优解的运算复杂度一般是 指数级 的 对于最优化问题的一个子类,动态规划能够提供最够好的性能。这个子类需要同时满足optimal substructure和overlapping

COW奶牛!Copy On Write机制了解一下

这一生的挚爱 提交于 2020-03-02 06:40:38
前言 只有光头才能变强 在读《Redis设计与实现》关于哈希表扩容的时候,发现这么一段话: 执行BGSAVE命令或者BGREWRITEAOF命令的过程中,Redis需要创建当前服务器进程的子进程,而大多数操作系统都采用 写时复制(copy-on-write)来优化子进程的使用效率 ,所以在子进程存在期间,服务器会提高负载因子的阈值,从而避免在子进程存在期间进行哈希表扩展操作,避免不必要的内存写入操作,最大限度地节约内存。 触及到知识的盲区了,于是就去搜了一下copy-on-write写时复制这个技术究竟是怎么样的。发现涉及的东西蛮多的,也挺难读懂的。于是就写下这篇笔记来记录一下我学习copy-on-write的过程。 本文 力求简单讲清copy-on-write这个知识点 ,希望大家看完能有所收获。 一、Linux下的copy-on-write 在说明Linux下的copy-on-write机制前,我们首先要知道两个函数: fork() 和 exec() 。需要注意的是 exec() 并不是一个特定的函数, 它是 一组函数的统称 , 它包括了 execl() 、 execlp() 、 execv() 、 execle() 、 execve() 、 execvp() 。 1.1简单来用用fork 首先我们来看一下 fork() 函数是什么鬼: fork is an operation

299. Bulls and Cows

霸气de小男生 提交于 2020-03-02 01:50:28
Question 299. Bulls and Cows Solution 题目大意:有一串隐藏的号码,另一个人会猜一串号码(数目相同),如果号码数字与位置都对了,给一个bull,数字对但位置不对给一个cow,注:数字对与位置对优先,一个号码不能重复判断. 思路:构造map结构,遍历实现 Java实现:实现的不漂亮,好歹能通过 public String getHint(String secret, String guess) { Map<Character, Index> map = new HashMap<>(); for (int i=0; i<secret.length(); i++) { Index idx = map.get(secret.charAt(i)); if (idx == null) { idx = new Index(); map.put(secret.charAt(i), idx); } idx.add(i); } int bulls = 0; int cows = 0; List<Character> cowsList = new ArrayList<>(); // for count cows // count bulls for (int i=0; i<guess.length(); i++) { Index idx = map.get(guess

详解Linux chattr 命令,超越权限任性修改

人盡茶涼 提交于 2020-02-28 23:40:42
导读 很多时候, Linux 机器被不同的用户使用。因此,这些用户有机会访问一组共同的文件。这就为一些问题打开了大门,比如意外删除或编辑重要文件,而作为管理员,你肯定不希望发生这样的事情。值得庆幸的是,存在一个名为“chattr”的命令,它可以在上述场景中帮助到你。下面,我们使用一些容易理解的示例来讨论这个工具。本页面所有的例子都在Ubuntu 16.04 LTS上进行了测试。 Linux chattr 命令 一般,“chattr”命令用于更改Linux文件上属性。以下是它的语法: chattr [ -RVf ] [ -v version ] [ mode ] files... 下面是man手册对它的描述: chattr 改变一个Linux文件系统上的文件属性。 一个通用格式是:+-=[aAcCdDeijsStTu] ‘+’选项,将给文件添加属性;‘-’选项,移除文件中的属性;‘=’选项,使得文件只有这些属性。 字母 'aAcCdDeijsStTu' 可以赋予文件的新属性: a:只能附加数据A:不修改访问时间c:压缩文件,C:不执行写入时复制(COW) 。多个调用者获取同一个资源,这时,另一个调用者对这资源进行了修改,不生成一个副本给d:不 dump D: 同步更新目录e:extent格式(一种文件系统格式)i:不能修改。不能删除或重命名,不能创建到该文件的链接

面试

两盒软妹~` 提交于 2020-02-27 05:08:45
Redis有哪些数据结构? 字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。 使用过Redis分布式锁么,它是什么回事? 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的。 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来? 使用keys指令可以扫出指定模式的key列表。redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。 Redis如何做持久化的? bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件重新构建内存,再使用aof重放近期的操作指令来实现完整恢复重启之前的状态。 bgsave的原理是什么? fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copyonwrite,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。 是否使用过Redis集群,集群的原理是什么?

java中的copyOnWrite容器Copy-On-Write

大城市里の小女人 提交于 2020-01-07 17:33:28
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非常多的并发场景中使用到。 什么是CopyOnWrite容器 CopyOnWrite容器即写时复制的容器。通俗的理解是当我们往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是我们可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。 CopyOnWriteArrayList的实现原理 在使用CopyOnWriteArrayList之前,我们先阅读其源码了解下它是如何实现的。以下代码是向ArrayList里添加元素

mlock家族:锁定物理内存

拈花ヽ惹草 提交于 2020-01-06 16:08:45
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 锁住内存是为了防止这段内存被操作系统swap掉。并且由于此操作风险高,仅超级用户可以执行。 看家族成员: #include <sys/mman.h> int mlock(const void *addr, size_t len); int munlock(const void *addr, size_t len); int mlockall(int flags); int munlockall(void); 系统调用 mlock 家族允许程序在物理内存上锁住它的部分或全部地址空间。这将阻止Linux 将这个内存页调度到交换空间(swap space),即使该程序已有一段时间没有访问这段空间。 一个严格时间相关的程序可能会希望锁住物理内存,因为内存页面调出调入的时间延迟可能太长或过于不可预知。安全性要求较高的应用程序可能希望防止敏感数据被换出到交换文件中,因为这样在程序结束后,攻击者可能从交换文件中恢复出这些数据。 锁定一个内存区间只需简单将指向区间开始的指针及区间长度作为参数调用 mlock。Linux 分配内存到页(page)且每次只能锁定整页内存,被指定的区间涉及到的每个内存页都将被锁定。getpagesize 函数返回系统的分页大小,在 x86 Linux 系统上,这个值是 4KB。 简单的测试程序:

进程、系统性能和计划任务

不问归期 提交于 2019-12-15 15:27:56
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 进程、系统性能和计划任务 进程管理和内存分配 进程管理工具 进程管理和性能相关工具 进程信号和前后台管理 计划任务实现 进程管理和内存分配 进程概念 内核功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能等 Process: 运行中的程序的一个副本,是被载入内存的一个指令集合 进程ID(Process ID,PID)号码被用来标记各个进程 UID、GID、和SELinux语境决定对文件系统的存取和访问权限 通常从执行进程的用户来继承 存在生命周期 task struct:Linux内核存储进程信息的数据结构格式 task list:多个任务的的task struct组成的链表 进程创建: init:第一个进程 进程:都由其父进程创建,父子关系,CoW fork(), clone() 进程,线程和协程 进程相关概念 Page Frame: 页框,用存储页面数据,存储Page 4k 物理地址空间和线性地址空间 MMU:Memory Management Unit 负责转换线性和物理地址 TLB:Translation Lookaside Buffer 翻译后备缓冲器 用于保存虚拟地址和物理地址映射关系的缓存 LRU:Least Recently Used 近期最少使用算法,释放内存 用户和内核空间

docker镜像,容器和存储驱动

孤街浪徒 提交于 2019-12-04 12:32:57
镜像和层 镜像是由一些只读并且描绘文件系统区别的层组成的.它们一层一层堆叠起来,组成了镜像的基础文件系统.这些层都是只读的. 下图是由4层构成的ubuntu镜像: 而docker存储驱动的职责就是将这些层堆叠起来.并提供一个统一的视图.让我们觉得跟普通文件系统没什么区别. 当你创建了一个容器时.会在镜像的层上再添加一层叫做"容器层(container layer)",所有在运行中的容器中所做的修改操作,都是影响的这一层. 看下图 内容可寻址的存储 docker 1.10 开始,介绍了一种全新的寻址镜像和层上数据的存储模型.之前的镜像和层上数据的存放,都是通过随机UUID存放.新模型采用一种安全的内容hash来存放. 新模型特点包括提高了安全性.防止了id冲突,保证了pull,push,load,save操作后的数据一致性.并且更好的提供了层之间的共享问题. 参考图片: 容器层还是random uuid 对于新的模型,原先旧模型的镜像数据需要重新计算id来迁移.这些操作会在你运行新版本docker进程后自动执行. 镜像较多的话会比较耗资源.如需手工迁移请参考官方文档. 容器和层 容器和镜像主要区别就在于容器多了最上层的容器层.所有在容器中的修改操作,都是影响的容器各自的容器层.底下镜像的层都是只读不变的. 下图展示了多个容器共享同一个镜像,但是拥有各自的容器层.互相不受影响.

CopyOnWriteArrayList

风格不统一 提交于 2019-11-29 21:56:47
CopyOnWriteArrayList 要意识到此为数据容器, 需考察其 增 , 删 , 查 . 要留意其时空效率. 要意识到是开放类, 向 Doug Lea 学习 库 类的设计. 根据特点思考使用场景 概述 java.util.ArrayList 一个线程安全的变种, 消除 ConcurrentModificationException . 安全: 所有的变化操作都通过底层复制一个新的数组实现. 思考: 相比ArrayList的空间,时间占用? 单线程情况和并发情况下. 思考: System.arraycopy为什么快? 一般来说代价较高,但是: 遍历操作远超过数据改动操作的情况下更加有效 遍历时不想或不可以使用 synchronize 消除并发干扰情况下更加有用 迭代器不支持 add , set , remove 允许null值 内存一致性: 和其他并发容器一样, 增加数据操作所在的线程先于访问或移除元素操作所在的其他线程 实现 增 : /** * 同步锁. 忽略序列化. */ final transient Object lock = new Object(); /** * 添加指定元素到列表尾端 */ public boolean add(E e) { // 增的时候,需要加锁. synchronized (lock) { Object[] elements =