Ada Tutorial(1):Ada基础——wordcount程序

news2024/11/18 3:44:48

文章目录

  • Ada 常用的库和方法
    • Ada.Characters.Handling
      • 字符类型函数
      • 转换函数
  • Ada 基础语法概览
    • 数据类型和子类型
      • 类型(Type)
      • 子类型(Subtype)
      • 类型和子类型的区别
      • 常用类型转换方法
        • 显示类型转换
        • 类型相关函数
    • 循环语句
      • 无条件循环 (Loop)
      • For 循环
      • while 循环
      • 循环中的其它控制结构
    • 分支语句
      • if
      • case
    • 数组
      • 数组定义
      • 声明数组变量
      • 访问数组元素
      • 数组的其他特性
    • record
      • record 定义
      • 创建和使用 Record 变量
      • Record 的其他特性
        • Variant record
        • Nested record
    • 子程序
      • 过程 procedure
      • 函数
      • 参数传递
  • Tutorial 1

Ada 常用的库和方法

Ada.Text_IO: 这个库提供了用于标准输入输出的一系列函数,包括处理数字的函数。例如,Get 和 Put 可以用来读取和输出整数或浮点数。
Ada.Integer_Text_IO: 这个库提供了更具体的用于处理整数的输入输出函数。
Ada.Float_Text_IO: 这个库提供了更具体的用于处理浮点数的输入输出函数。
Ada.Numerics: 这个库包含了一系列用于数值计算的函数和过程,包括一些数学函数如平方根、指数、对数等。
Ada.Numerics.Float_Random: 这个库提供了一个伪随机数生成器,可以生成浮点数的随机数。

Ada.Characters.Handling

在这里插入图片描述

字符类型函数

字符分类函数:

Is_Control(Item : in Character) return Boolean: 判断给定字符是否是控制字符。控制字符的位置在范围0…31或127…159之内。
Is_Graphic(Item : in Character) return Boolean: 判断给定字符是否是图形字符。图形字符的位置在范围32…126或160…255之内。
Is_Letter(Item : in Character) return Boolean: 判断给定字符是否是字母。字母字符的位置在’A’…‘Z’或’a’…‘z’的范围内,或者在192…214、216…246或248…255的范围内。
Is_Lower(Item : in Character) return Boolean: 判断给定字符是否是小写字母。小写字母字符在’a’…‘z’的范围内,或者在223…246或248…255的范围内。
Is_Upper(Item : in Character) return Boolean: 判断给定字符是否是大写字母。大写字母字符在’A’…‘Z’的范围内,或者在192…214或216… 222的范围内。
Is_Basic(Item : in Character) return Boolean: 判断给定字符是否是基本字母。基本字母字符在’A’…‘Z’和’a’…‘z’的范围内,或者是以下几个特殊字符:‘Æ’, ‘æ’, ‘Ð’, ‘ð’, ‘Þ’, ‘þ’, 或 ‘ß’。
Is_Digit(Item : in Character) return Boolean: 判断给定字符是否是十进制数字。十进制数字字符在’0’…‘9’的范围内。
Is_Decimal_Digit(Item : in Character) return Boolean: 这个函数是Is_Digit的别名。
Is_Hexadecimal_Digit(Item : in Character) return Boolean: 判断给定字符是否是十六进制数字。十六进制数字字符在’0’…‘9’,‘A’ … ‘F’或’a’ … 'f’的范围内。
Is_Alphanumeric(Item : in Character) return Boolean: 判断给定字符是否是字母或数字。
Is_Special(Item : in Character) return Boolean: 判断给定字符是否是特殊图形字符。特殊图形字符是不是字母或数字的图形字符。

  • Is_space(Item: Character) 判断是否为空格

转换函数

To_Lower(Item : in Character) return CharacterTo_Lower(Item : in String) return String: 转换给定字符或字符串为小写。
To_Upper(Item : in Character) return CharacterTo_Upper(Item : in String) return String: 转换给定字符或字符串为大写。
To_Basic(Item : in Character) return CharacterTo_Basic(Item : in String) return String: 如果给定字符或字符串中的字符是带有重音符号的字母,则将其转换为无重音符号的字母;

Ada 基础语法概览

  • 可以参考 https://www.w3cschool.cn/ada/ada-shujuleixing.html

