日志系统前置知识

news2024/9/22 13:29:53

日志:程序运行过程中所记录的程序运行状态信息。通过这些信息,以便于程序员能够随时根据状态信息,对系统的运行状态进行分析。功能:能够让用户非常简便的进行日志的输出以及控制。

同步写日志

同步日志是指当输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑语句,日志输出语句与程序的业务逻辑语句将在同⼀个线程运行。每次调用⼀次打印日志API就对应⼀次系统调用write写日志文件。

在高并发场景下,随着日志数量不断增加,同步日志系统容易产生系统瓶颈: 一方面,大量的日志打印陷入等量的write系统调用,有⼀定系统开销。 另一方面,使得打印日志的进程附带了大量同步的磁盘IO,影响程序性能。

异步写日志  

异步日志是指在进行日志输出时,日志输出语句与业务逻辑语句并不是在同⼀个线程中运行,而是有专门的线程用于进行日志输出操作。业务线程只需要将日志放到⼀个内存缓冲区中不用等待即可继续执行后续业务逻辑(作为日志的生产者),而日志的落地操作交给单独的日志线程去完成(作为日志的消费者), 这是⼀个典型的生产-消费模型。

这样做的好处是即使日志没有真的地完成输出也不会影响程序的主业务,可以提高程序的性能: 主线程调用日志打印接口成为非阻塞操作,同步的磁盘IO从主线程中剥离出来交给单独的线程完成。

不定参宏函数

#include <stdio.h>
#define LOG(fmt,...) printf("[%s:%d]" fmt,__FILE__,__LINE__,##__VA_ARGS__);//fmt是格式化字符串,包含许多格式化字符,要从后面取出各种各样不同的参数来组织字符串, 而...标识是不定参,而宏__VA_ARGS__是使用不定参。##是告诉我们当不定参是空的时候则取消前面的逗号
int main()
{
    printf("[%s:%d]""%s",__FILE__,__LINE__,"hello wjj\n");//__FILE__,__LINE__两个宏说明是所在文件和行号。
    LOG("%s%d\n","wjj",666);
    LOG("hello wjj\n");//此时不定参是空,所以##起了作用。
    return 0;
}

 


#include <iostream>
#include <cstdarg>
void printNum(int n, ...) //打印数字,我们首先得确定有多少个数字,n代表传入数字的个数,而传的数字是不确定的。
{
    va_list al;
    va_start(al, n);//获取地址参数的起始地址,这里就是获取参数n之后的第一个不定参数的起始地址
    for (int i = 0; i < n; i++) 
    {
        int num = va_arg(al, int);//从不定参数中获取出⼀个整形参数,这也是va_arg函数第二个参数的意思。
        std::cout << num << std::endl;
    }
    va_end(al);//清空可变参数列表--其实是将al指针置空
}
int main()
{
    printNum(3,1,2,3);
    return 0;
}
//printf前面格式化的字符串里面格式化的字符%d、%s告诉我们编译器接下来应该从后面取几个字节的数据当做整型数据还是字符串来进行处理。

//模拟实现一下printf的实现
#include <iostream>
#include <cstdarg>
void myprintf(const char *fmt, ...) 
{
    char *res;
    va_list al;
    va_start(al, fmt);//fmt有什么格式化的字符,决定我们从后面取出什么类型的数据
    int len = vasprintf(&res, fmt, al);//int vasprintf(char **strp, const char *fmt, va_list ap);借用res会自己申请空间,根据fmt格式化字符,从格式化参数列表al里面取出一个一个的参数进行数据组织,并放入申请的空间里面去。 
    va_end(al);
    std::cout << res << std::endl;
    free(res);//要释放
}
int main()
{
    myprintf("%s-%d", "wjj", 25);
    myprintf("hello wjj");
    return 0;
}

#include <iostream>
#include <cstdarg>
#include <memory>
#include <functional>
void xprintf() //对函数模板进行特化,增加一个无参的形式。
{
    std::cout << std::endl;
}
template<typename T, typename ...Args>//后者定义的是一个不定参参数包类型
void xprintf(const T &value, Args &&...args) 
{
    std::cout << value << " ";//先打印第一个参数
    if ((sizeof ...(args)) > 0) //获得参数包的个数
    {
        xprintf(std::forward<Args>(args)...);//采用一种递归的思想,完美转发,你传递过来的时候是左值,现在就还是左值。 并且还要补充一个无参的形式
    }
    else 
    {
        xprintf();
    }
}
int main()
{
    xprintf("wjj");
    xprintf("wjj", 666);
    xprintf("hello", "wjj", 666);
    return 0;
}

  

