mbr gpt

MBR GPT http://www.rodsbooks.com/linux-fs-code/ 自从 2007 年 Vista 操作系统推出以后, 各大硬件厂商对硬件开发速度明显加快, 其中对于硬盘的速度和容量, 从最早的 5400 转, 160G 容量, 提升到现在的 7200 转甚至万转机械盘, 容量也先后出现上 TB 级别的。单硬盘都出现 4Tb 容量。 由于磁盘容量越来越大, 传统的 MBR 分区表 (主引导记录) 已经不能满足大容量磁盘的需求。传统的 MBR 分区表只能识别磁盘前面的 2.2TB 左右的空间, 对于后面的多余空间只能浪费掉了,而对于单盘4TB的磁盘,只能利用一半的容量。因此,才有了GPT (全局唯一标识分区表) 。 除此以外,MBR分区表只能支持4个主分区或者3主分区+1扩展分区 (包含随意数目的逻辑分区) ,而GPT在Windows下面可以支持多达128个主分区。 下面IT之家也给大家分享下MBR和GPT的详细区别。 MBR 分区表 在传统硬盘分区模式中,引导扇区是每个分区 (Partition) 的第一扇区,而主引导扇区是硬盘的第一扇区。它由三个部分组成,主引导记录MBR、硬盘分区表DPT和硬盘有效标志。在总共512字节的主引导扇区里MBR占446个字节,第二部分是Partition table区 (分区表) ,即DPT,占64个字节,硬盘中分区有多少以及每一分区的大小都记在其中。第三部分是magic number,占2个字节,固定为55AA。 一个扇区的硬盘主引导记录MBR由4个部分组成。 •主引导程序 (偏移地址0000H-0088H) ,它负责从活动分区中装载,并运行系统引导程序。 •出错信息数据区,偏移地址0089H-00E1H为出错信息,00E2H-01BDH全为0字节。 •分区表 (DPT,Disk Partition Table) 含4个分区项,偏移地址01BEH-01FDH,每个分区表项长16个字节,共64字节为分区项1、分区项2、分区项3、分区项4。 •结束标志字,偏移地址01FE-01FF的2个字节值为结束标志55AA,如果该标志错误系统就不能启动。 GPT 分区表, GUID Partition Map GPT 的分区信息是在分区中,而不象 MBR 一样在主引导扇区, 为保护 GPT 不受 MBR 类磁盘管理软件的危害, GPT 在主引导扇区建立了一个保护分区 (Protective MBR) 的MBR分区表 (此分区并不必要), 这种分区的类型标识为0xEE, 这个保护分区的大小在Windows下为128MB,Mac OS X下为200MB,在Window磁盘管理器里名为GPT保护分区, 可让MBR类磁盘管理软件把GPT看成一个未知格式的分区,而不是错误地当成一个未分区的磁盘。 ...

2015-04-21 · 1 min · 114 words · -

SonarQube

SonarQube SonarQube (曾用名Sonar (声纳) [1]) 是一个开源的代码质量管理系统。 Sonar是一个用于代码质量管理的开源平台,用于管理源代码的质量,可以从七个维度检测代码质量 提供重复代码、编码标准、单元测试、代码覆盖率、代码复杂度、潜在Bug、注释和软件设计报告 通过插件形式,可以支持包括java,C#,C/C++,PL/SQL,Cobol,JavaScrip,Groovy等等二十几种编程语言的代码质量管理与检测 sonarQube能带来什么? Developers’ Seven Deadly Sins 1.糟糕的复杂度分布 文件、类、方法等,如果复杂度过高将难以改变,这会使得开发人员难以理解它们, 且如果没有自动化的单元测试,对于程序中的任何组件的改变都将可能导致需要全面的回归测试 2.重复 显然程序中包含大量复制粘贴的代码是质量低下的 sonar可以展示源码中重复严重的地方 3.缺乏单元测试 sonar可以很方便地统计并展示单元测试覆盖率 4.没有代码标准 sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具规范代码编写 5.没有足够的或者过多的注释 没有注释将使代码可读性变差,特别是当不可避免地出现人员变动时,程序的可读性将大幅下降 而过多的注释又会使得开发人员将精力过多地花费在阅读注释上,亦违背初衷 6.潜在的bug sonar可以通过PMD,CheckStyle,Findbugs等等代码规则检测工具检测出潜在的bug 7.糟糕的设计 (原文Spaghetti Design,意大利面式设计) 通过sonar可以找出循环,展示包与包、类与类之间的相互依赖关系 可以检测自定义的架构规则 通过sonar可以管理第三方的jar包 可以利用LCOM4检测单个任务规则的应用情况 检测耦合 关于Spaghetti Design: http://docs.codehaus.org/display/SONAR/Spaghetti+Design 通过sonar可以有效检测以上在程序开发过程中的七大问题 SonarQube安装 预置条件 1.已安装JAVA环境 2.已安装有MySQL数据库 软件下载地址: http://www.sonarqube.org/downloads/ 下载SonarQube与SonarQube Runner 中文补丁包下载: http://docs.codehaus.org/display/SONAR/Chinese+Pack 1.数据库配置 MySQL> CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci; MySQL> CREATE USER ‘sonar’ IDENTIFIED BY ‘sonar’; MySQL> GRANT ALL ON sonar.* TO ‘sonar’@’%’ IDENTIFIED BY ‘sonar’; ...

