自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(48)
  • 收藏
  • 关注

原创 线程安全(现象、原理、解决、死锁)

线程安全线程不安全现象黄牛抢票程序直接上代码,创建了4个线程分别表示4个抢票的,我们知道抢票,肯定是一人一票,不可能存在两个人买的是同一张票,接下来的代码的结果就是线程不安全的现象#include <stdio.h>#include <unistd.h>#include <pthread.h>#define THREADCOUNT 4int g_tickets = 100;void* threadStart(void* arg){ (v

2021-06-29 18:24:58 333 1

原创 常见指令及权限理解

VMware:用来安装虚拟机的软件,在电脑上虚拟出一套计算机硬件环境CentOS:操作系统,虚拟机Linux:操作系统内核Xshell:远程操作软件,可以远程操作linux主机、服务器在XShell和直接在VMware终端写代码是一样的虚拟机繁忙:删除vm-bit下的以lck结尾的文件夹,关闭VMware,重新使用管理员打开Linux下的目录结构磁盘:硬盘,用来存储文件一个硬盘至少有两个分区,交换分区和文件系统分区,交换分区只有一个,文件系统分区可以有多个交换分区:作为交换内存使用,通常大

2021-06-14 11:52:21 355

原创 【面试题总结】

函数重载C++允许在同一作用域中声明几个功能相似的同名函数,这些同名函数的形参列表(参数个数或类型或顺序)必须不同为什么C++支持函数重载,而C语言不支持?在LInux下,采用gcc编译完成后,函数名字的修饰没有发生改变;采用g++编译完成后,函数名字的修饰变成【_Z+函数长度+函数名+类型首字母】所以C语言没办法支持函数重载,因为同名函数没办法区分;而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载extern "C" > 有时候在C++工程中可能需

2021-05-05 16:09:47 91

原创 【面试题】TCP和UDP

TCP可靠机制有哪些?序列号、确认应答、超时重传数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明它下一次需要接收的数据序列号。如果发送迟迟未收到应答,那么有可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传这个时间一般是2RTT(报文段往返时间)+ 一个偏差值窗口控制(滑动窗口)与高速重发控制/快速重传(重复确认应答)确认应答机制对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段,这样性能较差.

2021-05-05 16:09:19 137

原创 【面试题】封装/继承/多态