设计模式

单例模式

⼀个类只能创建⼀个对象,即单例模式,该设计模式可以保证系统中该类只有⼀个实例,并提供⼀个访问它的全局访问点,该实例被所有程序模块共享。

//饿汉模式,用空间换时间的思想
class Singleton 
{
private:
    static Singleton _eton;//使用static来修饰。这里属于成员声明,并非定义,类内的静态成员需要在类外进行定义。
private:
    Singleton():_data(99){std::cout<<"单例对象构造\n";}//构造函数私有化,保证类外无法实例化对象,只能在类内实例化,
    ~Singleton(){}
    int _data;
public:
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton& getInstance() //提供一个访问接口
    {
        return _eton;
    }
    int GetData(){return _data;}
};
Singleton Singleton::_eton;//类内的静态成员需要在类外定义。静态对象的资源是在静态区的,它的生命周期随整个程序的,它的初始化构造是在我们程序初始化阶段就完成的。不管你用不用,这个对象的资源都已经分配了。

int main()
{
    std::cout<<Singleton::getInstance().GetData()<<std::endl;//就算没有这行代码,这个单例对象也会构造
    return 0;
}

//懒汉模式,延迟加载的思想,也就是一个对象到用的时候在进行实例化,而不是程序一起来不管用与否都进行实例化
//实现方法:定义对象的时候是定义一个对象的指针,在通过访问接口的时候发现其为空再去new一个对象
class Singleton { 
private:
    Singleton():_data(99){std::cout<<"单例对象构造\n";}//构造函数私有化,保证类外无法实例化对象
    ~Singleton(){}
    int _data;
public: 
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton& getInstance() 
    { 
        static Singleton _eton;//确保C++11起,静态变量将能够在满⾜thread-sa fe的前提下唯⼀地被构造和析构,这里静态局部对象的定义是线程安全的,多个线程试图同时初始化同一个静态局部变量时,初始化只会发生一次。
        return _eton; 
    } 
    int GetData(){return _data;}
}; 

int main()
{
    std::cout<<Singleton::getInstance().GetData()<<std::endl;//没有这行代码,这个单例对象不会构造
    return 0;
}

工厂模式

工厂模式是⼀种创建型设计模式, 它提供了⼀种创建对象的最佳⽅式。在工厂模式中,我们创建对象 时不会对上层暴露创建逻辑,而是通过使用⼀个共同结构来指向新创建的对象,以此实现创建-使用的分离。

//简单⼯⼚模式:通过参数控制可以⽣产任何产品
// 优点:简单粗暴,直观易懂。使⽤⼀个⼯⼚⽣产同⼀等级结构下的任意产品
// 缺点:
// 1. 所有东西⽣产在⼀起,产品太多会导致代码量庞⼤
// 2. 开闭原则遵循(开放拓展,关闭修改)的不是太好,要新增产品就必须修改⼯⼚⽅法。
class Fruit 
{
public:
    Fruit(){}
    virtual void show() = 0;
};
class Apple : public Fruit 
{
public:
    Apple() {}
    virtual void show() 
    {
        std::cout << "我是⼀个苹果" << std::endl;
    }
};
class Banana : public Fruit 
{
public:
    Banana() {}
    virtual void show() 
    {
        std::cout << "我是⼀个⾹蕉" << std::endl;
    }
};

class FruitFactory 
{
public:
    static std::shared_ptr<Fruit> create(const std::string &name) 
    {
        if (name == "苹果") 
        {
            return std::make_shared<Apple>();
        }
        else if(name == "⾹蕉") 
        {
            return std::make_shared<Banana>();
        }
        return std::shared_ptr<Fruit>();
    }
};
int main()
{
    std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
    fruit->show();
    fruit = FruitFactory::create("⾹蕉");
    fruit->show();
    return 0;
}


 

