From 9fbba1a77e6effa4c205532c93630149ae650353 Mon Sep 17 00:00:00 2001 From: nonstriater <410495266@qq.com> Date: Mon, 16 Nov 2015 15:52:08 +0800 Subject: [PATCH] delete files unrelated to algo --- BAT iOS面试题.md | 112 ---------- README.md | 11 +- thread.c | 71 ------- .../heap.c | 0 二叉树/README.md | 159 ++++++++------ 多线程.md | 201 ------------------ .../README.md | 22 +- 7 files changed, 115 insertions(+), 461 deletions(-) delete mode 100644 thread.c rename 二叉树/{二叉堆(优先队列) => 8-二叉堆(优先队列)}/heap.c (100%) delete mode 100644 多线程.md rename {开源项目中用到的那些算法 => 开源项目中用到的算法}/README.md (62%) diff --git a/BAT iOS面试题.md b/BAT iOS面试题.md index 8e5d410..12a6f48 100644 --- a/BAT iOS面试题.md +++ b/BAT iOS面试题.md @@ -1,118 +1,6 @@ -1面问的主要主要知识点。 -2面问主要考察的是设计解决方案的能力,另外辅助追问的方式,考察深度和广度,回答过程中需要列出适合的具体例子,方案还需要细致到具体的关键的函数名称,方法。 -3面考察设计模式的理解,算法 - - - -###UI系统 - -设计一个progress bar解决方案,追问到 Core Graphic、CGPath、maskLayer。 -设计一个popup view被追问到 keyWindow、UIWindow的layer、UIView hierarchy。 - - -CALayer和View的关系 -一个UIView包含CALayer树,CALayer是一个数据模型,包含了一些用于显示的对象,但本身不用于显示。 -CALayer相当于photoshop的一个层,很多动画可以通过设置CALayer来实现。据说有人用CALayer显示图片来播放视频。 -Core animation应该是用CAlayer来实现各种动画。 -这里有篇博文,介绍的还可以http://www.cnblogs.com/uyoug321/archive/2011/01/22.html - - - - -###消息系统 - -从设计模式的角度分析Delegate、Notification、KVO的区别。被追问到自己写的library和开源的项目中用到哪些设计模式,为什么使用,有哪些好处和坏处,现在能否改进。 - - -算是问题3的追问,设计一个方案来检测KVO的同步异步问题。willChange和 didChange的不同点,然后被追问到有没有其他地方也有类似情况,被追问到Core Data 中falut object。 - -这个是问题4的追问,设计一个KVO系统。 - - -###多线程 -Multithreading,什么时候采用Multithreading方案,以及理由。追问到系统还有哪些在后台运行的thread, -Multithreading中常常遇到的问题,追问到死锁,优先级翻转,线程池等。 - - - -###运行时 -Objective C runtime library:这些都需要背后C一层的描述, -Objective C的对象模型, -block的底层实现结构, -消息发送,消息转发, -内存管理 -Multithreading:什么时候处理多线程,几种方式,优缺点。 - -Object c研究的比较深入的教程 -http://www.cnblogs.com/yaski/ 第6章写的尤其好 - -KVO/KVC 实现机理分析 -http://archive.cnblogs.com/a/1886332/ - - -###数据处理 -Core Data:中多线程中处理大量数据同步时的操作。 -缓存设计LRU Cache -sqlite中插入特殊字符的方法和接收到处理方法。 - - -###网络部分 -asihttp代码原理 ,异步请求的原理,异步请求最大数目,为什么只能这么多? - - -叙述TCP/UDP协议,他们的应用,TCP的三次握手,滑动窗口,超时重传;HTTP协议和COOKIE机制和一些COOKIE的问题 - http协议,tcp/ip,TCP/UDP - - - - -### 数据结构和算法 - - C++里STL的几个库是怎么实现的 -(类似:stl有哪些容器?各个容器的区别?以及各容器的数据结构?) -哈希表的遍历时间复杂度 -(分析:这个跟hash表的存储结构和hash函数有关) - - -### 系统设计 - -设计一个服务器的存储模式 -大数据量缓冲服务器的架构设计 -手机汉字输入法的架构设计 - - - - -### 杂谈 -简述push原理,push的证书和其它的右什么不一样? -autolayout -core data - - - - -内存寻址方式: -寄存器直接寻址 -基址寻址:方便访问k条记录 -基址+变址寻址:访问一条记录的字段 - - - -比较32位平台和64位平台不同 -内存寻址空间变大 -基本数据类型的长度也会有些变化(long ,longlong, ptr) - - -iphone app为什么会被打回来,如何避免?? -1) 阅读文档 -2) 看别人被拒的原因,吸取教训 - - - - diff --git a/README.md b/README.md index f581355..fc439db 100644 --- a/README.md +++ b/README.md @@ -122,15 +122,15 @@ http://www.chinaunix.net/old_jh/23/437639.html ## 推荐阅读 - ###刷题必备 + +###刷题必备 《剑指offer》 《编程之美》 《编程珠玑》Programming Pearls 偏算法理论 《编程珠玑(续)》 《More Programming Pearls》 偏算法轶事 - - + 《数据结构与算法分析》 《算法设计与分析基础》 《算法导论》 告诉你有哪些算法 @@ -156,7 +156,7 @@ http://www.chinaunix.net/old_jh/23/437639.html ###高级数据结构 -(如元胞自动机、斐波纳契堆、线段树) +如元胞自动机、斐波纳契堆、线段树 《Algorithms》 4版 《Advanced Data Structures》 各种诡异数据结构和算法 600块 @@ -174,8 +174,7 @@ http://www.chinaunix.net/old_jh/23/437639.html ## 参考链接和学习网站 -### July 博客 -(http://blog.csdn.net/v_july_v) +### July 博客 (http://blog.csdn.net/v_july_v) 《数学建模十大经典算法》 《数据挖掘领域十大经典算法》 《十道海量数据处理面试题》 diff --git a/thread.c b/thread.c deleted file mode 100644 index 6dd0a64..0000000 --- a/thread.c +++ /dev/null @@ -1,71 +0,0 @@ - - -#include "stdio.h" -#include "pthread.h" - -pthread_mutex_t mutex; -pthread_cond_t condition; - -unsigned int i = 0; - -void *threadFunc1(void *arg){ - - pthread_mutex_lock(&mutex); - pthread_cond_wait(&condition,&mutex); - pthread_mutex_unlock(&mutex); - - printf("aaaaaaa %d\n",i); - pthread_exit((void *)0); - -} - - -void *threadFunc2(void *arg){ - - pthread_mutex_lock(&mutex); - pthread_cond_wait(&condition,&mutex); //??? 这里人存在问题 - pthread_mutex_unlock(&mutex); - - printf("vbbbbbbbbbb %d\n",i); - pthread_exit((void *)0); - -} - - -int main(int argc, char const *argv[]) -{ - - pthread_mutex_init(&mutex,NULL); - pthread_cond_init(&condition,NULL); - - pthread_t thread1,thread2; - pthread_create(&thread1,NULL,threadFunc1,(void *)0); - pthread_create(&thread2,NULL,threadFunc2,(void *)0); - - while(1){ - - pthread_mutex_lock(&mutex); - i++; - pthread_mutex_unlock(&mutex); - - if (i==100000000) - { - // - pthread_cond_broadcast(&condition); - break; - - } - - } - - pthread_join(thread1,NULL); - pthread_join(thread2,NULL); - - pthread_cond_destroy(&condition); - pthread_mutex_destroy(&mutex); - - - return 0; -} - - diff --git a/二叉树/二叉堆(优先队列)/heap.c b/二叉树/8-二叉堆(优先队列)/heap.c similarity index 100% rename from 二叉树/二叉堆(优先队列)/heap.c rename to 二叉树/8-二叉堆(优先队列)/heap.c diff --git a/二叉树/README.md b/二叉树/README.md index 990d2b3..84b1bec 100644 --- a/二叉树/README.md +++ b/二叉树/README.md @@ -118,55 +118,13 @@ n个节点的完全二叉树,其查找,删除的复杂度都是O(logN),但 -## 赫夫曼编码 Huffman - -这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树`进行的压缩算法。 - -对一个字符串,计算每个字符出现的次数,把这些字符放到优先队列(priority queue) -这这个priority queue转出二叉树 - -需要一个字符编码表来解码,通过二叉树建立huffman编码和解码的字典表 +## AVL树 -原始串: -二级制编码: -huffman编码: +## 红黑树 -###存储结构和基本操作 -``` -struct node{ - char *huffCode; // 叶子节点的huff编码 - int weight; - struct node *left,right; -} -``` - -###构建赫夫曼树 - -原则:出现频率越多的会在越上层,编码也越短,出现频率越少的在越下层,编码也越长。 -不存在某一个编码是另一个编码的前缀,字符都在叶节点上,所以不会存在一个编码是另一个编码的前缀 -二叉树每个节点要么是叶子节点,要么是双分支节点(且左分支编码为0,右分支编码为1) - - -###压缩 - -1. 扫描输入文件,统计各个字符出现的次数,对结构排序 (hash统计每个字符出现的次数) -2. 根据排序结构,构建赫夫曼树 (贪心策略,每次选频率值最低的2个节点合并,需要优先队列帮组(priority queue,又叫最小堆)) -3. 对树进行遍历(左分支编码为0,右分支编码为1),得到各个字符的huffman编码,存到hash表中(这个就是编解码表,也可直接存储到节点中,如上面的char *huffCode) -4. 重新对文件扫描,根据hash表进行压缩 - -压缩的文件为了能够解压缩,需要一个文件头,用来重建赫夫曼树,包括: -被编码的文本长度 unsigned int size -字符频率表 unsigned char freqs[NUM_CHARS] - -###解压缩 - -1. 读取文件头 -2. 遍历编码后的bits,从赫夫曼树的根节点出发,遇到0,进入左子树,遇到1进入右子树,直到叶节点 - - ## 字典树trie(前缀树,单词查找树) @@ -251,6 +209,94 @@ double-array trie 参考作者的这篇论文 http://linux.thai.net/~thep/datri + +## B树 + +平衡查找树,一种多路查找树。 + +能保证数据插入和删除情况下,任然保持执行效率。 + +一个M阶的B树满足: + +1. 每个节点最多M个子节点 +2. 除跟节点和叶节点外,其它每个节点至少有M/2个孩子 +3. 根节点至少2个节点 +4. 所有叶节点在同一层,叶节点不包含任何关键字信息 +5. 有k个关键字的页节点包含k+1个孩子 + +也就是说: +根节点到每个叶节点的路径长度都是相同的。 + + +## B+树 + + + +mysql索引使用B+树的数据结构 + +## B*树 + + +## R树 + + + + + +## Treap 树 + + + + +## 赫夫曼编码 Huffman + +这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树`进行的压缩算法。 + +对一个字符串,计算每个字符出现的次数,把这些字符放到优先队列(priority queue) +这这个priority queue转出二叉树 + +需要一个字符编码表来解码,通过二叉树建立huffman编码和解码的字典表 + + +原始串: +二级制编码: +huffman编码: + + +###存储结构和基本操作 + +``` +struct node{ + char *huffCode; // 叶子节点的huff编码 + int weight; + struct node *left,right; +} +``` + +###构建赫夫曼树 + +原则:出现频率越多的会在越上层,编码也越短,出现频率越少的在越下层,编码也越长。 +不存在某一个编码是另一个编码的前缀,字符都在叶节点上,所以不会存在一个编码是另一个编码的前缀 +二叉树每个节点要么是叶子节点,要么是双分支节点(且左分支编码为0,右分支编码为1) + + +###压缩 + +1. 扫描输入文件,统计各个字符出现的次数,对结构排序 (hash统计每个字符出现的次数) +2. 根据排序结构,构建赫夫曼树 (贪心策略,每次选频率值最低的2个节点合并,需要优先队列帮组(priority queue,又叫最小堆)) +3. 对树进行遍历(左分支编码为0,右分支编码为1),得到各个字符的huffman编码,存到hash表中(这个就是编解码表,也可直接存储到节点中,如上面的char *huffCode) +4. 重新对文件扫描,根据hash表进行压缩 + +压缩的文件为了能够解压缩,需要一个文件头,用来重建赫夫曼树,包括: +被编码的文本长度 unsigned int size +字符频率表 unsigned char freqs[NUM_CHARS] + +###解压缩 + +1. 读取文件头 +2. 遍历编码后的bits,从赫夫曼树的根节点出发,遇到0,进入左子树,遇到1进入右子树,直到叶节点 + + ## 后缀树(suffix tree) @@ -265,31 +311,6 @@ double-array trie 参考作者的这篇论文 http://linux.thai.net/~thep/datri -## AVL树 - - -## 红黑树 - - -## Treap 树 - - -## B树 - - -## B+树 - - -## B*树 - - -## R树 - - - - - - diff --git a/多线程.md b/多线程.md deleted file mode 100644 index 9713813..0000000 --- a/多线程.md +++ /dev/null @@ -1,201 +0,0 @@ - - -### 多线程有几种实现方法,都是什么? - -OC中: -Thread: 使用简单方便,但效率不及下面的几种方式 -NSOperationQueue:可以对thread的状态做精确的控制,gcd做不到 -GCD: 效率做好的方案,且结合block,使用方便 -pthread OS提供的api - - - -### 多线程同步和互斥有几种实现方法,都是什么? - -首先理解线程`同步`和`互斥`的概念。 - -`同步` 在一个功能调用时,如果没有得到结果,调用就不返回 - -`死锁` 2个线程访问共享资源,顺序不当造成的。如一个线程锁定了资源A,想访问另一个线程锁定的资源B,而这个线程又在等待A资源。 - -`线程同步` 线程A和B一块配合,A执行到一定程度需要拷B的结果,于是停下来,等待B的指向结果。 - -1. 临界区: 任意时刻只允许一个线程访问共享资源 -2. 互斥量: 拥有互斥对象的线程才能访问公共资源 -3. 信号量: 允许多个线程同时访问统一资源?? -4. 事件 : ? - - -结合代码来看看 linux上 3种 线程同步的方式: - -#### 互斥锁 - -pthread_mutex_t -pthread_mutex_init() -pthread_mutex_lock() // 在访问共享资源时,加锁,这样别的线程无法访问 -pthread_mutex_unlock() // 解锁,这样别的线程可以访问共享资源了 -pthread_mutex_destroy()// 释放互斥锁 - - -互斥锁是如何通知到等待锁的线程的? - -我猜内核会维护一个 互斥量对多个等待线程(1对多) 的表,在互斥量解锁后,采用某种方式选择一个等待线程唤醒,让其获得互斥锁,如此往复,直到所有等待线程唤醒执行。(具体待参加linux/kernel/mutex.c) - - -#### 条件变量 - -条件变量用来等待,阻塞一个线程,等待某个条件发生时触发。条件变量与互斥锁同时使用. - -条件变量和互斥量相关联 是一种用于 多线程之间共享数据状态改变的通信机制。 - -pthread_cond_init() -pthread_cond_destroy() -pthread_cond_wait(cond,mutex) // 条件测试为假,线程就会阻塞; -pthread_cond_signal() // 给出“条件成立”信号 -pthread_cond_broadcast() - - -以生产者消费者问题为例,消费线程在得知队列中没有产品时,将阻塞自己; -生产者线程生产产品后,没有办法激活消费线程,这个时候生产者还要继续运行生产产品,不能用互斥量来实现;如果消费线程采用轮询的方式,无疑又是对CPU的浪费;最好的方式还是生产线程来唤醒消费线程; - -那生产线程如何唤醒另一个线程呢? - - - - -条件变量本身是需要互斥量来保护的,也就是条件的检查实在互斥锁的保护下进行的。 因此pthread_cond_wait(cond,mutex)函数中,传递了一个mutex互斥量用来锁住cond条件变量 - - -iOS中又NSCondition - - - wait - - signal - - broadcast - -NSCondition 还实现了 NSLocking协议 - - lock - - unlock - - - -#### 信号量 - -又叫 `信号灯`,本质上是一个计数器。 - -sem_t -sem_init() // 初始化一个信号量,需要指定允许的最大资源计数。如果这里最大计数为1,跟互斥量类似了。 -sem_wait() // 给信号量-1 , 如果信号量任然>=0,线程可以继续指向,否则等待 -sem_post() // 给信号量+1 -sem_destroy() // 销毁信号量 - -可以理解为,`互斥量` 是 `信号量` 的一种特殊情况(max_sem_count==1) - -看下信号量的结构(/usr/src/linux/include/linux/sem.h) -struct semaphore { - spinlock_t lock; // 用来确保对count成员的原子操作 - unsigned int count; - struct list_head wait_list;// 在信号量+1,给wait的线程或进程发送信号量 -}; - - - -`线程互斥` : 某一资源同时只允许一个访问者访问。上面介绍的 `互斥量` `临界区` 都可以实现线程的互斥 - - - -### 怎么避免死锁?(经验) - -A线程 -@synchronized(lockobj){ - while([datas count==0){...} -} - -B线程 -@synchronized(lockobj){ - [datas addObject:[Item new]]; -} - -A线程一直在while循环上等待,但是B线程有无法获得lockobj锁而等待出现死锁。解决办法是用NSLock来替换@synchronized(lock),在while()中 - -1). 在使用锁的程序中,不要在程序中间使用return(这个时候还没有解锁,就可能会造成死锁), 而使用goto函数跳转至解锁并退出函数的位置 - - -1. 线程重排序reordering thread -2. minimize locking -3. a bigger loc -4. try lock -5. time out for locking - - - -### 互斥量与临界区比较? - -互斥量比临界区复杂,临界区只能完成统一进程内线程直接的同步,互斥量可以实现不同进程的线程的同步,可以跨进程使用。 - -互斥量,信号量,事件都可以跨进程访问 - - - -### 生产者消费者问题 - -生产者和消费者之间通常有一个缓冲区作为中介。这个缓冲区有以下作用: -1. 解耦合 -2. 让 生产者 和 消费者 并发执行 -3. 支持忙闲不均 - -队列缓冲区 -环形缓冲区 - - - -实现一个队列。队列的应用场景为: -一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列 - - - - - -### 读者写者问题 -这也是一个非常经典的多线程题目,题目大意如下:有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。 - - - -### 几个多线程面试题目 - -主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。 - -要求: -1.子线程输出的线程序号不能重复。 -2.全局变量的输出必须递增。 - - - -编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。 - - - -有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD。初始都为空。现要让四个文件呈如下格式: - -A:1 2 3 4 1 2.... -B:2 3 4 1 2 3.... -C:3 4 1 2 3 4.... -D:4 1 2 3 4 1.... - -请设计程序。 - - - - - - - - - - - - - - - - - diff --git a/开源项目中用到的那些算法/README.md b/开源项目中用到的算法/README.md similarity index 62% rename from 开源项目中用到的那些算法/README.md rename to 开源项目中用到的算法/README.md index 922642c..83e6a47 100644 --- a/开源项目中用到的那些算法/README.md +++ b/开源项目中用到的算法/README.md @@ -2,13 +2,31 @@ 数据结构往往是一个项目系统的核心,理解项目的数据结构和算法,才能真正理解项目的工作原理。这里罗列出常用开源系统中用到的数据结构和算法。 + + +每一条说清楚: +1. 项目简介 +2. 用到算法的功能介绍 +3. 用到的算法 + ##MYSQL 背后的数据结构和算法 http://blogread.cn/it/article/4088?f=wb2 +索引使用B+树 + +## Redis + + +## MongoDB + + +## Nginx + + ##Cocos2D-iPhone +## JavaScript 对象存储结构 - - +V8引擎