`
airu
  • 浏览: 267127 次
  • 性别: Icon_minigender_1
  • 来自: 云南
社区版块
存档分类
最新评论
文章列表

汉诺塔

汉诺塔相信大家都听过,而且也知道用递归来求解。 今天面试,突然问到这个,并要求写出代码,至少是伪代码。 一下子比较晕。仔细想了下,差点把汉诺塔搞错了。一下来自百科 “汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。” 现在,我们考虑如何使用递归。递归有个特点,那就是,上层把问题交给下层,直到最后可以很快求解时,再递归返回上层,得到答案。这个问题, ...
对于一个初学者来说,往往容易滥用类。一切皆类,所以,类在设计中便爆炸般增长了。 对于这类问题,我们有很多模式来解决,但是我认为根本的还是要搞清楚,什么时候可以创建一个新的类。Martin大叔的 重构,Kent大叔的TDD,都给我们提出了一些解决方法。 这里我们不讨论这么高深的问题,而是从GOF的设计模式入手,来看看,类是如何泛滥,又是如何通过桥接来解决的。这也正是面向对象中的关键之处。 桥接,顾名思义,在接口与实现之间,架设一座桥梁,这座桥,其实并非是为了过河,而是隔离接口与实现。这就是著名的OO原则:DIP,ISP,依赖倒置(细节依赖抽象,抽象不依赖细节,接口隔离)。下面看桥接的UML: ...
适配器模式是最常用的设计模式之一。我们随处可以见到他的身影。例如Android中的某些监听器接口,还有著名的ListAdapter。 适配器模式,实际上是一个接口转换模式。也就是我们要把一个接口转换为另外一个接口。也许你要问 ...

NIO 再复习

java 的IO,在cpu越来越牛逼过程中,渐渐变得不协调了。cpu超快,性能都卡在IO上了。书上比喻:操作系统用卡车运数据,Java IO用铲子铲。。。很形象。有人说,我们可以通过JNI来提升IO啊,但是如果这样,我们就牺牲了java平台的独立性。你的代码就要和具体的操作系统绑定了。NIO通过新的设计和直接内存访问,提供高速IO。具体的NIO到底如何提升java的IO,呢,我们下面就深入了解NIO。 一、缓冲区操作: 缓冲区对于基本I/O来说,是十分重要的概念。从上层来说,I/O的基本就是把数据填充缓冲区,或者从缓冲区取出。对于底层操作系统来说,可能是很复杂的事情。看图: 可以看到,缓 ...
UML中有个图叫状态图,描述了对象的状态。 一般来说,对于有状态的对象,在处理动作时,会根据不同的状态得到不同的行为结果。 比如说,一扇旋转门,我们推,如果是关闭的,那么他就打开,如果我们再推,他就关闭。 State设计模式,通过把状态封装,通过接口隔离,使得我们不需要用if else等语句硬编码。缺点是如果状态过多,那么将会有很多的状态类。 状态模式的UML如下图所示: 下面通过一个开关程序来说明状态模式。 这个开光类似遥控器上的开机,关机,当机器是开的状态时,他执行关闭,当机器是关闭的状态时,他执行打开动作。 电视类(一个可以拥有状态的类,可以实现一个 Stateable接口,不过 ...
单例模式,应该是最简单但是也是用得很多的模式。 当然,这个模式的实现也是五花八门,如果要考虑多种场合,那么也是非常的精彩。 目前,很多这方面的文章写的也很好。我真的就不想班门弄斧了。 所以连接如下:http://www ...
设模技式中,往往都是通过增加一个中间层,解决问题。 代理模式。本身就很清楚,代理就是要控制所代理的产品,或者是商品。那么对于面向对象来说,代理,就是要控制对象了。这种控制,不论是处于什么原因,事实就是,我们可能需要控制一些对象的行为,增加些行为调前的处理或者调用后的处理等等。 如果仅从方法上看,感觉更像是拦截器。拦截一个方法,从中加入一些我们需要的东西。这么一说,就比如,我们在调用对象行为的时候,希望能记录日志,但是不用每次都在调用之前去打印这些日志,那么我们就可以通过代理模式来完成。这也是AOP编程的思想。 下面我们来看看UML吧。 从图中可以看到,实际上就是两个实现相同接口的类,一个 ...
每一个模式,如果乍一看,可能都很好理解,但是却不知所用。 一个好的模式,是从实践中的出来的,所以,要想很好的理解模式,就必须做很多的实际工作,在这些工作中去体会模式为什么是这样的。     事实上,当这些所谓的模式被抽象出来以后,就很难还原这个模式所解决问题的场景了。于是我们看到的都是些教学例子,看起来简单,实际上却并不理想,很可能看完就忘记了。     好了废话不多说,我并非是说理的,只是整理一下一些常用的设计模式,并加上自己的看法罢了,留作日后好查阅。     今天来说说命令模式吧。这个模式一直是比较模糊的,感觉没什么东西,就记得有个命令接口,里面放个execute方法。网上很多网友说都说, ...

我为什么跳槽

说起跳槽,如果别人问我,我最多是学学开复,follow my heart 罢了。最近面试,被问得最多的也就是你为什么平均每年换一家公司。其实我也从来没有深刻的反思,就算曾经想过,也没有给出答案。今天突然和朋友聊天,才若有所 ...
自从有了git,很多开源项目都转移到了git。对于我们初学版本管理的人来说,git和SVN究竟有什么不同的地方呢?最近粗略了解了下git,并与SVN做了一番比较,大概结果如下: SVN VS git 一,集中式 VS 分布式 SVN是典型的C/S模式的集 ...

线程队列

队列很常见,但是如果我们考虑在多线程环境中,那么可能就要注意同步互斥了。 这里使用读写锁,可以在读的时候不需要锁住整个队列。但是添加到队列就必须用互斥的锁了。 这里就介绍一下读写锁。pthread_rwlock_t lock定义一个读写锁lock,同样注意要初始化。 用 pthread_rwlock_init(&lock) 来初始化 lock。 下面来看一个列子,使用双向链表实现队列。可以从头添加或者从尾添加。 th_queue.h #ifndef TH_QUEUE_H #define TH_QUEUE_H #endif struct task{ struct ta ...

初识Linux线程

Linux的线程也是曲折的,2.4内核的时候居然线程使用进程来实现。不过2.6内核我是没看到有什么诡异的了。线程是线程,进程是进程。 为什么要线程呢? 线程的切换,不需要切换进程的上下文,比如N多寄存器值的保存。所以是轻量级的。速度也更快,但是同时也带来很多问题,比如同步。 现在让我们来简单看看Linux的线程吧。 下面的程序,通过多线程,并且互斥来对一个变量累加。 #include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<unistd.h> #include ...

管道管道管道

Unix的管道真的是很方便,我们经常这样用: $ls -l|wc -l 用于统计一个目录下的文件数。这里如果详细说起来,涉及了进程组,会话的概念。当然最显眼的就是符号 | ,这是就是管道,下面我们说说上面的这句shell如何用c语言来写。为了更能说明问题,我们把结果写入一个文件中。 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<fcntl.h> void error_quit(char *msg) { fprintf(stderr,& ...
最近工作中遇到了一个讨厌的问题,在32位机器上运行的好好的,但是在64位机器上,出现了诡异的 Segmental fault。 于是调试分析,一切似乎都很正常。开始怀疑是否由于使用了变参。因为proc不支持...形式的变参,所以,不得已自己写了一个类似printf这样的变参,和proc程序分开。这个函数如下:     const char * get_fmt_str(const char * fmt, ...) { #define SHARE_BUF_STR_LEN 4096 static char str_buf[SHARE_BUF_STR_LEN]; va_lis ...
认证和授权   在此之前,我们并没有提到SVN的安全方面的东西。并非说这不重要,而是因为根据不同的配置,可能我们会有不同的认证和授权。SVN提供三种配置。我们这里不详细说明。   首先,我们是可以通过网络来访问S ...
Global site tag (gtag.js) - Google Analytics