//工厂方法模式:在简单⼯⼚模式下新增多个⼯⼚,多个产品,每个产品对应⼀个⼯⼚。
#include <iostream>
#include <memory>
#include<string>
class Fruit
{
public:
    Fruit() {}
    virtual void show() = 0;
};
class Apple : public Fruit
{
public:
    Apple() {}
    virtual void show()
    {
        std::cout << "我是⼀个苹果" << std::endl;
    }

private:
    std::string _color;
};
class Banana : public Fruit
{
public:
    Banana() {}
    virtual void show()
    {
        std::cout << "我是⼀个⾹蕉" << std::endl;
    }
};
class FruitFactory
{
public:
    virtual std::shared_ptr<Fruit> create() = 0;
};
class AppleFactory : public FruitFactory
{
public:
    virtual std::shared_ptr<Fruit> create()
    {
        return std::make_shared<Apple>();
    }
};

class BananaFactory : public FruitFactory
{
public:
    virtual std::shared_ptr<Fruit> create()
    {
        return std::make_shared<Banana>();
    }
};

int main()
{
    std::shared_ptr<FruitFactory> ff(new AppleFactory()); 
    std::shared_ptr<Fruit> fruit_apple = ff->create();
    fruit_apple->show();
    ff.reset(new BananaFactory());//更改fruit_apple管理的对象
    std::shared_ptr<Fruit> fruit_banana = ff->create();
    fruit_banana->show();
    return 0;
}

//抽象工厂:围绕一个超级工厂创建其他工厂。每个生成的工厂按照工厂模式提供对象。
//思想:将工厂抽象成两层,抽象工厂 & 具体简单工厂子类, 在工厂子类种生产不同类型的子产品
#include<iostream>
#include<memory>
class Fruit {
    public:
        Fruit(){}
        virtual void show() = 0;
};
class Apple : public Fruit {
    public:
        Apple() {}
        virtual void show() {
            std::cout << "我是一个苹果" << std::endl;
        }
    private:
        std::string _color;
};
class Banana : public Fruit {
    public:
        Banana() {}
        virtual void show() {
            std::cout << "我是一个香蕉" << std::endl;
        }
};
class Animal {
    public:
        virtual void voice() = 0;
};
class Lamp: public Animal {
    public:
        void voice() { std::cout << "咩咩咩\n"; }
};
class Dog: public Animal {
    public:
        void voice() { std::cout << "汪汪汪\n"; }
};

class Factory //通过这个抽象工厂类派生出水果工厂和动物工厂
{
    public:
        virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;
        virtual std::shared_ptr<Animal> getAnimal(const std::string &name) = 0;
};

class FruitFactory : public Factory {
    public:
        virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {
            return std::shared_ptr<Animal>();//生产水果就采用返回一个空的智能指针就可以了
        }
        virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {
            if (name == "苹果") {
                return std::make_shared<Apple>();
            }else if(name == "香蕉") {
                return std::make_shared<Banana>();
            }
            return std::shared_ptr<Fruit>();
        }
};

class AnimalFactory : public Factory {
    protected:
    public:
        virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {
            return std::shared_ptr<Fruit>();
        }
        virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {
            if (name == "小羊") {
                return std::make_shared<Lamp>();
            }else if(name == "小狗") {
                return std::make_shared<Dog>();
            }
            return std::shared_ptr<Animal>();
        }
};

class FactoryProducer {
    public:
        static std::shared_ptr<Factory> getFactory(const std::string &name) {
            if (name == "动物") {
                return std::make_shared<AnimalFactory>();
            }else {
                return std::make_shared<FruitFactory>();
            }
        }
};

int main()
{
    std::shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("水果");//先生产水果工厂
    std::shared_ptr<Fruit> fruit_apple=fruit_factory->getFruit("苹果");
    fruit_apple->show();
    std::shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动物");//先生动物果工厂
    std::shared_ptr<Animal> animal_dog=animal_factory->getAnimal("小狗");
    animal_dog->voice();
    return 0;
}

建造者模式

建造者模式是⼀种创建型设计模式, 使⽤多个简单的对象⼀步⼀步构建成⼀个复杂的对象,能够将⼀ 个复杂的对象的构建与它的表⽰分离,提供⼀种创建对象的最佳⽅式。主要⽤于解决对象的构建过于 复杂的问题。