面向对象C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题;C++是基于面向对象的,关注的是对象,将一件事情拆分成不同对象,靠对象之间的交互完成面向对象程序设计(Object-oriented programming,OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。面向对象的三大特征:封装、继承、多态封装概念:将数据和操作数据的方法有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互封装的本质是一种管理C++实现封装

2021-05-05 16:08:57 1206

原创 平衡二叉树

法一:自顶向下判断每个节点的左右子树是否为平衡二叉树class Solution {public: int Depth(TreeNode* root) // 求树的高度 { if(root == nullptr) return 0; else return max(Depth(root->left), Depth(root->right))+1; // 树的高度等于左右子树高度的最大值+1 .

2021-05-05 16:08:13 53

原创 括号序列

注意:题目描述里第二句话的意思!class Solution {public: /** * * @param s string字符串 * @return bool布尔型 */ bool isValid(string s) { // write code here if(s.size() == 0) return false; stack<char> stk; .

2021-05-05 16:07:50 60

原创 STL序列式容器 - vector

vector中常用接口构造与析构// 构造explicit vector(const allocator_type& alloc = allocator_type());explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type());template <class InputIterator&g

2021-05-05 16:06:38 62

原创 STL

什么是STL?STL(standard template library 标准模板库)是C++标准库的重要组成部分,它里面的代码都是按照模板来实现的。通俗说,STL将一些常见数据结构进行封装,还提供了一些通用类型的算法,这些算法非常灵活。通用类型是指:这些算法可以操作任意类型的数据,并且与数据类型无关灵活是指:算法具体做什么事,由用户使用时传递的参数决定STL六大组件(模块)容器:组织存储数据算法:要执行的操作① 与数据结构相关的算法:各个容器的接口② 与数据结构无关的通用算

2021-05-05 12:27:00 51

原创 STL序列式容器 - string

string类中的常用接口#include<string>构造与析构// 构造string();string(const string& str);string(const string& str, size_t pos, size_t len = npos);string(const char* s);string(const char* s, size_t n);string(size_t n, char c);template<cla

2021-05-04 21:20:10 73

原创 动态内存管理

内存空间的分区C语言的动态内存管理malloc / calloc / realloc1. mallocvoid* malloc(size_t size);用来向内存申请一块连续可用的空间,并返回指向这块空间的指针1)开辟成功,返回一个指向开辟好空间的指针;开辟失败,返回一个NULL指针,因此malloc的返回值一定要用assert检查2)返回值是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定3)如果参数size为0,malloc的行为是标准未定义的

2021-04-23 20:31:15 100

原创 类的默认成员函数【赋值运算符重载、取地址重载、const取地址重载】

赋值运算符重载C++为了增强代码可读性,引入了运算符重载。函数原型:返回值类型 operator操作符(参数列表)1、区分调用拷贝构造函数和赋值运算符重载拷贝构造函数:是用已经存在的对象初始化新创建的对象 赋值运算符重载:是用已经存在的对象给另一个已经存在的对象赋值例1:验证调用赋值运算符重载的时机class Date{public: Date(int year = 2000, int month = 4, int day = 21) { cout << "C

2021-04-21 23:23:10 306

原创 类的默认成员函数【拷贝(复制)构造函数】

拷贝(复制)构造函数用一个已经存在的对象初始化另一个新对象时,编译器会自动调用拷贝构造函数。1、拷贝构造函数是构造函数的一种重载形式2、拷贝构造函数的参数:单个形参,传递const类类型的引用1)如果传值引用,会引发无穷调用2)如果不加const,可能会因为我们不小心写错代码,改变已经存在的对象例1:拷贝构造函数参数不加constclass Date{public: Date(int year = 2000, int month = 4, int day = 21) { _ye

2021-04-19 17:39:25 1470

原创 类的默认成员函数【析构函数】

学习类的6个默认成员函数时关注四点:概念特性调用场景编译器自动生成的默认成员函数干了什么事析构函数对象销毁时,编译器自动调用析构函数,完成对对象中资源的清理工作。注意:销毁对象的工作是由编译器完成的。例1:使用malloc在堆上申请了空间,销毁对象时要调用析构函数进行资源清理typedef int DataType;class SeqList{public: SeqList(int capacity = 10) { _pData = (DataType*)malloc(ca

2021-04-18 22:12:49 897

原创 关于编译器生成默认构造函数的理解

构造函数默认构造函数无参的构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以称之为默认构造函数;默认构造函数只能有一个1、如何理解 “ 如果用户不显示定义构造函数,编译器会生成默认构造函数 ” ?例1:不显式定义构造函数class Date{private: int _year; int _month; int _day;};int main(){ Date d; system("pause"); return 0;}从监视窗口可以看到

2021-04-17 19:16:49 576

原创 类与对象【类对象模型、this指针】

类对象模型1、创建出来的类对象只保存成员变量,成员函数放在公共代码段例1:验证类对象模型class Student{public: char _name[20]; char _sex[3]; int _age;public: void InitStu(char name[], char sex[], int age) { strcpy(_name, name); strcpy(_sex, sex); _age = age; } void PrintStu() {

2021-04-17 19:15:14 100

原创 进程控制

进程创建1.vfork函数vfork函数创建出来的子进程的虚拟地址空间和父进程共用一份,如果父子进程同时并行运行,有可能会导致函数调用栈混乱。vfork解决函数调用栈混乱的方式:子进程先运行,子进程运行完毕之后,父进程再运行2.fork函数#include <unistd.h>pid_t fork();// 返回值:// fork成功:父进程返回子进程id;子进程返回0// fork失败:返回-1进程终止1、正常终止:代码运行完毕正常终止方式:1)main函数的re

2021-04-17 00:06:51 251

原创 宏和内联函数

#define 定义宏例1:宏常量#define MAX 10int main(){ const int a = 10; int b = 20; int* pa = (int*)&a; *pa = 100; printf("%d\n", MAX); printf("%d\n", a); printf("%d\n", b); cout << a << endl; cout << *pa << endl; return

2021-04-14 16:50:14 163

原创 引用

引用:引用不是定义一个新变量,而是给已经存在的变量取了一个别名,编译器不会为引用变量开辟空间,它和引用的实体共用同一块内存空间。类型& 引用变量名(对象名) = 引用实体引用特性:1.引用在定义时必须初始化2.一个变量可以有多个引用void TestRef(){ int a = 10; int b = 1; // 一个变量可以有多个引用 int& ra = a; // 引用在定义时必须初始化 int& rra = a; // 下边三个地址一样,说明它们是同

2021-04-14 13:13:05 113

原创 二叉树链式结构的遍历

前序遍历法一:递归/** 1. Definition for a binary tree node. 2. struct TreeNode { 3. int val; 4. TreeNode *left; 5. TreeNode *right; 6. TreeNode() : val(0), left(nullptr), right(nullptr) {} 7. TreeNode(int x) : val(x), left(nullptr), r

2021-03-19 23:11:31 87

原创 【面试题】动态内存管理

C语言中动态内存管理方式1. mallocvoid* malloc(size_t size);用来向内存申请一块连续可用的空间,并返回指向这块空间的指针1)开辟成功,返回一个指向开辟好空间的指针;开辟失败,返回一个NULL指针,因此malloc的返回值一定要用assert检查2)返回值是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定3)如果参数size为0,malloc的行为是标准未定义的,取决于编译器2. freevoid free(void*

2021-03-18 00:00:47 99

原创 二叉树的镜像

思路交换根结点的左右子树的根6和10交换左子树根10的两个叶子结点9和11交换右子树根6的两个叶子结点5和7/** * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * }; */class Solution {public: /*..

2021-03-16 19:37:56 41

原创 删除链表中重复的结点

/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {public: ListNode* deleteDuplication(ListNode* pHead) { // 新建一个结点作为pHead的前一个,防止删除头节点后找不到后面的元素 L.

2021-03-15 20:43:23 38

原创 链表分割

思路创建两个新结点,用cur遍历pHead,当cur->val小于x时,将此时cur所在结点连接在shead后;当cur->val大于x时,将此时cur所在结点连接在mhead后;遍历结束后,将小于x的部分和大于x的部分的数据结合起来即可/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {}};*/class Partiti..

2021-03-15 19:41:15 49

原创 链表中倒数第k个结点

快慢指针法:这里的快指针只是比慢指针先走k步思路:先定义两个指针fast和slow,起始位置都在链表头部如果链表长度小于k,直接返回nullptr此时快慢指针同时向前走,而他们刚好相差k步,当fast到达链表末尾时,slow刚好到达倒数第k个位置/*struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { }};*/class Solution {pu.

2021-03-15 17:12:10 37

原创 链表的中间结点

快慢指针解法:定义两个指针slow和fast,初始位置都在head,slow一次走一步,fast一次走两步,当fast到达最后一个结点时,slow恰好来到一半的位置class Solution {public: ListNode* middleNode(ListNode* head) { ListNode *fast=head,*slow=head; while(fast!=nullptr && fast->next!=nullptr).

2021-03-15 16:45:24 50

原创 反转链表

迭代注意:要先保存当前节点cur的next指向的元素,然后再改变cur->next=prev,否则next的数据会找不到class Solution {public: ListNode* reverseList(ListNode* head) { ListNode* prev=nullptr; ListNode* cur=head; while(cur) { ListNode* next=cu..

2021-03-15 16:27:24 37

原创 移除链表元素

思路如果待删元素位于链表头部,直接删除会导致后面的节点找不到,所以通过设置哨兵来解决class Solution {public: ListNode* removeElements(ListNode* head, int val) { // 1.设置哨兵 ListNode* sentinel=new ListNode(0); sentinel->next=head; // 2.找待删除元素位置 Lis..

2021-03-15 16:20:00 43

原创 const关键字

const的使用1)const 修饰变量变量定义的同时必须初始化,功能是对变量声明为只读特性,保护变量值以防被修改const int i = 5;int const i = 5;i = 10; //不能修改i的值,错误以上两种写法都是正确的,若想对i重新赋值,如i = 10,则是错误的2)const 修饰数组数组元素与变量相似,具有只读属性,不能被修改const int array[5] = {1, 2, 3, 4, 5};array[0] = 7; // 错误3)co

2021-02-17 12:55:24 68

原创 day1

#include<iostream>#include<vector>#include<algorithm>using namespace std;int main(){ int n; cin>>n; vector<int> v(100000,0); v.resize(3*n); for(int i=0;i<v.size();i++) { cin>>v[i];..

2020-11-26 12:09:46 51

原创 Linux线程的互斥与同步

为了解决线程安全的问题我们引入了互斥Linux线程互斥1.互斥相关背景概念临界资源:多线程执行流共享的资源临界区:每个线程内部访问临界资源的代码互斥:同一时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用原子性:不会被任何调度机制打断的操作,该操作只有两种状态,完成与未完成2.互斥锁先让我们看一段代码#include<stdio.h>#include<unistd.h>#include<pthread.h>#def

2020-11-18 17:30:06 208 2

原创 String类接口

String类的常用接口1.构造和析构1.string() // 构造空的string类对象2.string(const char* s)// 用C-string来构造string类对象3.string(size_t n,char c)// string类对象包含n个字符c4.string(const string&s)// 拷贝构造5.string(const string&s,size_t pos,size_t n)// 从pos位置开始拷贝n个字符构造strin

2020-11-12 15:43:13 255

原创 系统调用IO接口

int open( char *filename , int flag , mode_t mode);1)相关解读参数:(要打开的文件名称,选项,权限)flag :选项参数 打开方式必选项(只能选择其一):O_RDONLY :只读O_WRONLY :只写O_RDWR :读写可选项:O_CREAT :文件存在则打开,不存在则创建O_EXCL与O_CREAT同时使用(O_CREAT|O_EXCL):文件存在则报错,不存在则创建O_TRUNC:打开文件的同时清空原有内容O_APPE.

2020-07-21 21:21:10 258

原创 标准库IO接口

FILE *fopen(char *filename,char *mode);参数:(文件名称,打开方式)打开方式:1)r 只读2)r+ 读写3)w 只写4)w+ 读写5)a 追加写,文件不存在时创建新文件6)a+ 追加读写7)b 二进制操作r+和w+的区别:r+读写打开文件,若文件不存在则报错;w+读写打开文件,若不存在则创建,若存在清空原有内容返回值:返回一个FILE*的文件流指针作为文件的操作句柄;失败返回NULLsize_t fread(char *buf,si.

2020-07-15 23:20:30 288

原创 实现一个迷你Shell

Shell的主要流程1.等待标准输入2.进行字符串解析,得到命令名称以及参数3.创建子进程4.子进程中进行程序替换,运行指定的指令5.父进程等待,等待子进程命令执行完毕代码实现#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>int main(){ //增加一个shell提示 printf("[test@loca

2020-07-12 11:43:25 246

原创 进程控制2(进程替换)

进程替换进程替换:替换一个进程正在运行的程序,让当前进程pcb调度运行管理另一个新的程序替换原理:用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。即:将一个新的程序加载到内存中,修改当前进程pcb的页表信息(还会初始化虚拟地址空间),让这个页

2020-07-09 23:00:48 171

原创 类与对象总结2(6个默认成员函数)

类的六个默认成员函数空类中并不是什么都没有,任何一个类在我们不写的情况下,都会自动生成下面6个默认成员函数。构造函数主要完成初始化工作析构函数主要完成清理工作拷贝构造是使用同类对象初始化创建对象赋值重载主要是把一个对象赋值给另一个对象取地址运算符重载const取地址运算符重载构造函数构造函数是特殊的成员函数,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次。构造函数的主要任务是初始化对象,而不是开空间创建对象。特征:1)函数

2020-07-07 22:54:54 133

原创 类与对象总结1

-面向过程和面向对象面向过程:数据和操作数据的方法是分离开的面向对象:封装 继承 多态类的引入C语言中有结构体,C++中也有结构体(C++要兼容C语言),用class来代替C语言中,结构体中只能定义变量;在C++中,结构体不仅可以变量还可以定义函数用class定义的类:不是一个具体的变量,只是一种描述,没有分配实际的存储空间用类定义的变量:是一个具体的变量,开辟空间类的定义类的两种定义:1)类的声明和定义全部放在类中,编译器可能会将成员函数当成内联函数;2)类的声明和定义分开,将声明放

2020-07-03 12:33:09 89

原创 mysql+jdbc

/** * */package com.jia.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.util.Scanner;/** * @Description * JDBC: * 1、加载驱动 * 2、获取连接(Java连接mysql数据库) * 3、预执行(准备好SQL语句) * 4、执行 * 5、释放资

2020-06-30 22:29:55 122

原创 进程控制1

进程创建pid_t fork(); //pid_t 就是一个整形通过复制父进程创建子进程,子进程独立于父进程,fork的父子进程运行顺序不定,取决于内核的调度算法进程调用fork,当控制转移到内核中的fork代码后,内核做:1)分配新的内存块和内核数据结构给子进程2)将父进程部分数据结构内容拷贝至子进程3)添加子进程到系统进程列表当中4)fork返回,开始调度器调度父子进程数据独有,代码共享(因为代码是只读的,不能改变)写时拷贝技术子进程创建出来后,各个虚拟地址在物理内存中

2020-06-30 22:26:07 90

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除