2015-02-12 · 2 min · 330 words · -

RPC, Message Queue, MQ

RPC, Message Queue, MQ http://oldratlee.com/post/2013-02-01/synchronous-rpc-vs-asynchronous-message RPC 和 MQ 的区别 系统结构 RPC系统结构: Consumer 调用的 Provider 提供的服务。 +———-+—–+———-+ | Consumer | <=> | Provider | +—-+—–+—–+———-+ Message Queue 系统结构: Sender 发送消息给 Queue; Receiver 从 Queue 拿到消息来处理。 +——–+—–+——-+—–+———-+ | Sender | <=> | Queue | <=> | Receiver | +——–+—–+——-+—–+———-+ 功能特点 在架构上, RPC 和 Message 的差异点是, Message 有一个中间结点 Message Queue, 可以存储消息。 消息的特点 Message Queue 缓存请求压力, 然后逐渐释放出来, 消费者可以按照自己的节奏处理数据。 Message Queue 引入一个新的结点, 系统的可靠性会受 Message Queue 的影响。 Message Queue 是异步单向的消息。发送消息设计成是不需要等待消息处理的完成。 所以对于有同步返回需求, 用 Message Queue 则变得麻烦了。 ...

2015-02-06 · 1 min · 163 words · -

remote dev

remote dev virtualbox windows 宿主机, archlinux 虚拟机, virtualbox 安装增强包, 使用 seamless mode vscode remote ssh jetbrain remote development beta 版本 不稳定. vm@server, xforward 延迟: 22ms 内存: 16G+ cpu: 8c 无线网带宽问题,延迟 编辑器内部纵向滚动屏幕带宽占用峰值2300KB/s vm@server, rdp Ubuntu 22.04 安装 xrdp 开放 3389 端口, win10 mstsc 连接到 3389, 拖动窗口有延迟, 编辑器内部纵向滚动屏幕延迟可以接受. 拖动窗口带宽占用峰值 1700KB/s, 编辑器内部纵向滚动屏幕带宽占用峰值500KB/s 延迟: 22ms 内存: 16G+ cpu: 8c vm@server, vnc 延迟: 22ms 内存: 16G+ cpu: 8c 图形界面延迟 基于像素的传输,画质不好. wsl + x server 延迟: <1ms 内存: 16G+ cpu: 4c 内存占用问题 wsl + idea 延迟: <1ms 内存: 16G+ cpu: 4c 磁盘性能问题 windows + idea 延迟: <1ms 内存: 16G+ cpu: 4c ansible,git,leveldb 问题

2015-02-05 · 1 min · 97 words · -

QNAP

QNAP qnap, plex server, apple tv, av1 https://www.reddit.com/r/PleX/comments/12pe5tx/comment/jgrrjnc/ https://github.com/currifi/plex_av1_tvos?tab=readme-ov-file https://support.plex.tv/articles/202915258-where-is-the-plex-media-server-data-directory-located/ https://www.qnap.com/en/how-to/faq/article/how-do-i-access-my-qnap-nas-using-ssh QNAP 启用 ssh 服务 ssh admin@192.168.50.227 # print The exact data directory location getcfg -f /etc/config/qpkg.conf PlexMediaServer Install_path mkdir /share/CACHEDEV1_DATA/.qpkg/PlexMediaServer/Library/Plex Media Server/Profiles # copy file https://github.com/scriptsingh/plex_av1_tvos/blob/main/tvOS.xml to Profiles dir 重启 plex server 威联通 nas web ui> app center> plex server stop start

2014-12-30 · 1 min · 53 words · -

mutex, 锁