#include <iostream>
#include <memory>
#include<string>
/*抽象电脑类,里面有许多零部件需要安装*/
class Computer {
    public:
        using ptr = std::shared_ptr<Computer>;
        Computer() {}
        void setBoard(const std::string &board) {_board = board;}//一个电脑类得由各个下属的子类才能完成构造,比如说键盘
        void setDisplay(const std::string &display) {_display = display;}//得有显示器
        virtual void setOs() = 0;//得有操作系统,这是一个抽象类不同类型电脑得由不同操作系统。
        std::string toString() {
            std::string computer = "Computer:{\n";
            computer += "\tboard=" + _board + ",\n"; 
            computer += "\tdisplay=" + _display + ",\n"; 
            computer += "\tOs=" + _os + ",\n"; 
            computer += "}\n";
            return computer;
        } 
    protected://方便派生列访问呢
        std::string _board;//构造电脑需要的三个零部件
        std::string _display;
        std::string _os;
};

/*派生出具体产品类*/
class MacBook : public Computer {
    public:
        using ptr = std::shared_ptr<MacBook>;
        MacBook() {}
        virtual void setOs() {
            _os = "Max Os X12";
        }
};

/*抽象建造者类:将零件建造出来,包含创建一个产品对象的各个部件的抽象接口,建造者类是先将各个零部件生产出来,然后返回具体的对象*/
class Builder {
    public:
        using ptr = std::shared_ptr<Builder>;
        virtual void buildBoard(const std::string &board) = 0;
        virtual void buildDisplay(const std::string &display) = 0;
        virtual void buildOs() = 0;
        virtual Computer::ptr build() = 0;
};

/*具体产品的具体建造者类:实现抽象接口,构建和组装各个部件*/
class MackBookBuilder : public Builder {
    public:
        using ptr = std::shared_ptr<MackBookBuilder>;
        MackBookBuilder(): _computer(new MacBook()) {}
        virtual void buildBoard(const std::string &board) {
            _computer->setBoard(board);
        }
        virtual void buildDisplay(const std::string &display) {
            _computer->setDisplay(display);
        }
        virtual void buildOs() {
            _computer->setOs();
        }
        virtual Computer::ptr build() {
            return _computer;
        }
    private:
        Computer::ptr _computer;
};

/*由于零部件的构造还会有顺序要求,所以这里采用指挥者类,提供给调用者使用,通过指挥者来获取产品*/
class Director {
    public:
        Director(Builder* builder):_builder(builder){}//指挥者指挥的是一个Builder对象
        void construct(const std::string &board, const std::string &display) //建造对象
        {
            _builder->buildBoard(board);
            _builder->buildDisplay(display);
            _builder->buildOs();
        }
    private:
        Builder::ptr _builder;
};

int main()
{
    Builder *buidler = new MackBookBuilder();//MackBookBuilder建造者建造mac电脑,工人建造没有顺序之分
    std::unique_ptr<Director> pd(new Director(buidler));//pd指挥建造者如何建造,先做什么后做什么。
    pd->construct("英特尔主板", "LG显示器");
    Computer::ptr computer = buidler->build();
    std::cout << computer->toString();
    return 0;
}

 代理模式

代理模式指代理控制对其他对象的访问, 也就是代理对象控制对原对象的引⽤,完成原对象基础之上的一些额外功能。

/*房东要把⼀个房⼦通过中介租出,而不是从房东手上租房*/
#include <iostream>
#include <string>
class RentHouse//租房类
{
public:
    virtual void rentHouse() = 0;
};
/*房东类:将房⼦租出去*/
class Landlord : public RentHouse//房东类
{
public:
    void rentHouse()
    {
        std::cout << "将房⼦租出去\n";
    }
};
/*中介代理类:代理了房东的类,对租房⼦进⾏功能加强,实现租房以外的其他功能*/
class Intermediary : public RentHouse
{
public:
    void rentHouse()
    {
        std::cout << "发布招租启⽰\n";
        std::cout << "带⼈看房\n";
        _landlord.rentHouse();
        std::cout << "负责租后维修\n";
    }
private:
    Landlord _landlord;
};
int main()
{
    Intermediary intermediary;
    intermediary.rentHouse();
    return 0;
}

 项目框架

