- 博客(45)
- 收藏
- 关注
原创 如何下载google play上的软件
最近用了安卓手机,想安装一些软件真难,大家应该懂得,google play这个玩意装起来是真麻烦,经过不停的baidu google 查到了一个快捷的方式。
2022-10-04 22:21:42 1408 1
原创 idea添加jar包时启动tomcat项目时显示jar包找不到
WEB-INF目录下有个lib目录存放jar包,因为需要在Project Structure中选择了自己的jar包,本地测试没有问题,上了tomcat就会报错,找不到jar(ava.lang.NoClassDefFoundError)这个错误,最后找出错误,在导入新的jar包的时候,先在Project Structure中将以前的lib目录删除(右边有个红色的减号),然后把新的jar包拷贝到项
2017-05-11 00:37:50 7533 1
原创 高级I/O-----dup/dup2
dup/dup2dup/dup2是两个用于指定文件操作符的方法,作用很相似,它是得两个文件描述符指向同一个file结构体,使file的引用计数为2,所以在使用的时候我们需要手动关闭另外一个不需要的。dup:dup的作用是将文件描述符指向一个最小的文件描述符。1234 #i
2016-05-31 21:42:41 294
原创 高级I/O----sockerpair
socketpairsocketpair:相比较之前提到的管道,socketpair是一个全双工的通信方式,它的一端即可以读也可以写,对于它我是这样理解的:假设现在我们是在本地使用socketpair的,客户端为fd[0],服务器端为fd[1],当服务器向客户端写数据时,从fd[1]的写端写入数据,而从fd[1]的读端读取数据,反之从客户端上的操作也是如此。下面是实现的
2016-05-29 18:22:33 500
原创 网络编程中常见的5种I/O模型
I/O模型Unix下共有五种I/O模型:1>:阻塞I/O2>:非阻塞I/O3>:I/O多路复用4>:信号驱动I/O5>:异步I/O其中前四种是同步I/O模型,只有第五种是异步的。同步与异步:这里的同步和两个实体之间通信中的同步的概念是不一样的,这里的同步是指关于这个I/O中的一系列动作都需要自己来完成,无论你是原地等待事件的发生(阻塞)还是当某个事件已经准备好的时候你去完成后面的的动作(非阻塞)都
2016-05-29 16:55:08 2639
原创 socket中的虚拟端口号port
端口号协议端口号: 端口号的全名就是协议端口号,它用于应用层和传输成的交互,在创建一个套接字的时候需要知道ip地址和端口号,这里的端口号它是虚拟的,运输层协议中我们知道端口号是一个十六位的整数,那么就表示了0到65535这么多的端口号,他到底有什么用处呢。 如果说ip是确定网络中的唯一一台主机的话,那么ip加端口号是确定网络中唯一一台主机中的唯一一个进程,注意端口号指具有本地的意义,他只时为了
2016-05-29 16:55:05 1336
原创 基于TCP协议下的socket编程
socket: TCP/IP协议中一个端口号和一个IP地址绑定在一起就生成一个socket就表示了网络中唯一的一个进程,它是全双工的工作方式。基于TCP的socket编程函数的使用:1、socket() #include /* See NOTES */ #include int socket(int domain, int typ
2016-05-29 16:55:02 2548
原创 解决TIME_WAIT状态常见的解决办法
TIME_WAIT状态: 在TCP连接中,主动关闭链接的一方会进入TIME_WAIT状态,它会保持长达2MSL周期的时间,为什么会保持这么长的时间上一篇博客中已经提到过了。如果server的最后一次ACKclient没有收到,client会重新发送一次fin这个时间是在2ML周期之间的,这个时候server还保持着TIME_WAIT的状态所以它会再次发送ACK确认,而如果不等待这么长时间的话,s
2016-05-29 16:54:59 1694
原创 可靠的传输层协议——TCP协议
TCP协议TCP协议工作在传输层,虽然它与UDP的下一层都是IP但是它却和UDP的效果完全不同,它是一种可靠的传输层协议一、TCP协议封装650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/80/32/wKioL1c7BSPAP9k2AACMZR1EUHU179.png" title="无标题.png" width="650" hei
2016-05-29 16:54:56 1600
原创 NAT分类和利弊
NAT是一种地址转换的技术,工作在路由器上,内部网络想要访问因特网时可以经过NAT转换为一个外部网络,安装有NAT的路由器叫做NAT路由器。 因为目前的ip地址很稀缺,不能满足一人一个(A,B,C类)ip地址的奢侈需求,NAT解决了这个问题,但也有它的利弊之处。NAT的实现方式有三种,即静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。1>静态转换是指将
2016-05-29 16:54:50 1769
原创 回顾linux系统编程学习过程
一、基础知识1、linux操作系统,熟悉常用的指令。2、vim编译器的使用,Makefile的编写。3、用户以及权限方面相关的知识。4、linux下环境变量的概念。二、进程概念相关1、进程的概念,了解PCB的概念,以及task_struct结构体。2、进程的创建,fork()与vfork()的区别和联系。3、进程的等待,waitpid()与wait(),阻塞等待与非阻塞等待。4、进程的程序替换,e
2016-05-29 16:54:47 274
原创 守护进程的创建
守护进程守护进程又称作精灵进程是一个特殊的后台进程,他没有控制终端,周期性的执行该执行的任务650) this.width=650;" src="http://s5.51cto.com/wyfs02/M02/7F/E2/wKiom1cwjkLjjkz0AACRvMOl2GA781.png" title="无标题.png" width="700" height="189" border="0" hs
2016-05-29 16:54:44 439
原创 可重入函数与线程安全
可重入函数与线程安全 线程安全:假如在一个函数中它是这么写的,在一个全局链表上存放数据,在单线程模式下,我们先new一个新的节点然后让head->next指向这个节点,这种场景在多线程场景下会是这样的过程,线程一new了一个节点,然后cpu转去执行线程二,线程二new一个节点后head->next指向线程二,然后执行线程一,线程一的head->next也指向它刚刚new出来的节点
2016-05-29 16:54:41 256
原创 Linux信号
Linux信号一、信号:在计算机中存在了一组由整数构成的一组数,这组数大多用于软件中断作用。用kill -l可以查看系统中所定义的信号。650) this.width=650;" src="http://s2.51cto.com/wyfs02/M02/7F/9D/wKioL1clo-KTTL5cAAEg8Wk91UA719.png" title="kill-l.png" width="700" h
2016-05-29 16:54:39 229
原创 信号量实现环形buff下多生产者多消费者模型
posix下定义了一个semaphore,他和systemV版本下的sem很像,而这个多用于线程,它的单位是信号量,而sem的单位是信号量集。 #include int sem_init(sem_t *sem, int pshared, unsigned int value); int sem_destroy(sem_t *sem); int sem_wait(sem_t *sem);
2016-05-29 16:54:36 390
原创 线程的同步与互斥---生产者消费者模型
生产者与消费者模型 生产者与消费者模型是一种描述进程间同步与互斥的一个方式,在这个模式下有两类人,一个是不停产生数据的生产者,一个是不停获取数据的消费者,为了效率最高,就必须保持两者之间的同步与互斥。 为了在生产者与消费者使用mutex保持互斥的前提下,posix版本下还有另外一个函数cond它的作用是在生产者生产出来一个数据时便提醒消费者,而消费者在没东西消费时可以使用cond将自己保持在一
2016-05-29 16:54:33 312
原创 线程的同步与互斥
线程的同步与互斥多线程往往会引起很多问题,比如下面所示代码: 1 #include 2 #include 3 int g_val=0; 4 void *test(void *arg) 5 { 6 int count=5000; 7 int tmp=0; 8 while(count-->0) 9 { 10 tmp=
2016-05-29 16:54:30 896
原创 线程的控制与分离
线程的控制与分离线程与进程:线程可以说是系统的一个执行流,它是操作系统用于调度去cpu中执行的基 本模块,线程它是在进程中存在的,进程相当于承担系统资源的一个实体, 而线程是用来去执行的,它和进程 有些是共享的: 1.文件描述符表 2.每种信号的处理方式(SIG_IGN、SIG_DFL或者自定义的信号处理函数) 3
2016-05-29 16:54:27 226
原创 进程间通信(4)---最高效的进程间通信方式--内存共享
内存共享 内存共享,它也是一种进程间通信的方式,它是在虚拟地址空间中堆和栈地址空间的中间的共享映射区中开辟一块地址,然后由页表和mmu在物理内存中开辟一段空间,其他进程如果获取到了这个内存的ID便可以和另外的进程共享这段内存。内存共享的特点:高效,它比其他的进程间通信的方式都要高效因为它直接看到的就是相当于他自己的一块内存。 要用到的函数: int shmget(key_t key, size_
2016-05-29 16:54:24 993
原创 进程间通信(3)--信号量
信号量与简单互斥锁的实现信号量:与管道和消息队列不同,信号量可以说是一个计数器,它用来控制多进程对临界资源的访问,它作的是PV操作,P为减一操作,它是用来获取临界资源的使用权,如果减一之后大于零则可以访问,不然就挂起等待,V为加一操作,当进程对他的访问结束后便执行,用来归还资源的使用权。原子操作:PV的加一减一都是原子操作也就是说加一减一对应的计算机语言只有一条操作,如果不这样设计就会引起双方同时
2016-05-29 16:54:22 302
原创 进程间通信(2)消息队列
消息队列也是一种用于进程间通信的方式,它放在计算机内核中,并由消息队列表示符(类比文件描述符)标识,它由操作系统维护。消息队列的特点:1>它支持进程间双向无阻塞的通信。2>它是面向消息传递的。3>它的生命周期是随计算机内核的。下图列出了消息队列的最大消息的一些数据。650) this.width=650;" src="http://s2.51cto.com/wyfs02/M01/7E/E0/wKi
2016-05-29 16:54:19 222
原创 进程间通信(1)---匿名管道与命名管道
管道是进程间通信一种基本的的一种方式,管道又分为两种,匿名管道和命名管道,先说匿名管道匿名管道(pipe)#include int pipe(int filedes[2]);调用pipe时会在内核中开辟一个缓冲区,使用时fileds[0]为输出端,fileds[1]为写入端口,调用成功时返回0,失败时返回-1;pipe的特点:1:它只能在有血缘关系的进程间进行通信。2:它只能进行单项通信,一个进
2016-05-29 16:54:16 784
原创 数据结构--二叉树的线索化
线索二叉树它解决了无法直接找到该结点在某种遍历序列中的前趋和后继结点的问题,出现了二叉链表找左、右孩子困难的问题,线索二叉树又分为前序线索化,中序线索化和后序线索化,分别用不同的逻辑去实现。线索二叉树的实现思想:借用一个枚举类型tag其中包含两个状态Link(代表有数据),thread(代表下一个节点为空)在一个节点的左节点或者右节点为空的情况下,将它的left或right设为thread,则它的
2016-05-29 16:54:13 241
原创 C语言下的FILE指针与Linux的文件描述符
FILE*:它是C库中定义的一个结构体指针,我们在C语言文件操作时打开一个文件返回的指针类型就是它,在C库中是这样定义的,其中的_file它是一个整数,就是作为文件索引的描述符,C库是建立在系统调用上的,这个FILE结构体可以说是一个包装,底层还是用文件描述符对磁盘上的文件进行连接的。650) this.width=650;" src="http://s4.51cto.com/wyfs02/M00
2016-05-29 16:54:10 1200
原创 数据结构--二叉树(1)
二叉树构建:二叉树的构建采用的是先序遍历,->先储存根节点然后左右节点,用递归的思想将所有数据放在树中。代码实现:实现了4种访问方法,先序,中序,后序,和层序的访问方法都采用递归的方式。#include#include#includeusing namespace std;template struct rootnode{ T _value; rootnode *_leftnod
2016-05-29 16:54:07 171
原创 数据结构-- 广义表
广义表(Lists,又称列表)是一种非线性的数据结构,是线性表的一种推广。即广义表中放松对表元素的原子限制,容许它们具有其自身结构。思想:广义表就类似下图的结构,他的大体(下图第一行)相当于一个带头结点的链表, 代码思想,首先要有一个头结点为HEAD类型,每一个广义表有且只有一个HEAD,而后每个节点如果有分支则把它定义为SUB类型,SUB便是它分支的一个新头他有一个su
2016-05-29 16:54:04 302
原创 数据结构---哈希表(KV模式)(除留余数法)
可以实现快速定位查找数据思想一:开一个适当大小的数组,讲需要存入的数据%上数组的_capacity的到的数作为他存放的位置,如果这个位置被占了,则在他的下一个位置存放数据(不会找不到空位置,下面会说到)。思想二:存放在数组上的是一个结构体,结构体包含一个索引值Key,存储值Value,和一个存储状态(枚举类型,EXIST,EMPTY,DELETE)可以使用这三种状态进行判断和懒人删除法(不用清除数
2016-05-29 16:54:01 1241
原创 数据结构----稀疏矩阵的快速转置
使用两种方法将稀疏矩阵快速转置#include#includeusing namespace std;templatestruct Triple //三元组{ size_t row; size_t col; T _value;};templateclass SparseMatrix{public: SparseMatrix(T *arr, size_t rowsi
2016-05-29 16:53:57 337
原创 简单模拟STL库中string的实现
#include#include#include#define CAPACITY 3using namespace std;class String{public: String(char *str="") :_str((char*)malloc(strlen(str)+1)), _size(strlen(str)) { strcpy(_str, str);
2016-05-29 16:53:55 164
原创 简单的单链表<实现单链表的增删查改逆序和寻找中间节点>
为了方便在c++中完成#include#include#includetypedef int datatype;typedef struct SingleLinkList{ datatype _data; SingleLinkList *_nextlist;}SingleLinkList;void PrintList(SingleLinkList* phead){ S
2016-05-29 16:53:52 161
原创 简单的动态线性表
头文件#ifndef __TEST_H__#define __TEST_H__#include#include#include#include#define MAX 3 //方便测试给一个小空间typedef int datatype;typedef struct Seqlist{ datatype *_Array; size_t _size; size_t _capa
2016-05-29 16:53:49 226
原创 调整数组使奇数全部都位于偶数前面
#includevoid sort(int *p, int len){ int *end = p; end = p + len - 1; while (p<end) { if (*p % 2 == 0) { while (end) { if (*end % 2 == 1) { break; } end--; }
2016-05-29 16:53:46 213
原创 指针数组与数组指针 和 函数指针与函数指针数组
很容易混淆的概念其实并不难理解1,指针数组;看字面意思就知道这一定是一个数组,里面的原酸全部是指针例如,定义一个简单的指针数组char *p[10]; //这就是一个包含十个字符指针的数组。例:#includeint main(){ char *p[7]; char arr[] = "abcdef"; int i = 0; for (i = 0; i { p[i] = arr; } pr
2016-05-29 16:53:43 172
原创 判断一个数或者一串字符串是不是回文数
一、判断一个整数是不是字符串 例123321是回文数#includeint my_reserve(int num){ int sum = 0; while (num) { int tmp = 0; tmp= num % 10; num = num / 10; sum = tmp+sum*10; } return sum;}int main(){ int
2016-05-29 16:53:40 621
原创 编写程序将"hello-NOworld"变成"hello-world"
从字符串str"hello-NOworld"中删除字符串sub"NO"如果找到并成功删除返回1,不然那返回0。#include#includeint my_substr(char *str,const char*sub){ assert(sub); char *cp1_str = str; char *cp2_str = str; const char *cp_sub = s
2016-05-29 16:53:37 258
原创 简单的冒泡排序
冒泡排序是一种简单的排序方法。#includeint main(){ int arr[] = { 1, 3, 5, 6, 8, 4, 2, 9, 7, 10 }; int i = 0; int k = 0; int len = sizeof(arr) / sizeof(arr[0]); for (i = 0; i <len; i++) { for (k = 0; k < len
2016-05-29 16:53:34 219
原创 使用可变参数列表实现求平均值的函数
#include#includeint average(int n, ...){ va_list num;--》va_list是类型,num是变量 va_start(num, n);初始化 int i = n; int sum=0; for (i = n; i > 0; i--) { sum += va_arg(num, int);读取加入num } return sum
2016-05-29 16:53:31 309
原创 揭露函数所传递参数的本来面目
传递函数时的会发生参数拷贝,新建地址,但是数组是除外的。例1;把两个数由小到大输出我们用两种不同的方式来验证我所说的机制。方式一;直接传。(不会发生交换)#includevoid change(int a, int b){ int tmp = a; a = b; b = tmp; printf("change:a=%d %p\n,b=%d %p\n", a, &a, b, &b);}
2016-05-29 16:53:29 187
原创 左右翻转二进制数==》繁琐与精简
实现://00000000000000000000000000011001//10011000000000000000000000000000这种翻转方法一和方法二思路大致一样,可以方法二却十分麻烦。方法一(简单)#include#includeunsigned int reverse_bit(unsigned int value){ int i = 0;
2016-05-29 16:53:25 247
原创 不使用(a + b) / 2这种方式,求两个数的平均值
#includeint ave(int a, int b){return (a & b) + ((a ^ b) >> 1);}int main(){int a = 10;int b = 14;printf("%d", ave(a,b));}//巧妙使用运算符会使程序简单本文出自 “痕迹” 博客,请务必保留此出处http://wpfbcr.blog.51cto.com/1069
2016-05-29 16:53:22 256
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人