mutex, 锁 Mutual exclusion (或者锁) 的实现有硬件实现和软件实现, 软件实现是通过一些特别的算法譬如 Peterson’s algorithm,这类软件实现通常比硬件实现需要更多的内存,而且由于现代计算机的乱序执行,需要手动加memory barrier来保证memory ordering,这里暂时不做讨论纯软件实现。CPU如果提供一些用来构建锁的atomic指令,一般会更高效一些。 锁的本质 所谓的锁,在计算机里本质上就是一块内存空间。当这个空间被赋值为1的时候表示加锁了,被赋值为0的时候表示解锁了,仅此而已。多个线程抢一个锁,就是抢着要把这块内存赋值为1。在一个多核环境里,内存空间是共享的。每个核上各跑一个线程,那如何保证一次只有一个线程成功抢到锁呢?你或许已经猜到了,这必须要硬件的某种 guarantee。具体的实现如下。 硬件 CPU如果提供一些用来构建锁的 atomic 指令, 譬如 x86 的 CMPXCHG (加上LOCK prefix), 能够完成 atomic 的 compare-and-swap (CAS), 用这样的硬件指令就能实现 spin lock. 本质上 LOCK 前缀的作用是锁定系统总线 (或者锁定某一块cache line) 来实现atomicity,可以了解下基础的缓存一致协议譬如MSEI。简单来说就是,如果指令前加了LOCK前缀,就是告诉其他核,一旦我开始执行这个指令了,在我结束这个指令之前,谁也不许动。缓存一致协议在这里面扮演了重要角色,这里先不赘述。这样便实现了一次只能有一个核对同一个内存地址赋值。 操作系统 mutex在linux内核中由 futex 系统调用支撑,如果没有竞争不需要陷入内核;内核的主要是 futex_wait/wake 函数配合上层完成业务逻辑; 一个 spin lock 就是让没有抢到锁的线程不断在 while 里面循环进行 compare-and-swap, 燃烧CPU, 浪费青春, 直到前面的线程放手 (对应的内存被赋值0) 。这个过程不需要操作系统的介入,这是运行程序和硬件之间的故事。如果需要长时间的等待,这样反复CAS轮询就比较浪费资源,这个时候程序可以向操作系统申请被挂起,然后持锁的线程解锁了以后再通知它。这样CPU就可以用来做别的事情,而不是反复轮询。 但是OS切换线程也需要一些开销,所以是否选择被挂起,取决于大概是否需要等很长时间,如果需要,则适合挂起切换为别的线程。线程向操作系统请求被挂起是通过一个系统调用,在linux上的实现就是 futex, 宏观来讲, OS需要一些全局的数据结构来记录一个被挂起线程和对应的锁的映射关系,这样一个数据结构天然是全局的,因为多个OS线程可能同时操作它。所以,实现高效的锁本身也需要锁。有没有一环套一环的感觉?futex的巧妙之处就在于,它知道访问这个全局数据结构不会太耗时,于是futex里面的锁就是spin lock。linux上pthread mutex 的实现就是用的 futex 。更多精彩内存参考talk: https://www.infoq.com/presentations/go-locks/ 用户态的锁 像Goroutine线程就是go runtime来调度的,而不是OS,所以go routine线程切换的开销要远小于OS线程切换的开销。Goroutine的本质就是一个coroutine,这种轻量的线程在很多语言的runtime里面都有实现。最近Java也有了 (project loom) 。 ...

2014-11-19 · 3 min · 484 words · -

ASCII

ASCII Dec Hex Char 10 0A LF 13 0D CR 32 20 Space 35 30 # 48 30 0 57 39 9 58 3A : 65 41 A 66 42 B 67 43 C 70 46 F 73 49 I 90 5A Z 97 61 a 101 65 e 102 66 f 115 73 s 122 7A z 124 7C | ASCII字符集,最基本的包含了128个字符。其中前32个,0-31,即0×00-0x1F,都是不可见字符。这些字符,就叫做控制字符。 这些字符没法打印出来,但是每个字符,都对应着一个特殊的控制功能的字符,简称功能字符或功能码Function Code。 简言之: ASCII中前32个字符,统称为Function Code功能字符。 此外,由于ASCII中的127对应的是Delete,也是不可见的,所以,此处根据笔者的理解,也可以归为Function Code。 此类字符,对应不同的"功能",起到一定的"控制作用",所以,称为控制字符。 ...

2014-03-05 · 1 min · 79 words · -

cpu 占用分析

cpu瓶颈分析 #系统的平均负载 uptime # 每个 CPU 的使用情况 mpstat # 每个进程 CPU 的使用情况 pidstat stress stress https://www.hi-linux.com/posts/59095.html https://www.infoq.cn/article/5jjIdOPx12RWWvGX_H9J?utm_source=rss&utm_medium=article http://9leg.com/java/2016/08/09/cpu-consumption-analysis.html 通常性能瓶颈的表现是资源消耗过多、外部处理系统的性能不足,或者资源消耗不多,但程序的响应速度却达不到要求。 资源主要消耗在cpu,io (又分文件io和网络io) ,内存方面,机器的资源是有限的,当某资源消耗过多时,通常会造成系统的响应速度变慢。 对于java应用而言,寻找性能瓶颈的方法通常为首先分析资源的消耗,然后结合java的一些工具来查找程序中造成资源消耗过多的代码。 今天先谈一谈cpu消耗如何分析,系统为linux,jdk为sun jdk。 在linux中,cpu主要用于中断、内核和用户进程的任务处理,优先级为中断>内核>用户进程,下面先讲述三个重要的概念。 上下文切换 每个cpu (多核cpu中的每个cpu) 在同一时间只能执行一个线程,linux采用的是抢占式调度。为每个线程分配一定的执行时间, 当到达执行时间、线程中有io阻塞或高优先级的线程要执行时,linux将切换执行的线程,在切换时要存储目前的线程的执行状态, 并恢复要执行的线程的状态,这个过程就是上下文切换。对于java应用而言,典型的是在进行文件io操作、网络io操作、锁等待或者线程sleep时, 当前线程会进入阻塞或休眠状态,从而触发上下文切换,上下文切换过多会造成内核占据较多的cpu使用,从而使应用响应速度变慢。 运行队列 每个cpu核都会维护一个可运行的线程队列,例如一个4核的cpu,java应用里启动了8个线程,且这8个线程都处于可运行状态, 那么在分配平均的情况下每个cpu中的运行队列就会有2个线程。通常而言,系统的load主要由cpu运行队列来决定。 利用率 cpu利用率为cpu在用户进程、内核、中断处理、io等待以及空闲5个部分使用的百分比,这5个值是用来分析cpu消耗的关键指标。 在linux中,可通过top或pidstat方式来查看进程中线程的cpu的消耗状况。 top 输入top命令后既可查看cpu的消耗情况,cpu的信息在top视图的上面几行中 对于多个或多核cpu,上面的显示则会是多个cpu所占用的百分比总合。如需查看每个核的消耗情况,可在进入top视图后按1,就会按核来显示消耗情况。 cpu-top 默认情况下,top视图中显示的为进程的cpu消耗状况,在top视图中按shift + h后,可按线程查看cpu的消耗状况,此时的pid既为线程id。 pidstat sy过高 当sy值过高时,表示linux花费了更多的时间在进行线程切换。java应用造成这种现象的主要原因是启动的线程比较多, 且这些线程多处于不断的阻塞 (例如锁等待,io等待) 和执行状态的变化过程中,这就导致了操作系统要不断的切换执行的线程, 产生大量的上下文切换。在这种情况下,对java应用而言,最重要的是找出不断切换状态的原因, 可采用的方法为通过kill -3 pid 或jstack -l pid的方法dump出java应用程序的线程信息,查看线程的状态信息以及锁信息, 找出等待状态或锁竞争过多的线程。 进程和线程的上下文切换都涉及进出系统内核和寄存器的保存和还原,这是它们的最大开销。但与进程的上下文切换相比,线程还是要轻量一些, 最大的区别是线程上下文切换时虚拟内存地址保持不变,所以像TLB等CPU缓存不会失效。但要注意的是另一份提问 What is the overhead of a context-switch?的中提到了: Intel和AMD在2008年引入的技术可能会使TLB不失效。 ...