数据类型和子类型

在 Ada 中,类型(Type)和子类型(Subtype)是其类型系统的核心概念。

类型(Type)

在 Ada 中,类型定义了一组值和这些值上的一些操作。有许多内置类型,如整数类型 Integer,实数类型 Float,字符类型 Character,布尔类型 Boolean 等。此外,你可以定义自己的类型。类型定义可以是标量的(比如数字或枚举值),也可以是复合的(比如数组或记录)。

例如,以下是一些类型定义的示例:

type My_Integer is range 1 .. 100;  -- 一个自定义的整数类型,值域是 1100
type Day is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday);  -- 一个枚举类型
type Matrix is array (1 .. 10, 1 .. 10) of Float;  -- 一个二维数组类型

子类型(Subtype)

子类型是某个类型的一个子集,可以通过约束来定义。约束可以是范围约束,也可以是判别约束(对于某些高级类型)。 每个类型都有一个对应的匿名子类型,这个子类型没有任何额外的约束。

**子类型的一个重要用途是提供额外的约束,以防止程序中出现不应该有的值。**例如:

subtype Positive is Integer range 1 .. Integer'Last;  -- 一个表示正整数的子类型

在这个例子中,PositiveInteger 的一个子类型,它的值必须在 1Integer'Last 之间。如果你试图给 Positive 赋一个负值或零,编译器会产生一个错误。

注意,虽然子类型提供了额外的约束,但是它并不是一个新的类型。 也就是说,你可以直接使用原类型的操作,不需要进行显式的类型转换。

类型和子类型的区别

最重要的区别是,类型定义了新的数据,而子类型只是原类型的一部分。 当你定义一个新的类型时,Ada 会提供默认的操作(比如赋值和比较),但是你不能直接使用原类型的操作。 另一方面,子类型可以直接使用原类型的所有操作,但是它提供了额外的约束,以限制可接受的值。

常用类型转换方法

在 Ada 中,类型转换通常是通过 “显式类型转换” 或者通过 “类型相关的函数” 来实现的。值得注意的是,Ada 的类型系统是强类型的,这意味着编译器通常不会自动将一个类型的值转换为另一个类型的值,你必须显式地进行转换。

以下是一些常见的类型转换方法:

显示类型转换

类型名(表达式)

例如:

declare
   A : Integer := 42;
   B : Float;
begin
   B := Float(A);
end;

类型相关函数

有些类型提供了函数来进行类型转换。例如,你可以使用 Integer'Value 函数将字符串转换为整数:

declare
   S : String := "42";
   I : Integer;
begin
   I := Integer'Value(S);
end;

同样地,你可以使用 Float'ValueBoolean'Value 等函数来将字符串转换为其他类型。

这只是类型转换的基本方法。更复杂的类型转换可能需要使用到其他的技术,例如使用子程序或者运算符重载。

循环语句

在 Ada 编程语言中,有几种类型的循环语句,下面我将以 Markdown 格式列举和解释每一种:

无条件循环 (Loop)

无条件循环将重复执行循环体,直到显式的退出条件被满足。这通常通过 exit 语句来实现。

loop
   -- 循环体
   exit when 条件;
end loop;

For 循环

for 循环用于遍历一定范围内的数值或者迭代器的所有元素。在 Ada 中,for 循环的循环变量是不可变的, 也就是说你不能在循环体中修改它的值。

-- 数值范围
for I in 1 .. 10 loop
   -- 循环体
end loop;

-- 迭代器
for Element of Some_Array loop
   -- 循环体
end loop;

while 循环

while 循环在满足特定条件时执行循环体。如果条件在一开始就不满足,那么循环体可能一次都不会执行。

while 条件 loop
   -- 循环体
end loop;

循环中的其它控制结构

Ada 还提供了一些其它的循环控制结构:

exit:用于退出当前循环。
exit when:当满足特定条件时退出当前循环。
next:跳过当前循环迭代,进入下一次迭代。
next when:当满足特定条件时跳过当前循环迭代,进入下一次迭代。
return: 从包含当前循环的过程或函数中返回。

分支语句

if

if 条件 then
   -- 条件为真时执行的语句
end if;

if 语句可以包含一个或者多个 elsif 部分,还可以包含一个 else 部分:

if 条件1 then
   -- 条件1为真时执行的语句
elsif 条件2 then
   -- 条件1为假,但是条件2为真时执行的语句
else
   -- 所有条件都为假时执行的语句
end if;

case

case 表达式 is
   when1 =>
      -- 表达式的值为值1时执行的语句
   when2 =>
      -- 表达式的值为值2时执行的语句
   when others =>
      -- 表达式的值不是任何给定值时执行的语句
end case;
  • case 语句可以处理的值必须是离散的,例如整数或者枚举类型。
  • when others 部分是可选的,但是如果没有它,那么 case 语句必须能够处理表达式所有可能的值。
    case 语句中,when 部分的值不能重复,也就是说不能有两个 when 部分处理相同的值。

数组

在 Ada 中,数组是一种复合数据类型,用于存储相同类型的数据项。数组由元素索引组成。元素是数组中的数据项,每个元素都有一个与之关联的索引,用于唯一标识这个元素。

数组定义

在 Ada 中,你可以通过以下语法定义一个数组类型:

type Array_Type is array (Index_Type range <>) of Element_Type;
  • 更具体一点:例如,以下代码定义了一个整数数组,其索引类型是 Integer
-- 括号中的 Integer 的意思是索引类型, of Integer 代表数据类型是 integer
type Integer_Array is array (Integer range <>) of Integer;

还可以定义多维数组。例如,以下代码定义了一个二维的整数数组:

type Matrix is array (Integer range <>, Integer range <>) of Integer;

声明数组变量

一旦你定义了数组类型,你就可以声明数组变量了。例如:

declare
   A : Integer_Array(1 .. 10);
   M : Matrix(1 .. 10, 1 .. 10);
begin
   -- 这里可以使用数组 A 和 M
end;

在这个例子中,A 是一个包含 10 个元素的一维数组,M 是一个包含 100 个元素的二维数组。

访问数组元素

可以通过索引来访问数组的元素。例如:

declare
   A : Integer_Array(1 .. 10);
begin
   A(1) := 42;  -- 设置数组的第一个元素
   Put(A(1));  -- 输出数组的第一个元素
end;

对于多维数组,你需要提供多个索引。例如:

declare
   M : Matrix(1 .. 10, 1 .. 10);
begin
   M(1, 1) := 42;  -- 设置数组的第一个元素
   Put(M(1, 1));  -- 输出数组的第一个元素
end;

数组的其他特性

Ada 还提供了一些其他的数组特性,例如 数组切片、数组的赋值、数组的比较等。以下是一些例子:

  • 数组切片:可以使用数组切片来访问数组的一部分。例如:A(1 .. 5) 是数组 A 的前五个元素。
  • 数组的赋值:你可以一次性赋值给整个数组。例如:A := B 将数组 B 的所有元素赋值给 A。注意,A 和 B 必须是相同的类型。
  • 数组的比较:你可以使用 =/= 运算符来比较两个数组是否相等。例如:如果 A = B 则表示 A 和 B 的所有元素都相等。

record

record 定义

在 Ada 编程语言中,record 是一种复合数据类型,它允许将不同类型的数据元素组合成一个单一的数据结构。这类似于 C 或 C++ 中的结构体(struct),或者 Python 中的类(class)。
Record 类型是由一组字段定义的,每个字段都有一个名称和一个类型。Record 类型的定义语法如下:

type Record_Type is record
   Field1 : Type1;
   Field2 : Type2;
   -- 更多的字段...
end record;

例如,以下代码定义了一个名为 Person 的 record 类型,它有三个字段:Name、AgeIs_Employed

type Person is record
   Name        : String;
   Age         : Integer;
   Is_Employed : Boolean;
end record;

创建和使用 Record 变量

定义了 Record 类型后,你可以创建此类型的变量,并使用 . 运算符访问其字段。例如:

declare
   P : Person;