日志系统:
作用:将一 条消息, 进行格式化称为指定格式的字符串后,写入到指定位置
1.日志要写入指定位置(标准输出,指定文件,滚动文件....),日志系统需要支持将日志消息落地到不同的位置---多落地方向
2.日志写入指定位置,支持不同的写入方式(同步,异步):
同步:业务线程自己负责日志的写入(流程简单,但是有可能会因为阻塞导致效率降低)
异步:业务线程将日志放入缓冲区内存,让其他异步线程负责将日志写入指定位置
3.日志输出以日志器为单位,支持多日志器(不同的项目组有不同的输出策略)、日志器的管理
模块划分:
日志等级模块:枚举出日志分为多少个等级---对不同的日志有不同等级标记- -以便于控制输出
日志消息模块:封装-条日志所需的各种要素 (时间,线程ID,文件名,行号,日志等级,消息主体.....)
消息格式化模块:按照指定的格式,对于日志消息关键要素进行组织,最终得到一个指定格式的字符串
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2105965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python百日进阶-Web开发-音频】Day707 - 时域处理 librosa.autocorrelate

文章目录 一、时域处理1.1 librosa.autocorrelate1.1.1 语法与参数1.1.2 例子1.1.2.1 计算完全自相关y1.1.2.2 计算长达 4 秒的起始强度自相关 一、时域处理 1.1 librosa.autocorrelate https://librosa.org/doc/latest/generated/librosa.autocorrelate.html 1.1.1 语法与参…

3. GIS后端工程师岗位职责、技术要求和常见面试题

本系列文章目录&#xff1a; 1. GIS开发工程师岗位职责、技术要求和常见面试题 2. GIS数据工程师岗位职责、技术要求和常见面试题 3. GIS后端工程师岗位职责、技术要求和常见面试题 4. GIS前端工程师岗位职责、技术要求和常见面试题 5. GIS工程师岗位职责、技术要求和常见面试…

828华为云征文|华为云Flexus X实例docker部署MinIO对象存储系统obs

828华为云征文&#xff5c;华为云Flexus X实例docker部署MinIO对象存储系统obs 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求&#xff0c;一定…

【Linux网络编程八】实现最简单Http服务器(基于Tcp套接字)

基于TCP套接字实现一个最简单的Http服务器 Ⅰ.Http请求和响应格式1.请求格式2.响应格式3.http中请求格式中细节字段4.http中响应格式中细节字段 Ⅱ.域名ip与URLⅢ.web根目录Ⅳ.Http服务器是如何工作的&#xff1f;一.获取请求二.分析请求2.1反序列化2.2解析url 三.构建响应3.1构…

虚拟机的安装-详细教程

目录 新建虚拟机 选择典型 安装操作系统 选择CentOS7 64位版本 虚拟机存放位置 磁盘容量 完成 编辑虚拟机 修改内存大小 设置处理器个数 选择镜像 开启虚拟机 进入界面&#xff0c;回车 选择语言 安装类型 磁盘分区 开启网络 设置密码和用户 重启 接受许可…

鸿蒙(API 12 Beta6版)图形【使用Text模块实现文本显示】方舟2D图形服务

场景介绍 ohos.graphics.text模块提供了接口创建复杂的文本段落&#xff0c;包括多样的文本样式、段落样式、换行规则等&#xff0c;并最终将这些信息转换为能在屏幕上高效渲染的布局数据。 接口说明 ohos.graphics.text常用接口如下表所示。 接口名描述pushStyle(textStyl…

【算法】单词出现次数和位置统计

【算法】单词出现次数和位置统计 题目描述 编写一个程序&#xff0c;用于统计一个给定单词在一段文本中出现的次数以及第一次出现的位置。如果单词在文本中出现&#xff0c;则输出出现次数和第一次出现的位置&#xff08;位置从0开始计算&#xff09;。如果单词没有出现&…

我完成第一个AI项目的全过程记录——对IMDB电影评论的情感分析

前言 这是我用时两天完成的第一个AI项目。 我的代码和运行结果放在kaggle上面&#xff0c;地址&#xff1a; Sentiment Analysis of IMDB Movie Reviews (90%&#xff09; 我参考的原作者kaggle项目地址&#xff1a;Sentiment Analysis of IMDB Movie Reviews 我如何选择的这个…