2013-12-10 · 1 min · 72 words · -

How browsers work

How browsers work http://taligarsiel.com/Projects/howbrowserswork1.htm http://ux.sohu.com/topics/50972d9ae7de3e752e0081ff

2013-06-10 · 1 min · 5 words · -

Spinlock(自旋锁), Ticket Spinlock, MCS Spinlock

Spinlock(自旋锁), Ticket Spinlock, MCS Spinlock 为什么要加锁 在 SMP 系统中,如果仅仅是需要串行地增加一个变量的值,那么使用原子操作的函数 (API) 就可以了。但现实中更多的场景并不会那么简单,比如需要将一个结构体A中的数据提取出来,然后格式化、解析,再添加到另一个结构体B中,这整个的过程都要求是「原子的」,也就是完成之前,不允许其他的代码来读/写这两个结构体中的任何一个。 这时,相对轻量级的原子操作API就无法满足这种应用场景的需求了, 我们需要一种更强的同步/互斥机制,那就是软件层面的「锁」的机制。 同步锁的「加锁」和「解锁」是放在一段代码的一前一后,成对出现的,这段代码被称为 Critical Section / Region (临界区) 。但锁保护的并不是这段代码本身,而是其中使用到的多核/多线程共享的变量,它「同步」(或者说串行化) 的是对这个变量的访问,通俗的语义就是“我有你就不能有,你有我就不会有”。 Linux中主要有两种同步锁,一种是 spinlock,一种是 mutex. spinlock 和 mutex 都既可以在用户进程中使用,也可以在内核中使用,它们的主要区别是: 前者不会导致睡眠和调度,属于 busy wait 形式的锁, 后者可能导致睡眠和调度,属于 sleep wait 形式的锁。 spinlock 是最基础的一种锁,像后面将要介绍的 rwlock(读写锁), seqlock(读写锁)等都是基于spinlock衍生出来的。就算是 mutex,它的实现与spinlock 也是密不可分。因此,本系列文章将首先围绕 spinlock展开介绍。 如何加锁 Linux 中 spinlock 机制发展到现在,其实现方式的大致有3种。 第一种实现 - 经典的 CAS 最古老的一种做法是: spinlock 用一个整形变量表示,其初始值为1,表示 available 的状态。当一个CPU (设为CPU A) 获得spinlock后,会将该变量的值设为0,之后其他CPU试图获取这个 spinlock 时,会一直等待,直到 CPU A 释放 spinlock, 并将该变量的值设为1。 那么其他的 CPU 是以何种形式等待的,如果有多个CPU一起等待,形成了竞争又该如何处理? 这里要用到经典的 CAS 操作 (Compare And Swap) 。 ...

2013-06-01 · 2 min · 330 words · -

The MIT License

