JavaSE——泛型

目录

一、泛型的引入

二、泛型的好处

三、泛型介绍

四、泛型的语法

(一)泛型的声明

(二)泛型的实例化

五、泛型使用的注意事项和细节

六、泛型练习题1

七、自定义泛型

(一)自定义泛型类

(二)自定义泛型接口

(三)自定义泛型方法

八、泛型练习题2

九、泛型的继承和通配符


一、泛型的引入

使用传统的集合添加数据的时候,有以下几点弊端:

  1. 不能对加入到集合ArrayList中的数据类型进行约束(不安全)
  2. 遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响

二、泛型的好处

1.编译时,检查添加元素的类型,提高了安全性

2.减少了类型转换的次数,提高效率

  • 不使用泛型

Dog-加入->Object-取出->Dog        放入到ArrayList中会先转成Object,在取出时,还需要转换成Dog

  • 使用泛型

Dog->Dog->Dog        放入和取出时,不需要类型转换,提高效率

3.不再提示编译警告 

public class Generic01 {public static void main(String[] args) {// 做一个泛型约束ArrayList<Dog> arrayList = new ArrayList<Dog>();arrayList.add(new Dog("aa", 1));arrayList.add(new Dog("bb", 2));arrayList.add(new Dog("cc", 3));// 使用泛型遍历,不需要向下转型for (Dog dog : arrayList) {System.out.println(dog);}}
}class Dog {private String name;private int age;public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}

三、泛型介绍

泛型是一种表示数据类型的数据类型。

  1. 泛型又称参数化类型,是JDK5出现的新特性,解决数据类型的安全性问题
  2. 在类声明或实例化时只要指定好需要的具体的类型即可
  3. Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮
  4. 泛型的作业是:可以在类声明时通过一个标识,表示类中某个属性的类型,或者是方法的返回值的类型,或者是参数类型。
  5. 注意,特别强调: E具体的数据类型,在定义Person对象的时候指定,即在编译期间,就确定E是什么类型。
public class Generic03 {public static void main(String[] args) {Person<String> person = new Person<String>("韩顺平教育");person.show(); //String/*可以这样理解:上面的Person类class Person {String s ;// E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(String s) {//E也可以是参数类型this.s = s;}public String f() {//返回类型使用Ereturn s;}}*/Person<Integer> person2 = new Person<Integer>(100);person2.show();//Integer/*class Person {Integer s ;//E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(Integer s) {//E也可以是参数类型this.s = s;}public Integer f() {//返回类型使用Ereturn s;}}*/}
}// 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,
// 或者是某个方法的返回值的类型,或者是参数类型
class Person<E> {E s; // E表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型public Person(E s) { // E也可以是参数类型this.s = s;}public E f() {//返回类型使用Ereturn s;}public void show() {System.out.println(s.getClass()); // 显示s的运行类型}
}

四、泛型的语法

(一)泛型的声明

interface接口<T>{} 和 class类<K,V>{}        比如:List,ArrayList

说明:1)其中,T、K、V不代表值,而是表示类型

           2)任意字母都可以。常用T表示,是Type的缩写

(二)泛型的实例化

要在类名后面指定类型参数的值(类型)。如:

List<String> strList = new ArrayList<String>();
Iterator<Customer> iterator = customers.iterator();

        创建3个学生对象,放入到HashSet中使用,放入到HashMap中使用,要求Key是 String name,Value 就是学生对象,使用两种方式遍历。

代码实现:

@SuppressWarnings({"all"})
public class GenericExercise {public static void main(String[] args) {// 使用泛型方式给HashSet 放入3个学生对象HashSet<Student> students = new HashSet<Student>();students.add(new Student("jack", 18));students.add(new Student("tom", 28));students.add(new Student("mary", 19));// 增强for遍历for (Student student : students) {System.out.println(student);}System.out.println("--------------------------");// 使用泛型方式给HashMap 放入3个学生对象// K -> String V->StudentHashMap<String, Student> hm = new HashMap<String, Student>();/*public class HashMap<K,V>  {}*/hm.put("milan", new Student("milan", 38));hm.put("smith", new Student("smith", 48));hm.put("tom", new Student("tom", 28));// 迭代器遍历Set<Map.Entry<String, Student>> entrySet = hm.entrySet();Iterator<Map.Entry<String, Student>> iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry<String, Student> next = iterator.next();System.out.println(next.getKey() + "-" + next.getValue());}}
}class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}

