自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Start with Hello Word

My name is WeiJiale(魏嘉乐),西安工业大学18级软件工程专业的小鸡仔,除了编程和健身目前还没有别的追求,很开心在这里能写下自己的first blood。据说每一个程序员都开始于Hello World,原本仅仅是两个单词而已,但经过了时间沉淀,这种默契的文化传承在编程中成为了一种特殊的情感标记。当然,我对编程的认识也由此开始,如同任何人类的语言一样,计算机编程语言提供了一种表达...

2019-09-16 15:50:46 242

原创 C++中引用类型的简单剖析

前言对于习惯使用C语言进行开发的同学们,在看到C++中出现的&符号,可能会陷入误区,因为在C语言中&符号表示了取地址符,但其实&在C++中却有着不同的意义与用途——引用。一:引用的简介1.1 引用概念引用就是给已经存在的变量取了一个别名,引用和它引用的变量共用同一块内存空间。比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。引用的声明方法:类型& 引用变量名 = 引用实体(引用类型必须和引用实体是同种类型)代码演示:void TestRef(){ int

2020-10-10 16:35:35 319

原创 编程思想:面向对象和面向过程的区别与联系

前言何谓面向对象?何谓面向过程?对于这编程界的两大思想,一直贯穿在我们学习和工作当中。我们知道面向过程和面向对象,但要让我们讲出来个所以然,又感觉是不知从何说起。而这种茫然,其实就是对这两大编程思想的迷糊之处。本文来详细阐述一下面向对象和面向过程的区别和联系。一:面向过程面向过程思想顾名思义其实就是面向解决问题的步骤进行编程。面向过程的编程思想总结起来就八个字——自顶向下,逐步细化!将要实现的功能描述为一个从开始到结束按部就班的连续的步骤(过程);依次逐步完成这些步骤,如果某一步的难度较大,

2020-10-07 20:53:55 5852

原创 C/C++中的关键字:extern的用法解析

前言在C/C++中,extern 关键字可以用于变量或者函数的声明前,还可以用于进行链接指定。一:extern 用于变量或函数的声明前二:extern 用于链接指定

2020-10-05 09:39:38 880

原创 Linux系统编程:生产者与消费者模型

前言生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加资源,消费者从存储空间中取走资源,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。...

2020-09-28 16:33:48 262

原创 Linux系统编程:死锁的产生和预防(银行家算法)

前言多个执行流在对多个锁资源进行争抢操作时,因为推进顺序不当导致执行流相互等待,流程无法继续推进,导致死锁。一:死锁的产生死锁产生的四个必要条件1. 互斥条件:同一时间一个锁资源只能被一个执行流加锁,直到释放。2. 不可剥夺条件:一个执行流在释放锁资源之前,其他的执行流无法剥夺占用资源。3. 请求保持条件:一个执行流请求被占有的锁资源时发生阻塞,还对已经获得的锁资源不进行释放。4. 环路等待条件:两个执行流相互请求对方的资源并且不释放已经得到的资源,相互等待。二:死锁的预防破坏死锁

2020-09-26 22:43:00 590

原创 Linux系统编程:多线程(概念、控制、安全)

前言线程是进程当中的一条执行流,执行一个程序中的部分代码,运行在进程的虚拟地址空间内部,共享进程的大部分资源,线程也被称为轻量级进程。进程:是系统资源分配的基本单位操作系统会为运行中的程序分配所需要的资源线程:是cpu调度的基本单位操作系统是通过pcb实现程序的调度和运行一:线程间的独有与共享1.1 线程间独有1. 线程ID:每个线程都有自己独有的线程ID,这个ID在进程中是唯一的,进程用线程ID来标识线程。2. 寄存器:线程间是并发运行的,每个线程都有自己不同的运行线索(上

2020-09-25 23:02:52 121

原创 C++类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)

前言当赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化。C语言中的类型转换形式:隐式类型转换和显示类型转换。C语言风格的类型转换格式简单,但可能造成数据精度的丢失以及代码不够清晰等问题,并且转换的可视性比较差。一:C++强制类型转换为了弥补C语言的缺陷,C++提出了自己的类型转化风格,由于C++要兼容C语言,所以C++中还可以使用C语言的转化风格。C++引入了四种命名的强制类型转换操作符:static_cast、reinterpre

2020-09-21 17:55:51 163

原创 C++设计模式:单例模式(饿汉模式+懒汉模式)

前言设计模式(Design Pattern)是一套经过分类的,被反复使用的,代码设计经验的总结。 为什么会产生设计模式这个概念呢?随着时间的沉淀,以及前人的总结,我们发现代码设计也是有规律的,一类特定的问题会被一种特定的模式解决,这就衍生出了设计模式的概念。使用设计模式的目的:为了代码的可重用性以及可靠性。设计模式是软件工程的基石脉络,如同大厦的结构一样,设计模式使代码编写真正工程化。一:单例模式单例模式即一个类在全局中(进程)只能创建一个实例。...

2020-09-21 00:15:29 411

原创 C++:特殊类的设计

前言掌握常见特殊类的设计方式,比如:只能在堆上创建对象的类、只能在栈上创建对象的类、不能被拷贝的类、不能被继承的类、只能创建一个对象的类。一:设计一个只能在堆上创建对象的类类实例化一个对象会调用构造函数或拷贝构造函数。设计思路:将类的构造函数私有化,防止他人调用拷贝在栈上生成对象。将类的拷贝构造函数声明为delete,防止拷贝构造在栈上生成对象。提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。代码演示:// 设计一个只能在堆上创建对象的类#include<iostr

2020-09-20 10:01:39 143

原创 C++:内存泄露(概念+危害+解决)

前言内存泄露(memory leak)是我们常常听说的一个名词,那么什么是内存泄露呢?内存泄露有什么危害呢?内存泄露应当怎样解决呢?今天我们一起来整理一下内存泄露相关的知识,对以上问题有一个明确的认知。一:什么是内存泄露1.1 内存泄露的概念内存泄露:由于疏忽或者错误(异常安全)导致程序未能释放已经不再使用的内存的情况。内存泄露并非是指内存在物理上的消失,而是指程序失去了对该内存的控制,导致的资源浪费。1.2 内存泄露的分类堆内存泄露(Heap Leak)通过malloc,realloc

2020-09-19 13:31:56 2201

原创 C++:基于RAII思想的智能指针

前言C++没有垃圾回收机制,new或者malloc的资源都需要我们手动进行释放。但有时也会发生忘记释放的问题,这就会造成内存泄漏或异常安全的问题。C++就引入了智能指针对上述问题进行解决。一:RAIIRAII 是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。我们实际上把管理一份资源的责任托管给了一个对象。不需要显式地释放资源。采用这种方式,对象

2020-09-17 18:55:26 247

原创 模拟实现 atoi 函数(C++版本)

前言只有注重代码质量的程序员,才能写出鲁棒、稳定的大型软件。往往我们容易忽略一些边界条件、特殊输入等看似细枝末节但实则至关重要的地方。 我们在写代码时,应当不断反思程序在思路或者代码中存在那些漏洞。一:模拟实现 atoi 函数atoi 函数的主要功能就是将一个字符串转为整数,例如:将 “12345” –> 12345。1.1 错误解法这个题目很简单,很多人都会在三分钟之内写下如下不到10行的代码:#include<iostream>using namespace std;

2020-09-14 23:21:40 341

原创 C++异常:异常体系

前言C语言传统的处理错误的机制:终止程序(比如:assert): 用户难以接受,发生内存错误就会终止程序。返回错误码: 系统的很多库的接口函数都是通过把错误码放到errno中,表示错误。需要程序员自己根据错误码去查找对应的错误。C标准库中setjmp和longjmp组合。实际中C语言基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的错误。今天我们主要来探究一下C++中处理异常的机制。一:C++异常概念异常是面向对象语法处理错误的一种方式。当一个函数发现自己无法处理

2020-09-13 11:40:38 264

原创 C++11:新特性(右值引用、移动语义、lambda表达式、线程库)

前言C++98是C++标准的第一个版本,以模板的方式重写C++标准库,引入了STL(标准模板库)。C++11则带来了数量可观的变化,其中包含了约140个新特性(正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库、右值引用和移动语义、lamber表达式),以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一种新语言。相比较而言,C++11能更好地用于系统开发和库开发、语法更加泛华和简单化、更加稳定和安全,不仅功能更强大,而且能提升程序

2020-09-11 21:30:16 350

原创 C++海量数据处理:位图和布隆过滤器

前言有一道非常经典的题目:给40亿个不重复的无序的无符号整数,再给一个无符号整数,如何快速判断这个数是否在这40亿个数中。关于这道题目我们首先想到的解法就是排序二分查找,或者借助关联式容器进行求解,但是40亿个数据的数据量是非常巨大的(16G),没有办法放入内存中,所以在面对这种海量数据处理的时候,我们今天来学习位图和布隆过滤器的相关知识,用来解决海量数据处理的问题。一:位图位图其实就是哈希结构的变形,同样通过映射来处理数据,采用直接定址法存储数据,只不过位图本身并不存储数据,而是通过存储一个比特位

2020-09-05 10:03:07 292

原创 STL关联式容器:unordered_map和unordered_set

前言在C++98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 O(logN),即最差情况下需要比较红黑树的高度次,当树中的结点非常多时,查询效率也不理想。在C++11中,STL又提供了4个unordered系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对unordered_map和unordered_set进行介绍。一:unordered_map和unordered_setunordered_map/unordered_s

2020-09-03 09:33:55 741

原创 高效的搜索方式:哈希

前言顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序结构查找时间复杂度为O(N),平衡树查找时间复杂度为O(logN),搜索的效率取决于搜索过程中元素的比较次数。有一种理想的搜索方法:可以不经过任何比较,一次直接从表中得到要搜索的元素。 如果构造一种存储结构,通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。一:哈希哈希表(Hash table,也叫散

2020-08-18 22:35:23 854

原创 STL关联式容器:map和set(基本操作+模拟实现)

前言在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。那么我们今天继续探索STL中的另一类容器——关联式容器:map。关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。一:map...

2020-08-01 00:14:02 278

原创 C++数据结构:红黑树的原理以及实现

前言之前我们学习了AVL树,说AVL树是具有特殊性质的二叉搜索树,而红黑树这种数据结构也是有着特殊性质的二叉搜索树,

2020-07-30 23:46:42 735

原创 C++数据结构:AVL树的原理以及实现

前言二叉搜索树虽然有较高的查找效率,但在数据有序或接近有序的情况下,二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度。一:AVL树AVL树又称高度平衡二叉搜索树。它可以是一颗空树,也可以是具有以下性质的二叉

2020-07-28 16:38:02 267

原创 C++数据结构:二叉搜索树的原理以及实现

前言我们今天在二叉树的基础上来梳理学习二叉搜索树的相关知识点,二叉搜索树也常被归类为一种搜索算法,并且在后续map和set的学习中需要二叉搜索树作为铺垫,有助于我们理解map和set的特性,不仅如此,二叉搜索树自身也是有着非常多的特性和优势。一:二叉搜索树的概念二叉搜索树(Binary Search Tree)又称二叉排序树和二叉查找树。它可以是一颗空树,也可以是具有以下性质的二叉树:若它的左子树不为空,则左子树上所有结点的值都小于根结点的值。若它的右子树不为空,则右子树上所有结点的值都大于根结

2020-07-25 22:40:10 315

原创 Linux系统下典型的网络IO模型

前言IO指的就是输入输出, 所谓的输入输出就是数据流在内存和硬盘之间的相互传输。并且输入输出都是相对于内存说的,数据从硬盘传输到内存属于输入,而数据从内存传输到硬盘属于输出。IO的过程其实就是发起IO调用后等待IO就绪条件,进行数据拷贝。Linux系统下有几种典型的IO模型,我们就来一起探索一下有关阻塞IO、非阻塞IO、信号驱动IO、异步IO的相关知识。一:阻塞IO...

2020-07-24 10:23:42 240

原创 Linux网络通信:其它协议及技术(DNS、ICMP协议、NAT技术)

前言在之前我们了解了Linux网络通信环境中应用层、传输层、网络层、链路层的典型协议及相关知识后,其实在整个通信环境中还有一些其它的协议及技术,如:DNS、ICMP协议、NAT技术等,正所谓八仙过海,各显神通,它们也都有自己独特的一面,接下来我们就一起来认识一下它们吧。一:DNS域名:服务器地址的别名,便于我们记忆,其实通过域名访问服务器的时候最终还是通过解析获取服务器的IP地址来访问服务器的。DNS(Domain Name System):域名系统,是一套从域名映射到IP地址的系统。用于存储IP地

2020-07-16 22:55:42 293

原创 Linux网络通信:链路层的典型协议以太网协议

前言Linux网络通信环境中的链路层主要负责相邻设备之间的数据帧传输,典型协议是以太网协议,典型设备是交换机。网络层主要偏向数据的传输方向,也就是数据的起点到终点,而链路层更加偏向相邻主机间数据如何传输,也就是数据在从起点到中的过程中数据的传输流程。一:以太网协议以太网协议用于在链路层组织数据,主导相邻主机之间的数据帧传输。1.1 以太网协议格式...

2020-07-14 23:09:51 363

原创 Linux网络通信:网络层的典型协议IP协议

前言Linux网络通信环境中的网络层主要负责地址管理与路由选择,为网络中的每条数据选择合适的路径,网络层的典型协议:IP协议。在之前的学习中我们对HTTP、UDP、TCP协议一定的了解后,我们一起来深入挖掘一下IP协议的相关知识。一:IP协议...

2020-07-11 22:59:09 252

原创 Linux网络通信:传输层的典型协议UDP协议和TCP协议

前言Linux网络通信环境中的传输层主要负责应用程序之间的数据传输,传输层有两个典型的协议:UDP协议和TCP协议。协议的特性影响着上层程序的编写,而协议的特性又来源于协议的实现,我们下面就来深入挖掘UDP协议和TCP协议。一:UDP协议UDP协议(User Datagram Protocol):称为用户数据报协议,是OSI参考模型中的一种无连接的传输层协议。1.1 UDP协议格式UDP 报文分为 UDP 报头和 UDP 数据区两部分。报头由 4 个 16 位长(2 字节)的字段组成,分别说明该

2020-07-10 09:17:20 1180 2

原创 Linux网络通信:应用层的典型协议HTTP协议

前言Linux网络通信环境中的应用层是直面程序员的一层,应用程序是程序员开发的,所以应用层的协议都是程序员自己定制的。一:自定制协议自定制协议:程序员根据应用的特点来根据数据的格式、数据的描述信息定义协议。举例:网络版计算器功能:客户端发送两个数字以及一个运算符给服务端,服务端获取到数据后运算完成返回结果。三个数据对象:int num1、int num2、char op1. 将所有数据转换成字符串并使用特殊字符间隔num1 ;num2 ;op ;这样就将数据按照指定格式组织起来了。2.

2020-07-07 23:24:30 416

原创 面向对象程序设计的三大特性(三):C++中的多态

前言在我们系统的学习了封装和继承之后,那自然少不了面向对象程序设计的另一大特性——多态,C++中的多态又是怎样的呢?下面带大家来一起梳理C++中多态的相关知识。1. 多态的概念顾名思义,多态就是多种形态。比如,买票这个行为,普通人买票时是全价买票,学生买票时是学生价买票,军人买票时是优先买票。多态:不同的对象去完成某个相同的行为时会产生出不同的状态。在继承中要构成多态的两个条件1.必须通过基类的指针或者引用调用虚函数2.被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写#inc

2020-07-05 00:00:16 313

原创 面向对象程序设计的三大特性(二):C++中的继承

前言众所周知,面向对象程序设计有三大特性:封装、继承、多态。在之前的学习中我们对C++中的封装有了一定层次的认知,那么C++中的继承是怎样实现的呢?今天就带大家来简单梳理一下C++中的继承。1. 继承的概念继承机制是面向对象程序设计使代码复用的重要手段,它允许程序员在保持原有类(基类、父类) 特性的基础上进行扩展,增加新的功能,这样产生的新类叫做 派生类(子类),继承展现了面向对象程序设计的层次结构,继承是类设计层次的复用。举个栗子:#include<iostream>#incl

2020-07-02 18:45:37 353

原创 STL容器适配器:stack、queue、priority_queue

前言容器适配器是一个封装了序列容器的类模板,它在一般序列容器的基础上提供了一些不同的功能,之所以称之为容器适配器,是因为它可以通过适配容器的现有接口来提供不同的功能。简单的理解容器适配器,其就是将不适用的序列式容器(包括 vector、deque 和 list)变得适用。STL中的三大容器适配器:stack、queue、priority_queue。一:deque(双端队列)在学习容器适配器之前我们首先了解一个叫做deque的序列容器。deque(双端队列): 是一个双端操作,任意位置O(1)插

2020-06-29 19:15:20 5263

原创 Linux网络套接字编程(socket详解)

前言套接字编程其实就是网络编程,套接字实际就是一套网络通信程序编写的接口,通过这些接口,并且提供相关信息,就可以实现传输层以下几层的操作。网络通信中涉及两台主机之间的通信:客户端(主动发送请求)、服务端(被动接收请求)。一:TCP/UDP协议的基本认识在TCP/IP网络体系结构中,TCP协议和UDP协议是传输层两种典型的协议,为上层用户提供级别的通信可靠性。UDP:用户数据报协议(User Data Protocol)无连接、不可靠、面向数据报不需要建立连接(发短信)不确保数据是否被对方

2020-06-01 23:11:28 816

原创 Linux网络通信:网络通信基础

前言网络就是利用物理链路将各个孤立的工作站或主机连接在一起组成的数据链路。通信就是人与人之间通过某种介质实现信息的交互。网络通信在Linux下简单理解其实就是不同主机的进程间通信。一:IP地址概念:IP地址(Internet Protocol Address):互联网协议地址(uint32_t无符号四个字节的整数)作用:IP地址在网络中唯一标识一台主机, 每一台主机都有自己的IP地址来精确定位主机,从而实现不同主机间的精确通信(知道数据是从哪台主机发送到哪台主机上)。并且网络通信中的

2020-05-27 00:10:24 370

原创 STL序列式容器:list(基本操作+模拟实现)

前言list类是STL中封装的链表模板类,并且底层实现是以带头双向链表作为基础进行封装的,甚至一些 STL 版本中(比如 SGI STL),list容器的底层实现使用的是带头双向循环链表list 容器中各个元素的前后顺序是靠指针来维系的,每个元素都配备了两个指针,分别指向它的前一个元素和后一个元素,list容器中的元素还可以分散存储在内存空间里(逻辑结构连续,物理结构分散)。list的优点:1.在任意位置插入删除数据的效率高2.不存在扩容的问题(拷贝数据、释放空间的代价)2.list支持前后

2020-05-26 01:28:23 371

原创 排序算法(四):归并排序(递归写法与非递归写法)

归并排序基本思想:归并排序是一种采用分治策略,将待排序序列分成若干个不可再分的子序列,先使每个子序列有序,再使子序列段间有序的高效排序算法。排序过程:分治思想

2020-05-24 15:18:14 478

原创 STL序列式容器:vector(基本操作+模拟实现)

前言vector类是STL中的另一大容器,经过封装,vector是一个可变长度并且拥有各种功能的顺序表,在其内部可以利用数组实现。vector和string在物理与逻辑结构上十分相似,不过vector是一个模板类,我们可以在其中存放任意类型的数据。vector的优点:1.可以通过下标进行随机访问2.在尾部插入或者删除元素时更加高效3.大小可以动态改变...

2020-05-23 12:08:26 472

原创 排序算法(三):交换排序(冒泡排序、快速排序的递归与非递归)

交换排序基本思想:所谓交换,就是根据序列中两个元素键值的比较结果来交换这两个元素在序列中的位置,将键值较大的元素向序列的尾部移动,键值较小的元素向序列的前部移动。排序分类:交换排序分为冒泡排序和快速排序一:冒泡排序排序过程:...

2020-05-20 12:34:15 286

原创 C语言中宏定义和函数的区别

前言在C语言中,对于一些常用或通用的代码段的封装可以有两种方式:函数和宏定义。这篇博客就来带大家梳理一下对于这两种方式我们在使用时应该如何抉择,以及它们的区别和优缺点。宏定义和函数的区别从程序的执行来看:函数调用需要开辟和释放栈空间带来开销(压栈、释放),不仅会降低代码效率,而且代码量也会大大增加。宏定义只在编译前进行,不分配空间,不占运行时间。总结:宏定义在代码规模和速度方面都比函数更胜一筹从参数的类型来看:函数的参数必须声明为一种特定的数据类型,如果参数的类型不同,就需要使用不

2020-05-19 20:51:34 1295

原创 C语言中常用的自定义数据类型(结构体、枚举、联合)

前言在程序编写的过程中,我们难免会遇到一些复杂的元素(例如学生:姓名、性别、学号)无法用单一的内置数据类型表示,于是就引入了自定义数据类型来描述这些复杂的元素。C语言中常见的自定义数据类型主要有:结构体、枚举、联合(结构体中主要解释位段)一:位段数据的存取一般以字节为单位,但某种情况下存储一个数据不必用一个或多个字节(例如:“真”或“假”用0或1表示只需要1个bit位),正是基于这种考虑,C语言又提供了一种叫做位段的数据结构。C语言允许在一个结构体中以位为单位来指定其成员所占内存长度, 这种以位为

2020-05-19 00:12:54 1089

原创 排序算法(二):选择排序(直接选排、堆排序)

选择排序基本思想:选择排序将序列分为已经有序和暂时无序两部分,遍历暂时无序的部分,将其中最小的元素放到有序序列的末尾,直到全部待排序的元素排完为止。排序分类:选择排序分为直接选择排序和堆排序一:直接选择排序排序过程:...

2020-05-15 17:26:37 598

空空如也

空空如也

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

TA关注的人

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