The MIT License http://baike.baidu.com/view/3159946.htm MIT许可证 (The MIT License) 是许多软件授权条款中,被广泛使用的其中一种。与其他常见的软件授权条款 (如GPL、LPGL、BSD) 相比,MIT是相对宽松的软件授权条款。MIT许可证之名源自麻省理工学院 (Massachusetts Institute of Technology, MIT) ,又称"X条款" (X License) 或"X11条款" (X11 License) MIT内容与三条款BSD许可证 (3-clause BSD license) 内容颇为近似,但是赋予软件被授权人更大的权利与更少的限制。有许多团体均采用MIT许可证。例如著名的ssh连接软件PuTTY与X Windows System (X11)即为例子。Expat, Mono开发平台库,Ruby on Rails, Lua 5.0 onwards等等也都采用MIT授权条款。被授权人权利 被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本。 被授权人可根据程序的需要修改授权条款为适当的内容。 被授权人义务 在软件和软件的所有副本中都必须包含版权声明和许可声明。 其他重要特性 此授权条款并非属copyleft的自由软件授权条款,允许在自由/开放源码软件或非自由软件 (proprietary software) 所使用。 MIT的内容可依照程序著作权者的需求更改内容。此亦为MIT与BSD (The BSD license, 3-clause BSD license) 本质上不同处。 MIT条款可与其他授权条款并存。另外,MIT条款也是自由软件基金会 (FSF) 所认可的自由软件授权条款,与GPL兼容。

2013-04-01 · 1 min · 56 words · -

Lua

Lua http://zh.wikipedia.org/zh-cn/Lua http://baike.baidu.com/view/416116.htm Lua ( /ˈluːə/ ) 程序设计语言是一个简洁、轻量、可扩展的脚本语言,是葡萄牙语中"Luna" (月亮) 的意思。 Lua 是一个动态弱类型语言,支援增量式垃圾收集策略。有内建的,与操作系统无关的协作式多线程 (coroutine) 支持 Lua的目标是成为一个很容易嵌入其它语言中使用的语言。大多数程序员也认为它的确做到了这一点。 很多应用程序使用Lua作为自己的嵌入式脚本语言,以此来实现可配置性、可扩展性。这其中包括大话西游II、仙境传说、魔兽世界、战锤40k、博德之门、轩辕剑外传汉之云、愤怒的小鸟等。 Lua是一种轻量语言,它的官方版本只包括一个精简的核心和最基本的库。这使得Lua体积小、启动速度快。它用标准C语言编写并以源 代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程式里。和许多"大而全"的语言不一样,网路通讯、图形界面等都没有默认提供。但是Lua可以很 容易地被扩展: 由宿主语言 (通常是C或C++) 提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。事实上,现在已经有很多成熟的扩展模块可供选用。 Lua是一种多重编程范式的程式设计语言: 它只提供了很小的一个特性集合来满足不同编辑范式的需要,而不是为某种特定的编辑范式提供繁杂的特性支援。例如,Lua并不提供继承这个特性,但是你可以用元表来模拟它。诸如名字空间、类这些概念都没有在语言基本特性中实现,但是我们可以用表结构 (Lua唯一提供的复杂数据结构) 轻易模拟。Lua可以在运行时随时构造出一个函数,并把它看作一个对象 (正是所谓的first class function) ,这个特性可以很好的满足函数式编程的需要。这是提供了这些基本的元特性,我们可以任意的对语言进行自需的改造。 Lua 原生支援的数据类型非常之少,它只提供了数字 (缺省是双精度浮点数,可配置) 、布尔量、字符串、表、子程序、协程 (coroutine) 以及用户自定义数据这几种。但是其处理表和字符串的效率非常之高,加上元表的支援,我们可以高效的模拟出需要的复杂数据类型 (比如集合、数组等) 。

2013-02-13 · 1 min · 38 words · -

快速匹配字符串

快速匹配字符串 假设内存有一个大字符串集,里面含有约1000万个字符串,如何快速知道该字符串集是否含有某个指定的测试字符串 ? (假设内存能放下这么多字符串) 方法一: hashCode法 方法二: Trie树 http://zh.wikipedia.org/wiki/Trie HashCode法 01 def sampleHashMap(strSet: Set[String]): Map[Int, Set[String]]={ 02 strSet.groupBy{ 03 s => s.hashCode 04 } 05 } 06 07 def contain(str: String, sampleMap: Map[Int, Set[String]]): Boolean = { 08 sampleMap.getOrElse(str.hashCode, Set[String]()).exists(_ equals str) 09 } 10 11 // 测试 12 val sampleSet = Set("a","b","c","AA","Archer","Jack"); 13 val sampleMap = sampleHashMap(sampleSet); 14 println(contain("Archer", sampleMap)); // true 15 println(contain("A", sampleMap)); // false 16 println(contain("a", sampleMap)); // true Trie树法 01 sealed abstract class Trie { 02 def contains(msg: String): Boolean = contains(msg, this) 03 04 @scala.annotation.tailrec 05 private def contains(msg: String, trie: Trie): Boolean = (msg, trie) match { 06 case (null, _ ) | (_ , null ) => false 07 case (StringCase(head, tail), TrieNode(edges)) => edges.get(head) match { 08 case None => false 09 case Some(subTrie) => contains(tail,subTrie) 10 } 11 case (StringCase(_,_), TrieLeaf()) => false 12 case _ => true 13 } 14 } 15 16 case class TrieNode(edges: Map[Char, Trie]) extends Trie{ 17 assert(edges.size > ) 18 } 19 case class TrieLeaf extends Trie 20 21 object StringCase{ 22 def unapply(s: String): Option[(Char, String)] ={ 23 if (s == null || s == "" ) None 24 else Some(s.head, s.tail) 25 } 26 } 27 28 object Trie{ 29 30 def apply(strs: String*): Trie ={ 31 apply(strs.toSet); 32 } 33 34 def apply(strSet: Set[String]) : Trie = { 35 if (strSet.size == || strSet == Set("")) TrieLeaf() 36 else { 37 val char2TrieSet = strSet.filter(_.length > ).groupBy(_.head).mapValues{ 38 strs => strs.map(_.tail) 39 }.mapValues{ 40 strs => apply(strs) 41 } 42 TrieNode(char2TrieSet); 43 } 44 } 45 46 } 47 48 val trie= Trie("abc","ac","b") 49 println(trie) 50 assert(trie.contains("") == true); // true 51 assert(trie.contains(null) == false); //false 52 assert(trie.contains("a") == true); // true 53 assert(trie.contains("b") == true); // true 54 assert(trie.contains("ab") == true); //true 55 assert(trie.contains("ac") == true); //true 56 assert(trie.contains("abc") == true); //true 57 assert(trie.contains("acb") == false); // false 58 assert(trie.contains("abcd") == false); //false 59 assert(trie.contains("bc") == false); //false