begin
   P.Name := "Alice";
   P.Age := 30;
   P.Is_Employed := True;
   
   Put("Name: " & P.Name);
   Put("Age: " & Integer'Image(P.Age));
   Put("Is employed: " & Boolean'Image(P.Is_Employed));
end;

在这个例子中,我们创建了一个 Person 类型的变量 P,并设置了它的各个字段的值。

Record 的其他特性

Record 还有一些其他的特性,例如 variant recordnested record

Variant record

Variant record 允许 record 中的一部分字段在不同的情况下具有不同的类型和数量。这类似于 C 或 C++ 中的联合体(union)。

Nested record

Nested record:一个 record 可以包含另一个 record,这被称为 nested record。这允许你构建更复杂的数据结构。

子程序

过程 procedure

过程是一个子程序,它被用来执行一些操作,但不返回值。 过程的定义语法如下:

procedure Procedure_Name (Parameter_List) is
begin
   -- 过程体
end Procedure_Name;

其中,Procedure_Name 是过程的名称,Parameter_List 是过程的参数列表,-- 过程体 是过程的主体,其中包含了要执行的代码。

例如,以下代码定义了一个名为 Print_Hello 的过程,该过程打印一条消息:

procedure Print_Hello is
begin
   Put_Line("Hello, world!");
end Print_Hello;

函数

函数是一个子程序,它执行一些操作,并返回一个值。 函数的定义语法如下:

function Function_Name (Parameter_List) return Return_Type is
begin
   -- 函数体
   return Result;
end Function_Name;

其中,Function_Name 是函数的名称,Parameter_List 是函数的参数列表,Return_Type 是函数返回值的类型,-- 函数体 是函数的主体,其中包含了要执行的代码,Result 是要返回的结果。

例如,以下代码定义了一个名为 Add 的函数,该函数接受两个整数参数,并返回它们的和:

function Add (X, Y : Integer) return Integer is
begin
   return X + Y;
end Add;

参数传递

参数传递
Ada 支持三种类型的参数传递:in、outin out

  • In:这是默认的参数类型,表示参数只能在子程序中被读取,不能被修改。

  • Out:这种类型的参数在子程序调用之前不需要初始化,它们在子程序中被赋值,并在子程序结束后返回给调用者。

  • In Out:这种类型的参数既可以在子程序中被读取,也可以被修改。在子程序结束后,修改后的值被返回给调用者。

以上就是 Ada 中子程序的一些基本知识。Ada 的子程序还有许多其他特性和细节没有在这里介绍,例如默认参数、子程序重载、子程序指针等等。

Tutorial 1

题目:Overview The WordCount program accepts a string from the standard input and delivers a count of words in the input string.
The following is a list of requirements:

  1. The program should accept a string characters on the standard input and count the number of words in the
    input.
  2. The input is terminated by a ‘#’ character.
  3. Words are separated by white spaces. To simplify the task, assume that white spaces are the space character (i.e. ignore tabs and new line characters).
  4. For the purposes of this workshop, a character that is not a whitespace character.
  5. The output is a single integer displaying the word count.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Characters.Handling; use Ada.Characters.Handling;

procedure Word_Count is
   Input   : Character;
   Word_Cnt: Integer := 0;
   In_Word : Boolean := False;
   
begin
   loop
      Get(Item => Input);
      exit when Input = '#';

      if Is_Space(Input) then
         if In_Word then
            Word_Cnt := Word_Cnt + 1;
         end if;
         In_Word := False;
      else
         In_Word := True;
      end if;
   end loop;


   if In_Word then
      Word_Cnt := Word_Cnt + 1;
   end if;

   Put_Line("Word count: " & Integer'Image(Word_Cnt));
end Word_Count;

题目:Implement the word counting program specified in the Specification section, and run a few tests to convince yourself that the program works on most inputs.
Tip: it is of course a good idea to implement your program incrementally. Start by writing and running a small program that extends the program given.
Note the following in the skeleton provided. ProtectedStack is importaed by adding the following:在这里插入图片描述

  • 这个题目是老师给出的解答,包括的操作有:
    • 定义了一个 ProtectedStack package(包括 adb 和 ads 文件)
    • solution 中构建了主逻辑
  • 这个题目中涉及了使用 generic 类型的数据,在使用的时候需要先进行实例化 is new
  • 其实 StringStack 这个我们实例化的 package 和之前的 ProtectedStack 功能一样,只不过是它的实例而已
-- protectedStack.adb

package body ProtectedStack is
   
   protected body Stack is 
      
      entry Push(I: in Item)
      when True is
      begin
	 if Stk.Size < Max_Size then
	    Stk.Size := Stk.Size + 1;
	    Stk.Data(Stk.Size) := I;
	 else
	    raise Stack_Overflow;
	 end if;
      end Push;

      entry Pop(I: out Item) 
      when True is
      begin
	 if Stk.Size > 0 then
	    I := Stk.Data(Stk.Size);
	    Stk.Size := Stk.Size - 1;
	 else
	    raise Stack_Underflow;
	 end if;
      end Pop;

      entry Top(I: out Item)
      when True is
      begin
	 if Stk.Size > 0 then
	    I := Stk.Data(Stk.Size);
	 else
	    raise Stack_Underflow;
	 end if;
      end Top;

      entry Empty(EmptyStack: out Boolean) 
      when True is
      begin
	 EmptyStack := (Stk.Size = 0);
      end Empty;

      entry Full(FullStack: out Boolean) 
      when True is
      begin
	 FullStack := (Stk.Size = Max_Size);
      end Full;

      entry Clean
      when True is
      begin
	 Stk.Size := 0;
      end Clean;
      
   end Stack;
   
end ProtectedStack;
--protectedstack.ads

generic
   Max_Size: Positive;          -- The maximum size of the stack.
   type Item is private;        -- The type of items in the stack. The type must
                                -- be definite, and the private means that this
                                -- package may not examine its internals.
package ProtectedStack is
   
   type StackType is private;

   -- Exceptions.
   Stack_Underflow, Stack_Overflow: exception;
   
   -- The public interface to the stack consists of the following
   --  operations. The stack is "protected" which means that the tasks
   --  have muitually exclusive access to the stack operations. They
   --  are declared just like the "entry" points in a task type
   --  declaration and are implemented using "entry" keywords as
   --  well. Entry calls are the main means of communication between
   --  concurrent tasks in Ada so this is effectively an Abstract Data
   --  Type that protects the Stack by enforcing mutually exlcusive
   --  access.
   
   protected type Stack is
      entry Push(I: in Item); 
      entry Pop(I: out Item);
      entry Top(I: out Item); 
      entry Empty(EmptyStack: out Boolean); 
      entry Full(FullStack: out Boolean);
      entry Clean; 
   private 
      Stk : StackType;
   end Stack;
   
private
   
   type StackData is array(1.. Max_Size) of Item;
   type StackType is record
      Size: Integer range 0 .. Max_Size := 0;
      Data: StackData;
   end record;
      
end ProtectedStack;

-- solution
with Ada.Text_IO; 
use  Ada.Text_IO;

with Ada.Integer_Text_IO;
use  Ada.Integer_Text_IO;

with ProtectedStack;
with Ada.Strings.Unbounded;

with Ada.Characters.Latin_1;

-- The WordCount program counts the number of characters and words in
--  a string received from standard input. A word is any alphanum
--  character separated by a space or tab
procedure WordCount is
   
   package ASU renames Ada.Strings.Unbounded;
   use ASU;   
   package StringStack is new ProtectedStack(100, ASU.Unbounded_String);
   
   Ch        : Character;            -- the current character
   Word      : ASU.Unbounded_String; -- the current word
   
   -- The number of characters and words
   NumChars : Integer := 0;
   NumWords : Integer := 0;
   
   -- a stack for putting words into
   St : StringStack.Stack;
   
   -- for testing is the stack is empty
   IsEmpty : Boolean;
   
begin
   
   Get(Ch);
   
   Word := ASU.To_Unbounded_String("");
   
   while (Ch /= '#') loop
      
      NumChars := NumChars + 1;
      
      -- if a space or tab, we encounter a new word
      if Ch = ' ' or Ch = Ada.Characters.Latin_1.HT then	 
	 
	 -- consume remaining spaces and tabs
	 while Ch = ' ' or Ch = Ada.Characters.Latin_1.HT loop
	    Get(Ch);
	 end loop;
	 
	 NumWords := NumWords + 1;
	 St.Push(Word);
	 Word := ASU.To_Unbounded_String("");
	 
      else
	 Word := Word & Ch;
	 Get(Ch);
      end if;
      
   end loop;
   
   -- push the terminating word
   NumWords := NumWords + 1;
   St.Push(Word);

   Put(NumWords); New_Line;
   Put(NumChars); New_Line;
   
   -- print the words on the stack
   St.Empty(IsEmpty);
   while not IsEmpty loop
      St.Pop(Word);
      Put(ASU.To_String(Word) & " ");
      St.Empty(IsEmpty);
   end loop;
end WordCount;

  • 注意事项:
    在这里插入图片描述

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

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

相关文章

探索智慧档案的发展路径,开源网安受邀参加国际档案日专题讲座

近日&#xff0c;深圳市档案学会举办了“奋进新征程&#xff0c;兰台谱新篇”2023年国际档案日专题讲座。开源网安常务副总经理王颉博士受邀参加此次讲座&#xff0c;分享了《档案信息安全实务&#xff1a;时代与展望》&#xff0c;从软件供应链安全的维度为到场人员讲解了数字…

Vue3 ElementPlus Dialog封装 (一:使用props emit)

引言 多个页面中需要录入用户数据&#xff08;弹窗内容相同&#xff09;&#xff0c;重复写弹窗代码比较繁琐。因此封装一下组件&#xff0c;使用效果如下&#xff1a; 本例中模型较简单&#xff0c;记录下使用方法和原理 实现原理 参考VUE官方两个例子&#xff0c;基本父子件…

调试CAN过滤器功能使用笔记

一.关于CAN过滤器的配置及使用 提示&#xff1a;此处使用的是雅特力的芯片&#xff08;基本兼容stm32的芯片&#xff09; 这里只讲32位宽的过滤器&#xff0c;16位的用法基本相同&#xff0c;注意因为位数减少数据不一样。 1.1首先过滤器有两种工作模式&#xff1a; 1.标识符…

Rust每日一练(Leetday0025) 矩阵置零、搜索二维矩阵、颜色分类

目录 73. 矩阵置零 Set Matrix Zeroes &#x1f31f;&#x1f31f; 74. 搜索二维矩阵 Search A 2d-Matrix &#x1f31f;&#x1f31f; 75. 颜色分类 Sort Colors &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang…

逻辑回归与决策树回归

逻辑回归 逻辑回归函数: 逻辑回归分析属于概率型回归分析方法。 假设在自变量xi1、xi2…xip的作用下&#xff0c;因变量y取值为1和0的二值变量&#xff0c;其取值为1的概率为pi&#xff0c;则可以表示为&#xff1a; 相反&#xff0c;y取值为0的概率即&#xff1a; 对y取值为…

FlinkSql 使用总结

一、FlinkSQL底层实现理解 FlinkSQL在flink Framework的位置 Flink Table & SQL API是在DataStream和DataSet之上封装的一层高级API。由于DataStream和DataSet有各自的API&#xff0c;开发起来又有些困难&#xff0c;如果只是应对一些相对通用的需求会有点麻烦。而Flink T…

【AUTOSAR】UDS协议的代码分析与解读(一)----测试UDS协议DID的填写与读取

测试环境配置 Environment-1: Trace32配置&#xff08;内核选择&#xff09; Environment-2: Dgs上位机配置&#xff08;报文发送&#xff09; AV012 Dgs密码 &#xff1a;hsae_dgs 配置请求ID和响应ID可以去代码中查看&#xff0c;备注型号和设备类别&#xff0c;选择售后烧…

一款集成了多种老牌工具字典的轻量级目录扫描器

功能 dirxk&#xff0c;一款集成了多种老牌工具字典的轻量级目录扫描器&#xff0c;包括御剑后台扫描字典&#xff0c;test404网站备份&#xff0c;web破壳扫描器&#xff0c;御剑1.5扫描字典&#xff0c;御剑专业版字典&#xff0c;wwwscan字典&#xff0c;dirscan字典&#…

ceph块存储使用总结

ceph块存储使用总结 大纲 ceph osd pool池创建 & 更新osd pool关联应用删除ceph osd pool使用ceph块存储自动挂载扩容 本次测试相关环境与软件&#xff1a; ceph15.2.17 Octopuseph-deploy 2.0.1ubuntu18.04.6 ceph osd pool池 基础概念 Ceph 将数据存储在存储池中。…

Hive存储格式

hive的存储格式 hive的存储格式分为两大类&#xff1a;一类纯文本文件&#xff0c;一类是二进制文件存储。 第一类&#xff1a; 纯文本文件存储 textfile: 纯文本文件存储格式&#xff0c;不压缩&#xff0c;也是hive的默认存储格式&#xff0c;磁盘开销大&#xff0c;数据解…

3. 说说Java“锁“事

3.1 从轻松的乐观锁和悲观锁开讲 ● 悲观锁&#xff1a; 认为自己在使用数据的时候一定有别的线程来修改数据&#xff0c;因此在获取数据的时候会先加锁&#xff0c;确保数据不会被别的线程修改&#xff0c;synchronized和Lock的实现类都是悲观锁&#xff0c;适合写操作多的场…

WhaleHiking的“三山五岳”第一站:泰山

Datawhale团队 来源&#xff1a;whaleHiking 开场白 大家应该都听说过杜甫的《望岳》——“会当凌绝顶&#xff0c;一览众山小。”&#xff0c;每次看见这句诗的时候&#xff0c;总想去泰山看一看&#xff0c;感受诗中的壮美山河景色&#xff01; 机不可失时不再来&#xff0c…

JVM图解

JVM图解 一、JVM的运行时数据区 概览JVM运行时数据区主要包括以下几个部分&#xff1a;程序计数器、虚拟机栈、本地方法栈、方法区、堆&#xff1b;其中 栈是运行时的单位&#xff0c;而堆是存储的单位&#xff01; 1.程序计数器 程序计数器可以看作是当前线程所执行的字节码…

调用阿里API实现银行卡实名认证

调用阿里API实现银行卡实名认证 1&#xff0e;作者介绍2&#xff0e;算法介绍2.1 阿里云技术介绍2.2 API介绍 3&#xff0e;实验代码3.1 调用阿里云API流程3.2 代码实现3.2.1完整代码3.2.2实验结果 4&#xff0e;报错分析5&#xff0e;参考链接 1&#xff0e;作者介绍 薛维哥&…

针对潜在客户CRM如何进行管理?

CRM客户管理系统可以帮助企业管理客户&#xff0c;提高客户转化率&#xff0c;增加企业收入和利润。那么&#xff0c;在CRM中如何进行潜在客户管理呢&#xff1f;本文将从以下几个方面来为您解答。 一、什么是潜在客户&#xff1f; 潜在客户是指对企业的产品或服务有意向&…

驱动开发:内核遍历文件或目录

在笔者前一篇文章《驱动开发&#xff1a;内核文件读写系列函数》简单的介绍了内核中如何对文件进行基本的读写操作&#xff0c;本章我们将实现内核下遍历文件或目录这一功能&#xff0c;该功能的实现需要依赖于ZwQueryDirectoryFile这个内核API函数来实现&#xff0c;该函数可返…

docker的资源控制

一、CPU控制 cgroups&#xff0c;是一个非常强大的linux内核工具&#xff0c;他不仅可以限制被namespace隔离起来的资源, 还可以为资源设置权重、计算使用量、操控进程启停等等。所以cgroups (Control groups) 实现了对资源的配额和度量。 cgroups有四大功能: 资源限制:可以…

报表生成器FastReport .Net用户指南:“Picture“对象

FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案&#xff0c;使用FastReport .NET可以创建独立于应用程序的.NET报表&#xff0c;同时FastReport .Net支持中文、英语等14种语言&#xff0c;可以让你的产品保证真正的国际性。 FastReport.NET官方版…

【30天熟悉Go语言】6 Go 复杂数据类型之指针

文章目录 一、前言二、数据类型总览三、指针1、特殊运算符& *2、内存角度来看指针3、使用指针修改数据4、指针使用的注意事项5、对比着看Java的引用类型 三、总结 一、前言 Go系列文章&#xff1a; GO开篇&#xff1a;手握Java走进Golang的世界2 Go开发环境搭建、Hello Wor…

Zstack实习-基础知识总结归纳-待更新

什么是虚拟化&#xff1f; 虚拟化技术是一种将物理计算资源&#xff0c;如服务器、存储和网络等&#xff0c;转化成虚拟的逻辑资源的技术。通过虚拟化技术&#xff0c;可以将多个独立的操作系统运行在同一台物理计算机上&#xff0c;实现资源的共享&#xff0c;提高硬件的利用率…