- 博客(122)
- 收藏
- 关注
原创 在Linux上使用JNI代码
生成可执行应用程序链接参考文章:GCC编译过程与动态链接库和静态链接库使用C语言调用Java代码由于协程Demo的需要,笔者需要使用C语言调用之前写过的Java代码库,从网上搜索到的资料,大多数是关于如何以Java代码为主程序,调用本地C语言接口函数,不符合笔者的需求,所以写下该博客,记录以C语言为运行主程序代码,调用Java相关的代码。下面代码展示如何在C语言中调用Java代...
2019-02-26 09:31:13
409
原创 云风协程库的源码解析
参考文章:云风协程库保存和恢复协程运行栈原理讲解基于云风协程库的协程原理解读深入理解计算机系统 读书笔记1Linux进程地址空间在32位操作系统中,进程的最大地址空间为4GB。整个进程地址空间从下往上为地址的增长方向。对于系统中的所有进程来说,代码都是从同一固定地址开始。只读代码和数据:该区域是直接按照可执行目标文件中的内容初始化的,在进程开始运行时,大小就固定不变;...
2019-02-24 19:51:30
521
原创 基于C语言的协程和Java混合编程的服务器
协程JNI进程间通信写在前面的话:笔者在学习《UDP》中的网络模型之后,已经尝试使用Java语言写过阻塞IO模型、非阻塞IO模型、IO多路复用模型以及异步IO模型。每种网络模型的特点这里就不再赘述,本文主要利用云风的协程库和JNI技术调用笔者之前写过的解析HTTP请求的Java代码(笔者的HTTP服务器Demo),从而实现一个新的HTTP服务器。这个基于协程的服务器只是笔者学习新知识的...
2019-02-24 17:36:13
317
原创 剑指Offer错题集(20题)
变态跳台阶一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。解题思路:比如5层台阶的跳法,从第4层跳到5层,加上之前第1层到第4层的解法从第3层跳到5层,加上之前第1层到第3层的解法…从第1层跳到5层public class Solution { public int JumpFloorII(int ta...
2018-12-13 20:46:27
211
原创 Manacher算法
整理自左程云算法课暴力法:以每个字符串为中心,判断其左右两边的相等的最长字符串往字符串中间添加特殊字符,可以满足字符串长度为奇数和偶数的情况eg.m: 1 2 2 1 3 3 1 2 2 1n: #1#2#2#1#3#3#1#2#2#1#maxLength: 在最中间的位置,找到最长的回文半径 21/2 = 10时间复杂度: O(n^2)Manacher算法:1. 回文半径...
2018-12-13 20:46:14
230
原创 RPC服务框架——Dubbo
Dubbo,分布式服务框架,致力于提供性能和透明化的远程服务调用方案和基于服务框架展开的完整SOA服务治理方案。Duboo的核心部分包含三部分远程通信 提供对于多种基于长连接的NIO框架抽象封装,包括多种线程模型,序列化,以及“请求——响应”模式的信息交换方式集群容错 提供基于接口方法的远程过程透明调用,包括对多协议的支持,以及对软负载均衡、失败容错、地址路由和动态配置等集群特性的...
2018-06-06 16:06:49
409
原创 ZooKeeper的典型应用场景——分布式协调/通知
分布式协调/通知服务是分布式系统中不可缺少的一个环节,是将不同的分布式组件有机组合起来的关键所在。对于一个在多台机器上部署运行的应用而言,通常需要一个协调者来控制整个整个系统的运行流程,例如分布式事务的处理、机器间的互相协调等。同时,引入这样一个协调者,便于将分布式协调的职责从应用中分离出来,从而可以大大减少系统之间的耦合性,而且能够显著提高系统的可扩展性。从实现细节来讲,就是利用ZooKeepe...
2018-06-03 22:57:33
1139
原创 ZooKeeper的典型应用场景——数据发布/订阅
数据发布/订阅系统,即所谓的配置中心:发布者将数据发布到ZooKeeper的一个或一系列节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。ZooKeeper采用的是推拉相结合的方式:客户端向服务器端注册自己需要关注的节点,一旦该服务端节点的数据发生变更,就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息后,需要主动向服务端获取最...
2018-06-03 21:26:13
497
原创 ZooKeeper的典型应用场景——分布式队列
分布式队列,简单地分为两大类,一种是常规的先入先出队列,另一种则是要等到队列元素聚集之后,才统一安排执行的Barrier模型。先入先出利用ZooKeeper实现FIFO队列,和分布式共享锁的实现十分类似,可以说是更为简单。FIFO队列类似于每个操作都是写的共享锁模型,设计思路:所有客户端都会到/queue_info这个节点下面创建一个临时顺序节点,例如“/queue_info/[hot...
2018-06-03 20:44:45
508
原创 ZooKeeper的典型应用场景——集群管理
集群管理:包括集群监控(侧重对运行时状态的手机)和集群控制(对集群进行操作与控制)ZooKeeper具有两大特性,可以实现集群机器活性监控的系统。客户端如果对ZooKeeper的一个数据节点注册Watcher监听,那么当该数据节点内容或者是其子节点发生变更的时候,ZooKeeper服务器就会向订阅的客户端发送变更通知。对在ZooKeeper上创建的临时节点,一旦客户端与服务器之间的会话...
2018-06-03 19:49:24
510
原创 ZooKeeper的典型应用场景——命名服务
在分布式环境中,上层应用仅仅需要一个全局唯一的名字,类似于数据库中的唯一主键。在过去,可以使用关系型数据库字段自带的auto_increment属性自动为每个记录生成一个唯一的ID,数据库会保证生成的这个ID在全局唯一。但是,随着数据规模的不断增大,分库分表随之出现,而auto_increment属性仅能针对单一表中的记录。UUIDUUID是一个不错的全局唯一ID生成方式,能够非常方便地保...
2018-06-03 16:23:54
826
原创 ZooKeeper的典型应用场景——分布式锁
在平时的实际项目开发中,可以依赖关系型数据库固有的排他性来实现不同进程间的互斥。然而,目前绝大数大型分布式系统的性能瓶颈都集中在数据库操作上,如果上层业务再给数据库添加一些额外的锁,例如行锁等,会让数据库更加不堪重负。排他锁定义锁在ZooKeeper中,通过数据节点来表示一个锁,例如/exclusive_lock/lock节点就可以被定义为一个锁。获取锁在需要获取锁的情况下...
2018-06-03 15:40:46
897
原创 ZooKeeper的典型应用场景——Master选举
Master选举是一个在分布式系统中非常常见的应用场景。分布式最核心的特性就是能够将具有独立计算能力的系统单元部署在不同的机器上,构成一个完整的分布式系统。在实际场景中,往往需要这些分布在不同机器上的独立系统单元中选出一个所谓的“老大”,称之为Master。在分布式系统中,Master往往用来协调集群中其他系统单元,具有对分布式系统状态变更的决定权。 比如:Master负责处理一些复杂的逻辑...
2018-06-03 09:39:29
638
1
原创 ZooKeeper技术内幕——Leader选举
Leader选举的实现细节服务器状态LOOKING:寻找Leader状态,当服务器处于该状态的时候,它会认为当前集群中没有Leader,因此需要进入Leader选举流程FOLLOWING:跟随者状态,表明当前服务器角色是FollowerLEADING:领导者状态,表明当前服务器角色是LeaderOBSERVING:观察者状态,表明当前服务器角色是Observer投票数据结构...
2018-05-31 20:26:33
251
原创 ZooKeeper技术内幕——系统模型
系统模型包括五个部分:数据模型、节点特性、版本、Watcher和ACL。数据模型数据节点 用ZNode来表示,ZNode是ZooKeeper中数据的最小单元,每个ZNode上都可以保存数据,同时还可以挂载子节点,因此构成了一个层次的命名空间,称之为树。事务ID 在ZooKeeper中,事务是指能够改变ZooKeeper服务器状态的操作。一般包括:数据节点创建与删除、数据节点内容更新...
2018-05-31 17:05:39
355
原创 开源客户端Curator
Curator是一套开源的ZooKeeper客户端框架,本文会学习并记录一些API。Curator使用创建Curator客户端的Maven依赖,不要使用高版本的<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framewo...
2018-05-31 09:15:21
283
原创 ZAB协议
ZooKeeper的ZAB协议ZAB(ZooKeeper Atomic Broadcast)协议并不像Paxos那样,是一种通用的分布式一致性算法,它是一种特别为ZooKeeper设计的崩溃可恢复的原子消息广播协议。在ZooKeeper中,主要依赖ZAB协议来实现分布式数据一致性,基于该协议,ZooKeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。ZAB协议的核心...
2018-05-24 22:12:56
265
原创 三阶段提交协议
三阶段提交协议(3PC)三阶段提交协议是2PC的改进版,将二阶段提交协议的阶段一,即“提交事务请求”一分为二,形成了由CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议。协议说明阶段一:CanCommit事务询问 执行者向所有参与发送CanCommit请求,等待所有参与者的响应参与者反馈响应 参与者节点若认为自身可以完成事务,返回Ye...
2018-05-23 23:15:12
1438
原创 二阶段提交协议
二阶段提交协议(2PC)二阶段提交协议是计算机网络中,尤其是在数据库领域内,为了使基于分布式系统架构下的所有节点在进行事务处理过程中能够保持原子性和一致性的一种算法。目前,绝大部分的关系型数据库都是采用二阶段提交协议来完成分布式事务处理的。协议说明阶段一:提交事务请求事务询问 协调者询问参与者是否可以执行事务提交的操作,并开始等待参与者的响应执行事务 各参与者执行事务操...
2018-05-23 22:08:46
308
原创 Leetcode-27 Remove Element(数组)
Leetcode-27 Remove Element给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。示例 1:给定 nums = [3,2,2,3], val = ...
2018-05-23 10:01:24
160
原创 Leetcode-283 Move Zeroes(数组)
Leetcode-283 Move Zeroes给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。示例:输入: [0,1,0,3,12]输出: [1,3,12,0,0]说明:1.必须在原数组上操作,不能拷贝额外的数组。2.尽量减少操作次数。class Solution { private void swap(in...
2018-05-23 08:23:01
136
原创 冒泡排序
public static void bubbleSort(double[] A){ int N = A.length; for(int i = 0; i 1 ; ++i){ boolean flag = true; for(int j = 0; j 1-i; ++j){ if(compareTo(A[j], A[j+1]) == 1
2017-10-27 15:37:57
213
原创 三向切分的快速排序
优点:三向切分的快速排序比归并排序、标准快速排序和其他排序方法在包括重复元素很多的实际应用中更快。public static void quickThreeWaySort(double[] A){ quickThreeWay(A, 0, A.length-1);}private static void quickThreeWay(double[] A, int lo, int
2017-10-27 15:37:28
318
原创 快速排序
快速排序是一种分治的排序算法。它将一个数组分成两个子数组,将两部分独立地排序。快速排序和归并排序是互补的:归并排序将数组分成两个子数组分别排序,并将有序的子数组归并以将整个数组排序;快速排序则是当两个数组都有序时,整个数组也自然就有序了。public static void quickSort(double[] A){ quickSortAPI(A, 0, A.length-
2017-10-27 15:36:52
204
原创 归并排序
将一个数组排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。优点:它能够保证将任意长度为N的数组排序所需的时间和NlogN成正比;缺点:所需额外的辅助空间和N成正比。private static double[] aux; public static void mergeSort(double[] A){ aux = new double[A.leng
2017-10-27 15:36:19
187
原创 希尔排序
希尔排序是一种基于插入排序的快速排序算法。对于大规模的乱序排序算法,插入排序会很慢,因为它只会交换相邻的元素,因此元素只能一点点地从数组的一端移动到另一端。希尔排序为了加快排序,交换不相邻的元素对数组局部进行排序,并最终用插入排序将局部有序的数组排序。特点:对于中等大小的数组运行时间可接受。它的代码量小,且不需要额外的内存空间。public static void
2017-10-27 15:35:52
221
原创 插入排序
插入排序和选择排序有一个相同的地方是:当前索引左边的所有元素都是有序的。与选择排序不同的是:插入排序所需的时间取决于排序数组中元素的初始顺序。例如,一个很大且其中的元素已经(或接近有序)的数组进行排序会比对随机顺序的数组或者是逆序数组(最坏情况)进行来的快。特点:插入排序对于部分有序的数组十分高效,也很适合于小规模数组。public static void insertio
2017-10-27 15:35:21
193
原创 选择算法
选择排序两个鲜明的特点:运行时间和输入无关:为了找出最小的元素而扫描一遍数组并不能为下一趟扫描提供任何有用的信息。一个已经有序的数组或者是元素全部相等的元素和一个随机排序的数组所用的排序时间一样长。数据移动是最少的:显然可见,移动数据只发生在是外层循环中。故选择排序只用了N次交换,这是其他大部分算法不具备的。package com.algorithms;import jav
2017-10-27 15:32:56
263
原创 文章标题
关于Java中static的笔记本文中更多的只是自己的一些总结,笔者也是刚学java不就,文中难免出现纰漏,还望大家多多指正。class Base{ Base() { System.out.println("in Base()"); } static int i = static_aux(); static void static_f1(){
2017-09-14 00:52:39
225
原创 优先队列/堆
优先队列运用于在接近无限大N的输入中,找出最大(最小)的M个元素。如果用数组来实现二叉堆的话,那么位置k的结点的父结点的位置为k/2,而它的两个子结点的位置分别为2k和2k+1数组中A[0]不使用,示例代码中使用最大堆优先队列能够保证插入元素和删除最大元素这两个操作复杂度为NlogM
2017-06-08 00:03:34
321
原创 快速排序
int quick(std::vector& V, int lo, int hi){ int i = lo; int j = hi + 1; //在比较时候,使用了--j,避免跳过hi元素,先加1 int pivot = V[lo]; //pivot是被用来比较元素 for (;;) { //i从左往右遍历数组,j从右往左遍历数组 while (V[++i] < piv
2017-06-06 19:16:24
357
原创 归并排序
//自顶向下的归并排序void mergeSort(std::vector& V, int lo, int hi){ if (hi <= lo) return; int mid = lo + (hi - lo) / 2; mergeSort(V, lo, mid); //递归实现数组的切分 mergeSort(V, mid + 1, hi); merge(V, lo, hi)
2017-06-06 11:20:46
256
原创 希尔排序
基于插入排序实现的希尔排序。对于大规模乱序数组插入排序显得很慢,因为它只会交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要进行n-1次移动。希尔排序为了加快速度简单的改动了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。
2017-06-05 23:01:31
245
原创 插入排序
void insertSort(){ std::vector V{ 5,2,9,4,1,8,3,7,6 }; for (size_t i = 1; i < V.size(); ++i) { //从后往前进行比较,比较之前,i-1前面的序列都是有序的了 //此时i依次向前进行比较,如果i小于前面的就开始一步步向前交换 //否则,就可以停止了 for (size_t j = i;
2017-06-05 21:43:12
264
原创 选择排序
选择排序是排序算法中比较简单的。主要思路:每次在未排序的数组序列中选择最小的对象放在数组前面。 最小的放在第一位,第二小的放在第二位.......
2017-06-05 21:11:21
238
原创 双栈计算求值表达式
#include #include #include int main(){ std::string s = "((1+(2+3)*(4*5)))+1)"; std::stack stack_c; std::stack stack_i; int value = 0; for (size_t i = 0; i < s.size(); ++i) { if (s[i] = '
2017-06-05 09:12:22
449
原创 C++primer 第八章
8.4#include #include #include #include using namespace std;int main(){ ifstream input("read.txt"); if (!input) { cerr << "Can't open read.txt" << endl; return -1; } vector svec; str
2016-09-05 20:47:45
399
原创 C++primer 第七章
本章主要一步步构造类。7.2#pragma once#include #include using namespace std;struct Sales_data { std::string isbn() const { return bookNo; } Sales_data& combine(const Sales_data&); std::string bookNo;
2016-09-05 14:43:59
442
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人