2012-11-26 · 2 min · 328 words · lcf

Lambda 表达式

Lambda 表达式 “Lambda 表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型。 所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为"goes to”。该 Lambda 运算符的左边是输入参数 (如果有) ,右边包含表达式或语句块。Lambda 表达式 x => x * x 读作"x goes to x times x"。 函数式接口functional interface, @FunctionalInterface 函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。 这类接口只定义了唯一的抽象方法的接口 (除了隐含的Object对象的公共方法) , 因此最开始也就做SAM类型的接口 (Single Abstract Method) 。 为什么会单单从接口中定义出此类接口呢? 原因是在 Java Lambda 的实现中, 开发组不想再为Lambda表达式单独定义一种特殊的Structural函数类型,称之为箭头类型 (arrow type) , 依然想采用Java既有的类型系统(class, interface, method等), 原因是增加一个结构化的函数类型会增加函数类型的复杂性,破坏既有的Java类型,并对成千上万的Java类库造成严重的影响。 权衡利弊, 因此最终还是利用SAM 接口作为 Lambda表达式的目标类型。 JDK中已有的一些接口本身就是函数式接口,如Runnable。 JDK 8中又增加了java.util.function包, 提供了常用的函数式接口。 函数式接口代表的一种契约, 一种对某个特定函数类型的契约。 在它出现的地方,实际期望一个符合契约要求的函数。 Lambda表达式不能脱离上下文而存在,它必须要有一个明确的目标类型,而这个目标类型就是某个函数式接口。 方法引用 (method reference) 双冒号 “::” 是 Java 8 引入 Lambda 表达式后的一种用法,表示方法引用 (method reference) ,可以更加简洁的实例化接口 双冒号表达式返回的是一个 函数式接口对象 (用 @FunctionalInterface 注解的 interface 类型) 的实例,如下: ...

2012-11-17 · 5 min · 1020 words · -

消息队列/message queue/MQ, CORBA, DCOM, RMI, RPC

消息队列/message queue/MQ, CORBA, DCOM, RMI, RPC http://blog.csdn.net/mr_smile2014/article/details/47452281 消息队列是在消息的传输过程中保存消息的容器,消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。 一、 产生背景: 现今,越来越多的企业面临着各种各样的数据集成和系统整合,CORBA、DCOM、RMI 等RPC中间件技术也应运而生,但由于采用RPC同步处理技术,在性能、健壮性、可扩展性上都存在着诸多缺点。而基于消息的异步处理模型采用非阻塞的调用特性,发送者将消息发送给消息服务器,消息服务器在合适的时候再将消息转发给接收者;发送和接收是异步的,发送者无需等待,二者的生命周期也可以不必相同,而且发送者可以将消息间接传给多个接收者,大大提高了程序的性能、可扩展性及健壮性,这使得异步处理模型在分布式应用上比起同步处理模型更具有吸引力。 分布式对象调用,如CORBA,RMI 和DCOM,提供了一种通讯机制,透明地在异构的分布式计算环境中传递对象请求,这些对象可以位于本地或远程机器。它通过在对象与对象之间提供一种统一的接口,使对象之间的调用和数据共享不再关心对象的位置、实现语言及所驻留的操作系统。这个接口就是面向对象的中间件。 二、传统面向对象中间件的局限性 同步通信: 客户发出调用后,必须等待服务对象完成处理并返回结果后才能继续执行。 客户和服务对象的生命周期紧密耦合: 客户进程和服务对象进程都必须正常运行,如果由于服务对象崩溃或网络故障导致客户的请求不可达,客户会接收到异常。 三、面向消息的中间件的优越性 消息中间件作为一个中间层软件, 它为分布式系统中创建、发送、接收消息提供了一套可靠通用的方法,实现了分布式系统中可靠的、高效的、实时的跨平台数据传输。消息中间件减少了开发跨平台和网络协议软件的复杂性,它屏蔽了不同操作系统和网络协议的具体细节,面对规模和复杂度都越来越高的分布式系统。它与传统的面向对象中间件相比具有如下优点: 采用异步通信模式: 发送消息者可以在发送消息后进行其它的工作,不用等待接收者的回应,而接收者也不必在接到消息后立即对发送者的请求进行处理。 客户和服务对象生命周期的松耦合关系: 客户进程和服务对象进程不要求都正常运行,如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户不会接收到异常,消息中间件能保证消息不会丢失。 四、消息中间件的技术标准 消息中间件主要有JMS和AMQP两种技术标准; JMS Java关于消息服务的标准是JMS,JMS即Java消息服务 (Java Message Service) 应用程序接口是一个Java平台中关于面向消息中间件 (MOM) 的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,类似于JDBC,需要不同的提供商进行各自的实现。实现JMS标准的软件可以作为Java下的消息中间件服务器。JMS 使您能够通过消息收发服务 (有时称为消息中介程序或路由器) 从一个 JMS 客户机向另一个 JMS客户机发送消息。消息是 JMS中的一种类型对象,由两部分组成: 报头和消息主体。报头由路由信息以及有关该消息的元数据组成。消息主体则携带着应用程序的数据或有效负载。根据有效负载的类型来划分,可以将消息分为几种类型,它们分别携带: 简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage),还有无有效负载的消息 (Message)。 AMQP AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同开发语言等条件的限制。Erlang中的实现有 RabbitMQ等。