五、泛型使用的注意事项和细节

  1. 泛型类型只能是引用数据类型,不可以设置基本数据类型
    List<Integer> list = new ArrayList<Integer>(); //OK
    // List<int> list2 = new ArrayList<int>();//错误
  2. 在指定泛型具体类型后,可以传入该类型或其子类类型
    Pig<A> aPig = new Pig<A>(new A());
    aPig.f();
    // class com.testdemo.generic.APig<A> aPig2 = new Pig<A>(new B());
    aPig2.f();
    // class com.testdemo.generic.Bclass A {}
    class B extends A {}class Pig<E> {E e;public Pig(E e) {this.e = e;}public void f() {System.out.println(e.getClass()); // 运行类型}
    }
  3. 泛型使用形式可以简化
    ArrayList<Integer> list3 = new ArrayList<>();
    List<Integer> list4 = new ArrayList<>();
    ArrayList<Pig> pigs = new ArrayList<>();
  4. 不写泛型默认是 Object类型

    ArrayList arrayList = new ArrayList();
    // 等价于 ArrayList<Object> arrayList = new ArrayList<Object>();

六、泛型练习题1

代码实现:

MyDate类:

public class MyDate implements Comparable<MyDate> {private int year;private int month;private int day;@Overridepublic String toString() {return "MyDate{" +"year=" + year +", month=" + month +", day=" + day +'}';}public int getYear() {return year;}public void setYear(int year) {this.year = year;}public int getMonth() {return month;}public void setMonth(int month) {this.month = month;}public int getDay() {return day;}public void setDay(int day) {this.day = day;}public MyDate(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}/*** 比较brithday* @param o the object to be compared.* @return*/@Overridepublic int compareTo(MyDate o) {// 比较生日int yearMinus = year - o.getYear();if (yearMinus != 0) {return yearMinus;}int monthMinus = month - o.getMonth();if (monthMinus != 0) {return monthMinus;}return day - o.getDay();}
}

Employee类:

public class Employee {private String name;private double sal;private MyDate birthday;@Overridepublic String toString() {return "Employee{" +"name='" + name + '\'' +", sal=" + sal +", birthday=" + birthday +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSal() {return sal;}public void setSal(double sal) {this.sal = sal;}public MyDate getBirthday() {return birthday;}public void setBirthday(MyDate birthday) {this.birthday = birthday;}public Employee(String name, double sal, MyDate birthday) {this.name = name;this.sal = sal;this.birthday = birthday;}
}

测试类:

public class GenericExercise02 {public static void main(String[] args) {ArrayList<Employee> employees = new ArrayList<>();Employee aa = new Employee("aa", 8000, new MyDate(1980, 2, 4));Employee bb = new Employee("张三", 9000, new MyDate(1999, 12, 24));Employee ccc = new Employee("张三", 5500, new MyDate(1999, 12, 18));employees.add(aa);employees.add(bb);employees.add(ccc);System.out.println("----------排序后:----------");for (Employee employee : employees) {System.out.println(employee);}// 排序employees.sort(new Comparator<Employee>() {@Overridepublic int compare(Employee o1, Employee o2) {if (!(o1 instanceof Employee && o2 instanceof Employee)) {System.out.println("类型不正确...");return 0;}// 比较nameint i = o1.getName().length() - o2.getName().length();if (i != 0) {return i;}return o1.getBirthday().compareTo(o2.getBirthday());}});System.out.println("----------排序后:----------");for (Employee employee : employees) {System.out.println(employee);}}
}

运行结果:

七、自定义泛型

(一)自定义泛型类

基本语法:

class 类名<T,R...>{ // ...表示多个成员
}

注意细节:

  1. 普通成员可以使用泛型 (属性、方法)

  2. 使用泛型的数组,不能初始化

  3. 静态方法中不能使用类的泛型

  4. 泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)

  5. 如果在创建对象时,没有指定类型,默认为Object

代码示例:

public class CustomGeneric_ {public static void main(String[] args) {// T=Double, R=String, M=IntegerTiger<Double, String, Integer> g = new Tiger<>("john");g.setT(10.9); // OK// g.setT("yy"); // 错误,类型不对System.out.println(g);// Tiger{name='john', r=null, m=null, t=10.9, ts=null}Tiger g2 = new Tiger("john~~"); // OK T=Object R=Object M=Objectg2.setT("yy"); // OK ,因为 T=Object "yy"=String 是Object子类System.out.println("g2=" + g2);// g2=Tiger{name='john~~', r=null, m=null, t=yy, ts=null}}
}// 1. Tiger 后面定义泛型,所以Tiger 就称为自定义泛型类
// 2. T, R, M 泛型的标识符, 一般是单个大写字母
// 3. 泛型标识符可以有多个
class Tiger<T, R, M> {String name;R r; // 属性使用到泛型M m;T t;// 因为数组在new 不能确定T的类型,就无法在内存开空间,不能new泛型数组T[] ts;public Tiger(String name) {this.name = name;}public Tiger(R r, M m, T t) { // 构造器使用泛型this.r = r;this.m = m;this.t = t;}public Tiger(String name, R r, M m, T t) { // 构造器使用泛型this.name = name;this.r = r;this.m = m;this.t = t;}// 因为静态是和类相关的,在类加载时,对象还没有创建// 所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
//    static R r2;
//    public static void m1(M m) {
//
//    }// 方法使用泛型public String getName() {return name;}public void setName(String name) {this.name = name;}public R getR() {return r;}public void setR(R r) { // 方法使用到泛型this.r = r;}public M getM() { // 返回类型可以使用泛型return m;}public void setM(M m) {this.m = m;}public T getT() {return t;}public void setT(T t) {this.t = t;}@Overridepublic String toString() {return "Tiger{" +"name='" + name + '\'' +", r=" + r +", m=" + m +", t=" + t +", ts=" + Arrays.toString(ts) +'}';}
}

(二)自定义泛型接口

基本语法:

interface 接口名<T,R...>{
}

注意细节:

  1. 接口中,静态成员也不能使用泛型(和泛型类规定相同)
  2. 泛型接口的类型,在继承接口或实现接口时确定
  3. 没有指定类型,默认为Object 

代码示例:

public class CustomInterfaceGeneric {public static void main(String[] args) {}
}
// 在继承接口 指定泛型接口的类型
interface IA extends IUsb<String, Double> {}// 当我们去实现IA接口时,因为IA在继承IUsu 接口时,指定了U 为String R为Double
// 在实现IUsu接口的方法时,使用String替换U, 是Double替换R
class AA implements IA {@Overridepublic Double get(String s) {return null;}@Overridepublic void hi(Double aDouble) {}@Overridepublic void run(Double r1, Double r2, String u1, String u2) {}
}// 实现接口时,直接指定泛型接口的类型
// 给U 指定Integer 给 R 指定了 Float
// 所以,当我们实现IUsb方法时,会使用Integer替换U, 使用Float替换R
class BB implements IUsb<Integer, Float> {@Overridepublic Float get(Integer integer) {return null;}@Overridepublic void hi(Float aFloat) {}@Overridepublic void run(Float r1, Float r2, Integer u1, Integer u2) {}
}// 没有指定类型,默认为Object,建议直接写成 IUsb<Object,Object>
class CC implements IUsb { // 等价于 class CC implements IUsb<Object,Object> {@Overridepublic Object get(Object o) {return null;}@Overridepublic void hi(Object o) {}@Overridepublic void run(Object r1, Object r2, Object u1, Object u2) {}
}interface IUsb<U, R> {int n = 10;// U name; 不能这样使用// 普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1, R r2, U u1, U u2);// 在jdk8 中,可以在接口中,使用默认方法, 也是可以使用泛型default R method(U u) {return null;}
}

(三)自定义泛型方法

基本语法:

修饰符 <T,R...> 返回类型 方法名(参数列表){
}

注意细节:

  1. 泛型方法,可以定义在普通类中,也可以定义在泛型类中
  2. 当泛型方法被调用时,类型会确定
  3. 修饰符后没有泛型,那么该方法就不是泛型方法,而是使用了泛型

代码示例:

public class CustomMethodGeneric {public static void main(String[] args) {Car car = new Car();car.fly("宝马", 100);// 当调用方法时,传入参数,编译器,就会确定类型// class java.lang.String// class java.lang.IntegerSystem.out.println("=======");car.fly(300, 100.1);// 当调用方法时,传入参数,编译器,就会确定类型// class java.lang.Integer// class java.lang.Double// 测试// T->String, R-> ArrayListFish<String, ArrayList> fish = new Fish<>();fish.hello(new ArrayList(), 11.3f);// class java.util.ArrayList// class java.lang.Float}
}// 泛型方法,可以定义在普通类中, 也可以定义在泛型类中
class Car { // 普通类//普通方法public void run() {}// 说明 泛型方法// 1. <T,R> 就是泛型// 2. 是提供给 fly使用的public <T, R> void fly(T t, R r) { // 泛型方法System.out.println(t.getClass()); // StringSystem.out.println(r.getClass()); // Integer}
}class Fish<T, R> { // 泛型类//普通方法public void run() {}//泛型方法public <U, M> void eat(U u, M m) {}// 说明:// 1. 下面hi方法不是泛型方法// 2. 是hi方法使用了类声明的 泛型public void hi(T t) {}// 泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型public <K> void hello(R r, K k) {System.out.println(r.getClass());//ArrayListSystem.out.println(k.getClass());//Float}
}

八、泛型练习题2

public class CustomMethodGenericExercise {public static void main(String[] args) {// T->String, R->Integer, M->DoubleApple<String, Integer, Double> apple = new Apple<>();apple.fly(10); // 10 会被自动装箱 Integer10, 输出Integerapple.fly(new Dog()); // Dog}
}class Apple<T, R, M> { // 自定义泛型类public <E> void fly(E e) {  // 泛型方法System.out.println(e.getClass().getSimpleName()); // 只显示类名:Integer}// public void eat(U u) {} // 错误,因为U没有声明public void run(M m) {} // ok
}
class Dog {}

九、泛型的继承和通配符

  1. 泛型不具备继承性
    // List<Object> list = new ArrayList<String>(); // 错误写法,编译报错
  2. <?>:支持任意类型泛型
  3. <? extends A>:支持A类以及A类的子类,规定了泛型的上限
  4. <? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

代码示例:

public class GenericExtends {public static void main(String[] args) {Object o = new String("xx");// 泛型没有继承性// List<Object> list = new ArrayList<String>();//举例说明下面三个方法的使用List<Object> list1 = new ArrayList<>();List<String> list2 = new ArrayList<>();List<AA> list3 = new ArrayList<>();List<BB> list4 = new ArrayList<>();List<CC> list5 = new ArrayList<>();//如果是 List<?> c ,可以接受任意的泛型类型printCollection1(list1);printCollection1(list2);printCollection1(list3);printCollection1(list4);printCollection1(list5);//List<? extends AA> c: 表示 上限,可以接受 AA或者AA子类
//        printCollection2(list1);//×
//        printCollection2(list2);//×printCollection2(list3);//√printCollection2(list4);//√printCollection2(list5);//√//List<? super AA> c: 支持AA类以及AA类的父类,不限于直接父类printCollection3(list1);//√//printCollection3(list2);//×printCollection3(list3);//√//printCollection3(list4);//×//printCollection3(list5);//×}// ? extends AA 表示 上限,可以接受 AA或者AA子类public static void printCollection2(List<? extends AA> c) {for (Object object : c) {System.out.println(object);}}// 说明: List<?> 表示 任意的泛型类型都可以接受public static void printCollection1(List<?> c) {for (Object object : c) { // 通配符,取出时,就是ObjectSystem.out.println(object);}}// ? super 子类类名AA:支持AA类以及AA类的父类,不限于直接父类,// 规定了泛型的下限public static void printCollection3(List<? super AA> c) {for (Object object : c) {System.out.println(object);}}
}class AA {}
class BB extends AA {}
class CC extends BB {}

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

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

相关文章

moe2024新生赛--pwn篇

moe2024新生赛–pwn篇 也算是复健吧。。 文章目录 moe2024新生赛--pwn篇**1 二进制漏洞审计入门指北**2 NotEnoughTime3 no_more_gets4 leak_sth5 ez_shellcode6 这是什么&#xff1f;libc7 这是什么&#xff1f;shellcode8 这是什么&#xff1f;random9 flag_helper10 这是什么…

PCB缺陷检测数据集 xml 可转yolo格式 ,共10688张图片

PCB缺陷检测数据集&#xff08;yolov5,v7,v8&#xff09; 数据集总共有两个文件夹&#xff0c;一个是pcb整体标注&#xff0c;一个是pcb部分截图。 整体标注有6个分类&#xff0c;开路&#xff0c;短路等都已经标注&#xff0c;标注格式为xml&#xff0c;每个文件夹下有100多张…

bp intruder 四种攻击类型 记录

1. Sniper 攻击&#xff08;狙击手模式&#xff09; 特点&#xff1a; Sniper 攻击是最基础的一种攻击类型&#xff0c;适用于单参数的简单测试。它会逐一替换每一个 payload 插入点&#xff0c;其他位置保持不变&#xff0c;从而测试单个参数对应用的影响。 工作流程&#…

Java-IO流使用场景

Java IO 流是Java编程中非常重要的组成部分,用于处理文件读写、网络通信等数据传输任务。 1. 字节流 1.1 读取文件 import java.io.FileInputStream; import java.io.IOException;public class ReadFileExample {public static void main(String[] args) {try (FileInputSt…

不用搭建服务?MemFire Cloud让开发更简单

不用搭建服务&#xff1f;MemFire Cloud让开发更简单 在当今的开发世界里&#xff0c;想要开发一个功能齐全的应用&#xff0c;往往意味着需要搭建复杂的后端、开发API接口、处理认证授权、管理数据库……这些琐碎的工作让很多开发者头疼不已&#xff0c;尤其是独立开发者或者…

成都睿明智科技有限公司电商服务可靠不?

在这个短视频风起云涌的时代&#xff0c;抖音不仅成为了人们娱乐消遣的首选平台&#xff0c;更是众多商家竞相追逐的电商新蓝海。成都睿明智科技有限公司&#xff0c;作为抖音电商服务领域的佼佼者&#xff0c;正以其独到的洞察力和专业的服务&#xff0c;助力无数品牌在这片沃…

【进阶OpenCV】 (16)-- 人脸识别 -- FisherFaces算法

文章目录 FisherFaces算法一、算法原理二、算法优势与局限三、算法实现1. 图像预处理2. 创建FisherFace人脸特征识别器3. 训练模型4. 测试图像 总结 FisherFaces算法 PCA方法是EigenFaces人脸识别的核心&#xff0c;但是其具有明显的缺点&#xff0c;在操作过程中会损失许多人…

程序员如何使用AI工具进行设计开发?

一、需求分析阶段 自然语言处理辅助理解需求&#xff1a; 使用自然语言处理工具&#xff0c;如 ChatGPT 等&#xff0c;将复杂的业务需求描述转化为更清晰的技术要求。例如&#xff0c;向 AI 解释项目的背景和目标&#xff0c;让它帮助梳理关键需求点和可能的技术挑战。通过与…

Docker下安装RabbitMQ

文章目录 Docker下安装RabbitMQ1. 下载Rabbitmq镜像2. 创建并运行RabbitMQ容器3. 查看启动情况4. 启动RabbitMQ访问的Web客户端4-1 方法一 进入容器开启4-2 方法二 直接开启5. 浏览器访问RabbitMQ的Web客户端页面6. Web客户端页面问题6-1 问题展示6-2 解决方案 Docker下安装Rab…

机器学习笔记-2

文章目录 一、Linear model二、How to represent this function三、Function with unknown parameter四、ReLU总结、A fancy name 一、Linear model 线性模型过于简单&#xff0c;有很大限制&#xff0c;我们需要更多复杂模式 蓝色是线性模型&#xff0c;线性模型无法去表示…

【自然语言处理】Encoder-Decoder模型中Attention机制的引入

在 Encoder-Decoder 模型中引入 Attention 机制&#xff0c;是为了改善基本Seq2Seq模型的性能&#xff0c;特别是当处理长序列时&#xff0c;传统的Encoder-Decoder模型容易面临信息压缩的困难。Attention机制可以帮助模型动态地选择源序列中相关的信息&#xff0c;从而提高翻译…

了解AI绘画扩散原理-更好掌握AI绘画工具

AI绘画正在成为一种热门的创作工具&#xff0c;壁纸、模特、真人转二次元、艺术字、二维码、设计图、老照片修复、高清修复等&#xff0c;越来越多的使用场景&#xff0c;AI绘画让没有美术基础的人也能够借助工具获得自己想要的美术图片。 AI绘画的核心是“生成模型”&#xf…

插件分享|沉浸式翻译

在这个全球化的时代&#xff0c;语言不再是交流的障碍。但你是否曾经因为一篇外文网页、一份PDF文档或是一段视频字幕而苦恼不已&#xff1f;现在&#xff0c;一款名为“沉浸式翻译”的网页翻译插件&#xff0c;将彻底改变你的翻译体验&#xff01;&#xff08;文末附安装地址&…

开源医疗大模型Llama3-Aloe-8B-Alpha,性能超越 MedAlpaca 和 PMC-LLaMA

前言 近年来&#xff0c;大型语言模型 (LLM) 在医疗领域展现出巨大潜力&#xff0c;能够帮助医生和研究人员更快地获取信息、分析数据&#xff0c;并提高医疗服务效率。然而&#xff0c;目前市场上大多数医疗 LLM 都是闭源模型&#xff0c;限制了其在学术研究和应用领域的推广…

基于Arduino的仿生面具

DIY 万圣节恐怖惊喜&#xff1a;自制动态眼动和声音感应的仿生面具 引言 万圣节即将来临&#xff0c;你是否准备好制作一些既诡异又迷人的装饰来增添节日气氛呢&#xff1f;今天&#xff0c;我们将一起探索如何使用3D打印、伺服电机、PIR传感器和DFPlayer MP3模块来制作一个动…

【黑马redis高级篇】持久化

//来源[01,05]分布式缓存 除了黑马&#xff0c;还参考了别的。 目录 1.单点redis问题及解决方案2.为什么需要持久化&#xff1f;3.Redis持久化有哪些方式呢&#xff1f;为什么我们需要重点学RDB和AOF&#xff1f;4.RDB4.1 定义4.2 触发方式4.2.1手动触发save4.2.2被动触发bgsa…

STM32 ADC学习日记

STM32 ADC学习日记 1. ADC简介 ADC 即模拟数字转换器&#xff0c;英文详称 Analog-to-digital converter&#xff0c;可以将外部的模拟信号转换为数字信号。 STM32F103 系列芯片拥有 3 个 ADC&#xff08;C8T6 只有 2 个&#xff09;&#xff0c;这些 ADC 可以独立使用&…

《中国林业产业》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《中国林业产业》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《中国林业产业》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;国家林业和草原局 …

【Linux】system V进程间通信--共享内存,消息队列,信号量

目录 共享内存 基本原理 创建共享内存 共享内存创建好后&#xff0c;我们可以查询共享内存&#xff0c;验证一下是否创建成功&#xff1b; 删除共享内存 共享内存的挂接 实现通信 消息队列&#xff08;了解&#xff09; 消息队列概念 消息队列接口 操作指令 信号量…

从MySQL到OceanBase离线数据迁移的实践

本文作者&#xff1a;玉璁&#xff0c;OceanBase 生态产品技术专家。工作十余年&#xff0c;一直在基础架构与中间件领域从事研发工作。现负责OceanBase离线导数产品工具的研发工作&#xff0c;致力于为 OceanBase 建设一套完善的生态工具体系。 背景介绍 在互联网与云数据库技…