C++基础与深度解析 | 什么是C++ | C++开发环境与相关工具 | C++编译/链接模型

文章目录

    • 一、什么是C++
    • 二、C++的开发环境与相关工具
    • 三、C++的编译/链接模型

一、什么是C++

  C++是一门比较流行的编程语言(高级语言),同时也是一门复杂的语言。从TIOBE 编程社区指数中可以看出:在2024.04中,其编程语言受欢迎程度指标排名前三。

image-20240428222927645

image-20240428223107895

  C++语言是C语言的扩展,其继承了一些C++的特性。

  • 关注性能

    • 与底层硬件紧密结合

      “大端序”与“小端序”是硬件的概念。不同的计算机架构可能采用不同的字节序。例如,x86架构的计算机通常使用小端序,而一些其他架构,如SPARC、PA-RISC、和很多网络协议,则使用大端序。在进行跨平台数据交换时,字节序是一个重要的考虑因素,因为不同的系统可能会以不同的顺序解释字节。为了解决这个问题,经常使用标准化的字节序表示,如网络字节序(大端序),来确保数据的一致性。

      字节序有两种主要类型:

      • 大端序Big-endian:在大端序系统中,字的高位存储在低字节地址中。这意味着如果你有一个32位的字(或整数),并且它的值是0x12345678,那么在内存中,它会被存储为:

        地址 0x00: 0x12
        地址 0x01: 0x34
        地址 0x02: 0x56
        地址 0x03: 0x78
        

        大端序是因为它用“大”的字节来表示“高”的位。

      • 小端序Little-endian:在小端序系统中,字的高位存储在高字节地址中。这意味着如果你有一个32位的字(或整数),并且它的值是0x12345678,那么在内存中,它会被存储为:

        地址 0x00: 0x78
        地址 0x01: 0x56
        地址 0x02: 0x34
        地址 0x03: 0x12
        

        小端序是因为它用“小”的字节来表示“高”的位。

      #include <stdio.h> void show_mem_rep(char *start, int n)  
      { int i; for (i = 0; i < n; i++) printf(" %.2x", start[i]); printf("\n"); 
      } int main() 
      { int i = 0x01234567; show_mem_rep((char *)&i, sizeof(i)); 
      } 
      

      其输出为:(其输出形式即字节序与底层硬件或架构紧密结合)

      67 45 23 01		//表明硬件或架构为小端
      01 23 45 67 	//表明硬件或架构为大端
      
    • 对象生命周期的精确控制

      举例:比较C#与C++两种高级语言的对象生命周期的精确控制,两种语言使用不同的设计方案,是在易用性与性能之间的取舍。

      • C# 使用垃圾回收机制(线程)来自动管理内存,不用关注对象的销毁过程(易用性,但损耗性能)

      • C++从构造对象开始、使用、销毁,所有的这些操作都是程序员显式控制的

    • “Zero-overhead abstraction” —零开销抽象,使用抽象而不会引入额外的性能开销

      • 不需要为没有使用的语言特性付出成本

        int fun1()
        {int* x = new int(3);  //在堆上开辟内存,需要涉及到间接引用return *x;
        }int fun2()
        {int x = 3;	//在栈上开辟内存return x;
        }
        

        其汇编语言的结果为:

        fun1():push    rbpmov     rbp, rspsub     rsp, 16mov     edi, 4call    operator new(unsigned long)mov     DWORD PTR [rax], 3mov     QWORD PTR [rbp-8], raxmov     rax, QWORD PTR [rbp-8]mov     eax, DWORD PTR [rax]leaveret
        fun2():push    rbpmov     rbp, rspmov     DWORD PTR [rbp-4], 3mov     eax, DWORD PTR [rbp-4]pop     rbpret
        

        总结来讲:如果不需要使用堆这个概念,就不需要付出额外的成本

      • 使用一些语言特性不等于付出运行期成本(可能会被编译器所优化掉,进一步提升程序的性能)

        consteval auto fun(unsigned input)
        {unsigned res = 0;for (unsigned i = 0; i < input; ++i){res += i;}return res;
        }int main()
        {return fun(3);
        }
        

        其汇编语言结果为

        main:push    rbpmov     rbp, rspmov     eax, 3pop     rbpret
        

        consteval关键字是C++20的特性,表明函数只能在编译期运行,换句话说,在编译器中会执行函数逻辑,计算fun(3)的函数返回值。增加了编译期的负担,但编译期一般执行一次,换来运行期不会执行函数代码而直接获得结果。

  • 引入大量特性,便于工程实践

    • 三种编程范式:面向过程、面向对象、泛型编程与元编程
    • 函数重载、异常处理、引用

  C++是一系列不断衍进的标准集合,从C++98/03,C++11,C++14,C++17,C++20等不断衍进。涉及到

  • 语言本身的改进

    • Memory Model(内存模型)
    • Lambda Expression(Lambda表达式)
  • 标准库的改进

    • type_traits(泛型编程)、ranges(元编程)

    • auto_ptr(智能指针)

      auto_ptr 有一些限制和问题,例如它不满足某些标准容器和算法的要求,因为它的复制行为与其他标准容器和算法的预期行为不一致。此外,它也不支持多线程环境。在 C++11 中,auto_ptr 被新的智能指针类 std::unique_ptr 所取代。std::unique_ptr 提供了更好的异常安全性和更直观的所有权模型。std::unique_ptr 同样用于自动管理动态分配的内存,但它不会导致自动转移所有权,而是提供了 std::move 操作来显式转移所有权。推荐使用 std::unique_ptrstd::shared_ptr 来管理动态内存,而不是使用 auto_ptr

  C++标准的工业界实现,常见的编译器有MSVC/GCC/Clang…

  • 每个编译器可能并不完全遵照标准

  • 不同的实现存在差异

  使用C++开发程序,一定要关注程序的性能,这是C++语言的优势。同时,也要关注C++的标准。比如:在C++98标准时,在标准层面并没有规定如何开发多线程的程序,此时,就不得不使用Windows的多线程库与Linux的多线程库来开发多线程程序,造成程序的移植问题(在Windows上开发的程序不能在Linux上编译与运行)。在C++11之后引入了多线程开发库,这个库纳入了C++11标准中去,我们就应该使用这些库进行开发,使用标准是在避免移植问题。尽量避免使用平台特定的相关工具语言来进行开发。