2012-11-15 · 1 min · 56 words · -

Smalltalk

Smalltalk Smalltalk被公认为历史上第二个面向对象的程序设计语言和第一个真正的集成开发环境 (IDE)。由Alan Kay,Dan Ingalls,Ted Kaehler,Adele Goldberg等于70年代初在Xerox PARC开发。Smalltalk对其它众多的程序设计语言的产生起到了极大的推动作用,主要有: Objective-C,Actor, Java 和Ruby等。90年代的许多软件开发思想得利于Smalltalk,例如Design Patterns, Extreme Programming(XP)和Refactoring等。 Smalltalk和许多程序设计语言不同,它不仅仅是一门语言。 一种面向对象的程序设计语言: 它是一种面向对象的语言,包含语言的语法和语义。一些编译器可以通过 Smalltalk 源程序产生可执行文件。这些编译器通常产生一种能在虚拟机上运行的二进制代码。Smalltalk语言本身非常精炼。 一种程序设计环境: 这里指的是一种提供许多 对象 的系统,而不是某种特殊的开发环境。和许多语言不同(包括C++),Smalltalk附带有一个巨大的、相当标准的类库。这些 类 使得开发Smalltalk程序的效率非常高。在其它语言 (例如 Ada , C 和 Pascal ) 中通常被作为语言的一部分的功能 (例如条件判断,循环等),在Smalltalk由特定的类提供。 **一个应用开发环境(ADE):**由于Smalltalk的历史原因,它具有一个非常优秀的高度集成、开放的应用开发环境。由于开发环境中的浏览器、监视器以及调试器都由同样的源程序衍生出来的,不同的版本之间也具有相当好的兼容性。此外,这些工具的源程序都可以在ADE直接存取。

2012-11-04 · 1 min · 35 words · -

Java中的instanceof关键字