InstantX团队新作!基于端到端训练的风格转换模型CSGO

由InstantX团队、南京理工大学、北京航空航天大学以及北京大学联合提出了一种基于端到端训练的风格转换模型 CSGO&#xff0c;它采用独立的特征注入明确地解耦内容和风格特征。统一的 CSGO 实现了图像驱动的风格转换、文本驱动的风格化合成和文本编辑驱动的风格化合成。大量实验…

Java的时间复杂度和空间复杂度和常见排序

目录 一丶时间复杂度 二丶空间复杂度 三丶Java常见排序 1. 冒泡排序&#xff08;Bubble Sort&#xff09; 2.插入排序&#xff08;Insertion Sort&#xff09; 3.希尔排序&#xff08;Shell Sort&#xff09; 4.选择排序&#xff08;Selection Sort&#xff09; 5.堆排序&am…

视频汇聚平台LntonAIServer视频质量诊断功能--偏色检测与噪声检测

随着视频监控技术的不断进步&#xff0c;视频质量成为了决定监控系统性能的关键因素之一。LntonAIServer新增的视频质量诊断功能&#xff0c;特别是偏色检测和噪声检测&#xff0c;进一步强化了视频监控系统的可靠性和实用性。下面我们将详细介绍这两项功能的技术细节、应用场景…

【Leetcode】1-5

1 两数之和 1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 和为目标值 target 就是在找 target - nums[i] 利用 哈希表 查找只需要 O(1) class Solution {public int[] twoSum(int[] nums, int target) {HashMap<Integer, Integer> hm new HashMap<>();…

科研绘图系列:R语言柱状图分布(histogram plot)

介绍 柱状图(Bar Chart)是一种常用的数据可视化图表,用于展示和比较不同类别或组的数据。它通过在二维平面上绘制一系列垂直或水平的柱子来表示数据的大小,每个柱子的长度或高度代表一个数据点的数值。柱状图非常适合于展示分类数据的分布和比较。柱状图的特点: 直观比较…

使用ChatGPT半小时撰写优质学术报告,详细使用指南

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者七哥(yida985)交流,多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。经过数月爆肝,终于完成学术AI使用教…

C++ | Leetcode C++题解之第386题字典序排数

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> lexicalOrder(int n) {vector<int> ret(n);int number 1;for (int i 0; i < n; i) {ret[i] number;if (number * 10 < n) {number * 10;} else {while (number % 10 9 || numbe…

打包部署之---》Xshell使用不了如何部署

前端打包发布有很多种&#xff0c;常用 xshell 连接服务器打包发布&#xff0c;但是小编发现最近小编电脑上的Xshell7出现了一个问题&#xff0c;一直报50003错误&#xff0c;说是不是最新版本&#xff1b;让你升级 可是点击确定以后确提示小编已经是最新版本; 这个时候小编选择…

【Java】面向对象基础(创建类,认识构造器,this关键字)

文章目录 前言一、创建类二、面向对象的基础&#xff08;认识构造器&#xff09;三、this关键字总结 前言 学习Java面向对象的基础。 一、创建类 1、在创建class文件的时候&#xff0c;文件夹名称跟第一个创建出来的类名是一样的。 二、面向对象的基础&#xff08;认识构造器…

数据结构---双向链表(内存泄露相关知识)

一、内存泄露 内存泄露&#xff08;Memory Leak&#xff09;是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏是程序设计中常见的错误之一&#xff0c;其特点包…

C语言学习笔记 Day16(C10文件管理--下)

Day16 内容梳理&#xff1a; C语言学习笔记 Day14&#xff08;文件管理--上&#xff09;-CSDN博客 C语言学习笔记 Day15&#xff08;文件管理--中&#xff09;-CSDN博客 目录 Chapter 10 文件操作 10.5 文件状态 10.6 文件的随机读写 fseek()、rewind() &#xff08;1&…

chapter13-常用类——(String类)——day15

目录 466-String结构剖析 467-String结构剖析 468-String测试题1 469-String测试题2 470-String对象特性1 471-String对象特性2 472-String常用方法1 473-String常用方法2 474-String常用方法3 466-String结构剖析 1、接口Serializabel&#xff0c;说明String对象可以串…