二、C++的开发环境与相关工具

  • 编译环境

    Visual C++ / GCC(G++)/ Clang(Clang++)…

  • 集成开发环境

    Visual Studio 、 CodeLite、Code::blocks、Eclipse、Qt

  • 工具(主要是Linux上的)

    • /usr/bin/time

        用于测量程序执行时间的命令行工具。它可以用于获取程序运行时的资源使用情况,包括 CPU 时间、实际经过的时间、内存使用量等。这个工具对于性能分析和基准测试非常有用,因为它提供了关于程序执行效率的重要信息。常用的 /usr/bin/time 选项:

      • -p:打印所有可用的资源使用信息。
      • -v:显示详细的资源使用信息。
      • -o <file>:将资源使用信息输出到指定的文件中。
      • -f <format>:指定输出的格式。

      基本的使用方法如下:

      /usr/bin/time [options] command
      

      例如,要测量运行某个程序 program 的资源使用情况,可以使用:

      /usr/bin/time -p program
      

      这将输出程序的 CPU 时间(用户 CPU 时间和系统 CPU 时间)、实际经过的时间、平均内存使用量、最大内存使用量等信息。

      如果你想要将这些信息保存到文件中,可以使用 -o 选项:

      /usr/bin/time -o time_output.txt program
      

      这将把资源使用信息保存到 time_output.txt 文件中。

    • valgrind

        Valgrind 是一个开源的程序分析工具,它主要用于内存调试、内存泄漏检测、性能分析以及检测程序中其他的一些常见错误。Valgrind 通过模拟硬件来运行程序,这使得它能够在不修改程序的情况下检测到许多问题。

      以下是 Valgrind 的一些主要工具和用途:

      1. Memcheck:这是 Valgrind 最常用的工具之一,用于检测内存泄漏和内存越界等错误。
      2. CachegrindCallgrind:这两个工具用于性能分析,它们可以帮助开发者了解程序的缓存使用情况和函数调用情况。
      3. Helgrind:用于检测多线程程序中的竞态条件和锁的使用问题。
      4. Massif:一个堆分析工具,用于检测程序的堆内存使用情况。
      5. Drmgrind:用于检测程序中的 DRM(数字版权管理)相关的问题。
      6. BBV:一个简单的二进制代码查看器。
      7. VGDB:允许开发者使用 GDB 调试器来调试正在 Valgrind 运行的程序。
      8. Exp-ptrcheck:一个实验性的指针检查工具。

      使用 Valgrind 的基本命令格式如下:

      valgrind [options] program [program_arguments]
      

      例如,使用 Memcheck 工具检测程序中的内存问题:

      valgrind --leak-check=yes --show-leak-kinds=all --track-origins=yes program
      

      这个命令会启动 Memcheck 工具,检查所有类型的内存泄漏,并显示泄漏内存的来源。

        在使用 Valgrind 之前,确保你的程序是编译时带有调试信息的,通常是使用 -g 选项进行编译,这样 Valgrind 才能提供更详细的信息。同时,Valgrind 与优化过的代码配合使用时可能无法准确检测到所有问题,因此在调试时可能需要关闭或减少编译器的优化级别。

    • Cpp Reference–C++百科全书

      C++ Reference 的网址是:https://en.cppreference.com/,它是 C++ 程序员日常开发中的重要参考资源之一。它提供了关于 C++ 标准库、关键字、运算符、概念(C++20引入)、类和函数等的详细信息。当程序员需要查找特定函数的用法、类成员的详细信息或者语言特性的时候是非常有用的。

      C++ Reference 的网站内容通常包括:

      1. C++ 标准库:包括了所有标准库的容器、迭代器、算法、输入/输出库等的详细文档。
      2. 语言特性:涵盖了 C++ 的所有关键字、特殊成员函数、类型转换、模板等。
      3. C++11/14/17/20 新特性:对于每个新标准,C++ Reference 都提供了新特性的详细解释和用法示例。
      4. 示例代码:很多页面都包含示例代码,帮助读者更好地理解如何使用特定的语言特性或库功能。
      5. 兼容性信息:指出了不同 C++ 标准和编译器对特定特性的支持情况。
      6. 语法:提供了 C++ 语法的详细描述,包括表达式、语句和声明等。
      7. 概念(Concepts):C++20 引入的新特性,用于模板编程中对类型进行约束。
      8. 工具和技巧:提供了一些编程技巧和最佳实践。
      9. 搜索功能:允许用户快速搜索 C++ 特性和库组件。
    • Compiler explorer–在线编译器和代码分析工具

      Compiler Explorer 是一个功能强大的在线编译器和代码分析工具,它允许开发者查看不同编译器的编译结果,包括汇编语言输出。它通过可视化的方式展示了代码编译的细节,有助于提升编程技能和理解底层硬件的工作原理。

      使用 Compiler Explorer 的基本步骤通常包括:

      • 打开 Compiler Explorer 网站(如 https://godbolt.org/)。
      • 在左侧的编辑器中编写或粘贴代码。
      • 选择适当的语言和编译器版本。
      • 根据需要调整编译选项。
      • 查看右侧的汇编输出或执行结果。

      Compiler Explorer 的一些主要特点:

      1. 多语言支持:支持 C++、Rust、Go、Java 等多种编程语言的编译。
      2. 编译器版本:提供了不同编译器及其版本的选择,包括 GCC、Clang、MSVC 等。
      3. 汇编代码查看:可以查看源代码对应的汇编指令,有助于理解编译器如何将高级语言翻译成机器可以执行的指令。
      4. 性能分析:支持使用 LLVM-mca 工具进行静态性能分析。
      5. 代码分享:可以生成分享链接,让他人查看你的编译结果和汇编代码。
      6. 插件和集成:存在如 VSCode 插件等第三方工具集成 Compiler Explorer 的功能,提高开发效率。
      7. 开源项目:Compiler Explorer 是一个开源项目,可以在 GitHub 上找到其源代码和贡献指南。
      8. 实时编译:提供实时的、交互式的编译体验,可以即时看到更改代码后的影响。
      9. 编译选项:允许用户尝试不同的编译器选项,观察对源代码编译结果的影响。
      10. 多文件编译:支持 CMake 等工具进行多文件项目的编译
    • C++ insights

        要使用 C++ Insights,你可以直接访问它的网站(例如 https://cppinsights.io/)并在提供的编辑器中输入 C++ 代码,或者在安装了相应扩展的 VSCode 中使用它。

        C++ Insights 是一个基于 Clang 的工具,旨在帮助开发者更深入地理解 C++ 代码在编译时的内部工作机制。它通过展示编译器看到的 C++ 源码细节,揭示了模板、自动类型推导(auto)、decltype 等语言特性背后的实现。C++ Insights 可以作为一个网页工具使用,也可以集成到 Visual Studio Code(VSCode)中作为一个扩展。

      C++ Insights 的一些关键特性:

      1. 源码到源码的转换:C++ Insights 可以将 C++ 代码的复杂特性转换成等价的、更易理解的 C++ 代码形式。
      2. 编译器内部视角:它提供了一个窗口,让开发者能够看到编译器是如何解释 C++ 代码的。
      3. 模板推导:C++ Insights 可以展示模板参数推导的结果,帮助开发者理解模板元编程。
      4. 自动类型推导:对于 auto 关键字,C++ Insights 可以展示编译器推导出的具体类型。
      5. 声明和定义的展开:它能够展示由编译器生成的隐式声明和定义,例如,从 decltype 表达式中生成的类型声明。
      6. Visual Studio Code 扩展:C++ Insights 提供了一个 VSCode 扩展,允许在编辑器内部直接查看编译器的视角。
      7. 代码差异:C++ Insights 允许你比较原始源码和转换后的代码,从而更清楚地理解编译器做了哪些更改。
      8. 开源项目:C++ Insights 是一个开源项目,其代码库托管在 GitHub 上,社区成员可以查看源码、报告问题或贡献代码

三、C++的编译/链接模型

  最初,用到的是简单的加工模型

image-20240502141716735

简单加工模型的问题:无法处理大型程序

  • 加工耗时较长
  • 即使少量修改,也需要全部重新加工

  为了解决上述问题,提出解决方案:C++的编译/链接模型(分块处理

image-20240502141912799

分块处理的优点:

  • 编译耗资源但一次处理输入较少,可以很快完成编译

  • 链接输入较多(N个目标文件)但处理速度较快

  • 便于程序修改升级

由“分块处理”衍生出的概念

  • 定义 / 声明

  • 头文件 / 源文件

  • 翻译单元(编译时预处理阶段会将源程序变成翻译单元)

    源文件 + 相关头文件(直接/间接) - 应忽略的预处理语句

  • 一处定义原则

    • 程序级别:一般函数遵循一处定义原则
    • 翻译单元级别:内联函数、类、函数模板遵循一处定义原则

  C++的编译/链接模型对于源程序是如何操作的?

image-20240502144524215

  • 预处理

    • 将源文件转换为翻译单元的过程,会将源文件中的头文件进行展开

    • 防止头文件被循环展开

        在C或C++编程中,头文件的循环展开(也称为循环包含)是一个常见的问题,它发生在一个头文件被另一个头文件多次包含时。这可能导致编译错误,因为代码被重复定义。为了解决这个问题,有两种常用的方法:#ifdef 解决方案和 #pragma once 解决方案

      • #ifdef 解决方案

          这是一种传统的防止头文件循环展开的方法。它依赖于宏定义来检查头文件是否已经被包含过。

        基本的步骤如下:

        1. 在头文件的开始处,定义一个唯一的宏,通常是头文件名的全大写形式。
        2. 检查这个宏是否已经定义。如果没有定义,定义它,并包含头文件的内容。
        3. 在头文件的末尾,取消定义这个宏。
        // example.h
        #ifndef EXAMPLE_H
        #define EXAMPLE_H// 头文件内容#endif // EXAMPLE_H
        
      • #pragma once 解决方案(新的C++标准)

          #pragma once 是一种更现代的、更简洁的方法,它告诉编译器这个头文件应该只被包含一次。它被大多数现代编译器支持,并且不需要像 #ifdef 那样做宏的检查和取消定义。

        // example.h
        #pragma once// 头文件内容
        

      比较

      • 简洁性#pragma once 更简洁,不需要像 #ifdef 那样编写额外的代码。
      • 兼容性:虽然 #pragma once 被广泛支持,但不是所有的编译器都支持它。#ifdef 是一种更通用的方法,几乎所有的编译器都支持。
      • 可读性:使用 #ifdef 可以更清楚地看到头文件的保护机制,而 #pragma once 则简洁到几乎不可见。

        在实际开发中,可以根据项目的需求和编译器的支持情况来选择使用哪种方法。如果项目需要高度的可移植性,或者使用旧的编译器,可能会倾向于使用 #ifdef。如果追求代码的简洁性,并且使用的是支持 #pragma once 的现代编译器,那么 #pragma once 是一个很好的选择。

  • 编译

    • 将翻译单元转换为相应的汇编语言表示

    • 可能涉及到编译优化。编译优化的好处:提升执行速度,但不利于调试;反之,利于调试,但执行速度变慢。开发过程中会使用到Debug编译(引入优化较少),开发结束后会使用release编译(引入优化较多)重新进行编译。

      举例:

      int main()
      {int res = 0;for (int i = 0; i < 1000; ++i){res += i;}return res;
      }
      

      O0编译后结果为:

      main:push    rbpmov     rbp, rspmov     DWORD PTR [rbp-4], 0mov     DWORD PTR [rbp-8], 0
      .L3:cmp     DWORD PTR [rbp-8], 999jg      .L2mov     eax, DWORD PTR [rbp-8]add     DWORD PTR [rbp-4], eaxadd     DWORD PTR [rbp-8], 1jmp     .L3
      .L2:mov     eax, DWORD PTR [rbp-4]pop     rbpret
      

      O1编译优化结果为:

      main:mov     eax, 1000
      .L2:sub     eax, 1jne     .L2mov     eax, 499500ret
      

      O2编译优化结果为:

      main:mov     eax, 499500ret
      
    • 增量编译与全量编译

      • 全量编译

        全量编译,也称为完整编译,是指每次构建项目时,无论源代码文件是否发生变化,都重新编译所有源代码文件的过程。这种编译方式适用于:

        • 小型项目:当项目较小,源文件数量不多时,全量编译的开销相对较小。
        • 初始开发阶段:在项目开发的早期阶段,频繁的全量编译有助于发现潜在的问题。
        • 确保一致性:全量编译可以确保生成的可执行文件是完全一致的,没有遗漏任何源文件的更改。

        然而,全量编译的缺点是:

        • 时间消耗:对于大型项目,全量编译可能需要较长的时间,因为编译器需要处理大量的源文件。
        • 资源消耗:全量编译会占用更多的CPU和内存资源
      • 增量编译

        增量编译是一种更高效的编译策略,它只重新编译自上次编译以来已经更改过的源文件,以及依赖于这些更改的文件。增量编译适用于:

        • 大型项目:在大型项目中,增量编译可以显著减少编译时间。
        • 频繁的构建:当开发过程中需要频繁构建时,增量编译可以提高开发效率。
        • 持续集成(CI):在持续集成环境中,增量编译可以快速地提供反馈。

        增量编译的优点包括:

        • 节省时间:只编译更改的部分,从而缩短构建时间。
        • 资源优化:减少对系统资源的需求。

        但是,增量编译也有其局限性:

        • 复杂性:需要编译器支持增量编译功能,并且可能需要额外的配置。
        • 依赖关系:如果项目的依赖关系复杂,增量编译可能需要更多的时间来确定哪些文件需要重新编译。
        • 潜在问题:有时候,一些间接依赖 或全局状态的改变可能不会被增量编译检测到,导致构建的可执行文件不是最新的。
  • 汇编

    汇编阶段是将编译器生成的中间代码(通常是汇编语言)转换成可执行机器代码的过程。

  • 链接

    • 合并多个目标文件,关联声明与定义
    • 连接( Linkage )种类:内部连接、外部连接、无连接
    • 链接常见错误:找不到定义

注意:

C++ 源程序转换成可执行文件是相对复杂的过程,主要包含预处理、编译、链接等阶段,每一阶段都可能引入错误。

  • C++ 的编译 / 链接过程是复杂的,预处理、编译与链接都可能出错
  • 编译可能产生警告、错误,都要重视

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

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

相关文章

HCIP【BGP综合实验】

目录 一、实验拓扑图&#xff1a; 二、实验要求&#xff1a; 三、实验思路&#xff1a; 四、实验步骤&#xff1a; 1、进行网段的子网划分&#xff08;整个实验总共有19条网段&#xff09;&#xff1a; (1)首先&#xff0c;根据实验要求&#xff0c;将172.16.0.0/16全部划…

2024湖南理工学院程序设计竞赛(同步赛) G. 区间递减(思维题 分类讨论 ST表)

题目 https://ac.nowcoder.com/acm/contest/82672/G 思路来源 出题人 涼風青葉7代码 题解 注意到三种情况即可&#xff0c; 第一种情况&#xff0c;10 9 8 1 2&#xff0c;保留1 第二种情况&#xff0c;6 5 10 9 4 4&#xff0c;保留5 4 4 第三种情况&#xff0c;6 5 4&…

jdk8的新特征

1&#xff1a; jdk8中新增的方法 在jdk8中对接口进行了增强&#xff0c;在jdk8之前 interface 接口名{ 静态常量&#xff1a; 抽象方法&#xff1a; } 在jdk8之后 interface 接口名{ 静态常量&#xff1a; 抽象方法&#xff1a; 默认方法&#xff1a; 静态方法&#xff1a; } 2…

JAVA基础--IO

IO 什么是IO 任何事物提到分类都必须有一个分类的标准&#xff0c;例如人&#xff0c;按照肤色可分为&#xff1a;黄的&#xff0c;白的&#xff0c;黑的&#xff1b;按照性别可分为&#xff1a;男&#xff0c;女&#xff0c;人妖。IO流的常见分类标准是按照*流动方向*和*操作…

Google与哈佛大学的科学家团队共同创造了一张人脑中一个极小部分的精细地图

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

插件:Best HTTP

一、简介 WebSocket WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直接可以创建持久性的连接&#xff0c;并进行双向数据传输。…

【SRC实战】无法支付的修改金额支付漏洞

挖个洞先 https://mp.weixin.qq.com/s/F4f8R4uKN0Q9BnTmjDMleg “ 以下漏洞均为实验靶场&#xff0c;如有雷同&#xff0c;纯属巧合 ” 01 — 漏洞证明 一、企业用户&#xff0c;标准商品 “ 支付订单需要公对公银行卡转账&#xff0c;如何绕过&#xff1f;” 1、点击任意…

java入门-面向对象的三大特性

面向对象三大特性 封装 什么是封装 封装 是将代码及其处理的数据绑定在一起的一种编程机制&#xff0c;该机制保证了程序和数据都不受外部干扰且不被误用。 封装的作用 访问控制符 方法传参-值传递 传参类型是基本类型 程序案例&#xff1a; public static void main(St…

C++笔记(体系结构与内核分析)

1.OOP面向对象编程 vs. GP泛型编程 OOP将data和method放在一起&#xff0c;目的是通过封装、继承、多态提高软件的可维护性和可扩展性GP将data和method分开&#xff0c;可以将任何容器与任何算法结合使用&#xff0c;只要容器满足塞饭所需的迭代器类型 2.算法与仿函数的区别 …

AJAX前端与后端交互技术知识点以及案例

Promise promise对象用于表示一个异步操作的最终完成&#xff08;或失败&#xff09;及其结果值 好处&#xff1a; 逻辑更清晰了解axios函数内部运作机制成功和失败状态&#xff0c;可以关联对应处理程序能解决回调函数地狱问题 /*** 目标&#xff1a;使用Promise管理异步任…

Linux-02

Linux常用命令&#xff1a; ls: 列出目录touch: 创建文件 touch test.txt echo:往文件写内容echo "i love linux" >>test.txtcd&#xff1a;切换目录pwd&#xff1a;显示目前的目录mkdir&#xff1a;创建一个新的目录 mkdir dai:创建目录dai mkdir -p test1/t…

基于springboot的物业服务平台的设计与实现

基于springboot的物业服务平台的设计与实现 摘 要:本文针对社区物业服务管理现状,采用B/S系统架构并选择MySQL数据库作为系统的数据存储系统,设计并实现一个以Spring Boot为后端框架、Vue为前端框架的社区物业服务管理平台。与传统的物业服务管理方式相比,该系统取代了传统…

如何查看打包后的jar包启动方法main方法

背景 有时候我们在引用一个jar包的时候,想查看一个jar包的结构,这时候查看启动类就比较重要,因为一些关键配置是在启动类上的,这里教大家如何查看这个启动类(springboot项目) 步骤 首先打开jar包预览结构,可以使用解压缩工具直接双击打开或者预览结构 打开路径 META-INF/MA…

springfox.documentation.spi.DocumentationType没有OAS_30(从swagger2转到swagger3出现的问题)

直接开讲&#xff1a; 查看源码根本没有OAS_30的类型选择 右键package的springfox找到maven下载的包&#xff0c;打开到资源管理器 可以看到项目优先使用2版本的jar包&#xff0c;但是OAS_30只在3版本中才有&#xff0c;意思就是让项目优先使用以下图片中的3.0.0jar包 解决办法…

[AutoSar]BSW_Diagnostic_004 ReadDataByIdentifier(0x22)的配置和实现

目录 关键词平台说明背景一、配置DcmDspDataInfos二、配置DcmDspDatas三、创建DcmDspDidInfos四、创建DcmDspDids五、总览六、创建一个ASWC七、mapping DCM port八、打开davinci developer&#xff0c;创建runnabl九、生成代码 关键词 嵌入式、C语言、autosar、OS、BSW、UDS、…

课堂练习——路由策略

需求&#xff1a;将1.1.1.0/24网段重发布到网络中&#xff0c;不允许出现次优路径&#xff0c;实现全网可达。 在R1上重发布1.1.1.0/24网段&#xff0c;但是需要过滤192.168.12.0/24和192.168.13.0/24在R2和R3上执行双向重发布 因为R1引入的域外路由信息的优先级为150&#xff…

8.微服务项目结合SpringSecurity项目结构

项目结构 acl_parent:创建父工程用来管理依赖版本 common service_base&#xff1a;工具类 spring_security: Spring Security相关配置 infrastructure api_gateway: 网关 service service_acl: 实现权限管理功能代码 acl_parent的pom.xml <?xml version"1.0" …

STM32 | STC-USB驱动安装Windows 10(64 位)

Windows 10&#xff08;64 位&#xff09;安装方法 由于 Windows10 64 位操作系统在默认状态下&#xff0c;对于没有数字签名的驱动程序是不能安装成功的。所以在安装 STC-USB 驱动前&#xff0c;需要按照如下步骤&#xff0c;暂时跳过数字签名&#xff0c;即可顺利安装成功。…

镜像制作过程

镜像制作过程 Centos镜像制作 虚拟机系统安装将网卡转换为eth0在install安装时按tab健加入一下配置 net.ifnames=0 biosdevname=0

XYCTF - web

目录 warm up ezMake ezhttp ezmd5 牢牢记住&#xff0c;逝者为大 ezPOP 我是一个复读机 ezSerialize 第一关 第二关 第三关 第一种方法&#xff1a; 第二种方法&#xff1a; ez?Make 方法一&#xff1a;利用反弹shell 方法二&#xff1a;通过进制编码绕过 ε…