Java中的instanceof关键字 instanceof是Java的一个二元操作符,和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子: String s = “I AM an Object!”; boolean isObject = s instanceof Object; 我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。 instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类: public class Bill {//省略细节} public class PhoneBill extends Bill {//省略细节} public class GasBill extends Bill {//省略细节} 在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断: public double calculate(Bill bill) { if (bill instanceof PhoneBill) { //计算电话账单 } if (bill instanceof GasBill) { //计算燃气账单 } … } 这样就可以用一个方法处理两种子类。 然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了: public double calculate(PhoneBill bill) { //计算电话账单 } public double calculate(GasBill bill) { //计算燃气账单 } ...

2012-10-31 · 1 min · 72 words · -

dictionary

dictionary ‘CMMI 配置库’ 配置项,就一个项目整个的生命周期过程中,所产生的一切文档、程序以及需要进行控制的项目。 那么这些配置项所保存、管理的一个地方,就叫配置库。 配置库,有逻辑上的意义,也有物理上的意义 逻辑上,就是上文所说的 物理上,就是一些用来做配置管理的软件系统,比如说VSS之类 通过这些配置管理软件,对配置项进行管理和控制,那么整个软件系统就可以称作配置库。 阿特金森循环 这一名词早在1880年就存在了.是一种高压缩比,长膨胀行程的内燃机工作循环。 因为这种循环结构比较复杂,所以大家都选用了奥托循环式的发动机. 发动机理论最典型的就是吸气-压缩-燃烧膨胀-排气的循环.而奥托注册了许多专利,所以阿特金森不得不研发一种不使用正时带和凸轮轴的内燃机. 阿特金森发动机巧妙的只用一个飞轮带曲柄连杆机构实现了4个冲程. 阿特金森发动机的特点是使燃烧在气缸中的油/气混合物的体积膨胀得更大,借此让动力装置能更高效地利用燃油。 而现代阿特金森循环发动机(Atkinson cycle engine)使用电子控制装置和进气阀定时装置,通过推迟进气门关闭,在压缩冲程从进气门排出部分燃气,减少进气量,从而实现膨胀比大于压缩比,提高燃油利用率,达到节油的目的。 马克思发生器 马克思发生器 (Marx Generator) 是一种利用电容并联充电再串联放电的高压装置,该结构由E.Marx于1924年提出,它能模仿雷电及操作过电压等过程。 所以经常用于绝缘冲击耐压及介质冲击击穿、放电等试验中。 Mercurial Mercurial 是一种轻量级分布式版本控制系统,采用 Python 语言实现,易于学习和使用,扩展性强。相对于传统的版本控制,具有如下优点: 更轻松的管理。 传统的版本控制系统使用集中式的 repository,一些和 repository 相关的管理就只能由管理员一个人进行。由于采用了分布式的模型,Mercurial 中就没有这样的困扰,每个用户管理自己的 repository,管理员只需协调同步这些repository。 更健壮的系统。 分布式系统比集中式的单服务器系统更健壮,单服务器系统一旦服务器出现问题整个系统就不能运行了,分布式系统通常不会因为一两个节点而受到影响。 对网络的依赖性更低。 由于同步可以放在任意时刻进行,Mercurial 甚至可以离线进行管理,只需在有网络连接时同步。 Redmine Redmine 是一个开源的、基于Web的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示。同时它又支持多项目管理。Redmine是一个自由开放 源码软件解决方案,它提供集成的项目管理功能,问题跟踪,并为多个版本控制选项的支持。 虽说像IBM Rational Team Concert的商业项目调查工具已经很强大了,但想坚持一个自由和开放源码的解决方案,可能会发现Redmine是一个有用的Scrum和敏捷的选择。 由于Redmine的设计受到Rrac的较大影响,所以它们的软件包有很多相似的特征。 Redmine建立在Ruby on Rails的框架之上,支持跨平台和多种数据库。。 Erlang Erlang 是一种通用的面向并发的编程语言,它由瑞典电信设备制造商爱立信所辖的 CS-Lab 开发,目的是创造一种可以应对大规模并发活动的编程语言和运行环境。Erlang是一个结构化,动态类型编程语言,内建并行计算支持。最初是由爱立信专门为通信应用设计的,比如控制交换机或者变换协议等,因此非常适 合于构建分布式,实时软并行计算系统。 使用 Erlang 编写出的应用运行时通常由成千上万个轻量级进程组成,并通过消息传递相互通讯。进程间上下文切换对于Erlang来说仅仅只是一两个环节,比起C程序的线程切换要高效得多得多了。 使用Erlang来编写分布式应用要简单的多,因为它的分布式机制是透明的: 对于程序来说并不知道自己是在分布式运行。 Erlang运行时环境是一个虚拟机,有点像Java虚拟机,这样代码一经编译,同样可以随处运行。它的运行时系统甚至允许代码在不被中断 的情况下更新。另外如果你需要更高效的话,字节代码也可以编译成本地代码运行。 Yaws: 一个Erlang写的服务器,据说并发性能是apache的15倍Erlang得名于丹麦数学家及统计学家Agner Krarup Erlang,同时Erlang还可以表示Ericsson Language。 ...

2012-10-26 · 4 min · 645 words · -

图像二值化

图像二值化 就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果。 将256个亮度等级的灰度图像通过适当的阈值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,首先,图像的二值化有利于图像的进一步处理,使图像变得简单,而且数据量减小,能凸显出感兴趣的目标的轮廓。其次,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像。 所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。

2012-09-30 · 1 min · 4 words · -

回车, 换行符, CRLF, LF

回车, 换行符, CRLF, LF 换行 line feed, LF, newline, \n, ascii 码: 0x0A 回车, carriage return, CR, return, \r, ascii 码: 0x0D CRLF, Carriage return & line feed unix: 换行, \n windows: 换行(回车+换行), \r\n, Unix/Mac 下打开会显示成 ^M macos: Line Feed, LF https://blog.csdn.net/wjcquking/article/details/6634504 回车符号和换行符号产生背景 关于"回车" (carriage return) 和"换行" (line feed) 这两个概念的来历和区别。 在计算机还没有出现之前,有一种叫做电传打字机 (Teletype Model 33) 的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做"回车",告诉打字机把打印头定位在左边界;另一个叫做"换行",告诉打字机把纸向下移一行。 这就是"换行"和"回车"的来历,从它们的英语名字上也可以看出一二。 后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。 Unix系统里,每行结尾只有"<换行>",即"\n";Windows系统里面,每行结尾是" <回车><换行>",即"\r\n";Mac系统里,每行结尾是"<回车>"。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在 Unix/Mac 下打开的话,在每行的结尾可能会多出一个^M符号 windows创建的文件是 \n\r 结束的, 而linux,mac这种unix类系统是\n结束的。 所以unix的文本到windows会出现换行丢失 (ultraedit这种软件可以正确识别) ; 而反过来就会出现^M的符号了 ...

2012-09-27 · 1 min · 138 words · -