JAVA IO前言Comparable & Comparator & 序列化Serializable & 反序列化Deserializable

2023-11-02

Comparable可认为是内比较器(可比较的),是接口类,类参数为泛型对象T,通常对比的类本身需实现继承Comparable接口类的唯一方法compareTo(T o),对比指标为类的一个或多个属性,对比类与Comparable接口类耦合性强,Comparable接口类源代码如下:

public interface Comparable<T> {
 	public int compareTo(T o);
}
  类对象通常在实现继承Comparable接口类后,配合java.util.Collections.sort(T[] arr)或java.util.Arrays.sort(List<T> list)来实现排序。
  JDK常见使用:如基本数据类型String,Integer implements java.io.Serializable, Comparable<T>以及File implements java.io.Serializable, Comparable<File>

 Comparator可认为是是外比专用比较器,是接口类,类参数为泛型对象T,通过编写独立的排序算法类继承Comparator接口类,而对比类本身不做任何继承,保证对比类与Comparator接口类无耦合接口类部分源代码如下:

public interface Comparator<T> {
    int compare(T o1, T o2);
    boolean equals(Object obj);
    .......
}

  类对象通常在独立的排序算法类实现继承Comparator接口类后,配合java.util.Collections.sort(T[] arr, Comparator<? super T> c)java.util.Arrays.sort(List<T> list, Comparator<? super T> c)来实现排序。常见使用习惯(代码片段):

StudentComparator implements Comparator<Student> {
   @Override
   public int compare(Student o1, Studento2) {
	  if (o1.getScore() > o2.getScore()) return -1;
	  else if (o1.getScore() < o2.getScore()) return 1;
	  else {
               if (o1.getAge() > o2.getAge()) return 1;
	       else if (o1.getAge() < o2.getAge()) return -1;
	       else return 0;
	   }
   }	
}
java.util.Arrays.sort(Student[] stuArrs,new StudentComparator());
java.util.Collections.sort(List<Student> sList,new StudentComparator());

序列化Serializable 和反序列化Deserializable

概念:把对象(内存中)转换为字节序列的过程称为对象的序列化;把字节(码)序列恢复为对象的过程称为对象的反序列化。

主要用途:1)把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中 2)在网络上传送对象的字节序列

    **磁盘数据存储格式或网络间数据存储传输格式都基于 字节 **

序列化 ID

  序列化 ID 是否一致确定了类反序列化是否正确默认long serialVersionUID = 1L),序列化保存的是对象的状态,不能保存类的状态,序列化静态变量不保存,直接从内存中取数据验证片断代码:

public class TestSerializable implements Serializable {
	private static final long serialVersionUID = 1L;
	public  static String staticVar = "static";
	public  String name = "cj";
        public static void main(String[] args) {
        TestSerializable m = new TestSerializable();
		 m.setName("cm");
		 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj"));
		 out.writeObject(m);
		 out.close(); 
		  TestSerializable mupdage = new TestSerializable();
		  mupdage.staticVar = "staticUpdate";
		  mupdage.setName("cmUpdate");
		  ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); 
		  TestSerializable  t = (TestSerializable) oin.readObject();
		  oin.close(); 
		  System.out.println(t.staticVar +" "+ t.getName());
        }
   }
   输出:staticUpdate cm

  原因:类普通属性值通过反序列化转化后的中对象获取值,而静态变量属性值从内存中获取

Transient[临时的] 关键字:特殊定义变量,阻止该变量被序列化,在被反序列化后,transient 变量的值被设为初始值

对敏感字段加密 

  情境:服务器端给客户端发送序列化对象数据,对象中敏感数据在序列化时需要进行加密,比如密码字符串等,客户端在拥有解密的密钥,且进行反序列化时,才可以对密码进行读取,这样可一定程度保证序列化对象的数据安全。
  解决:在序列化过程中,虚拟机会试图调用对象类里的 writeObject 和 readObject 方法,进行用户自定义的序列化和反序列化。如果没有这样的方法,则默认调用是 ObjectOutputStream 的 defaultWriteObject 方法以及 ObjectInputStream 的 defaultReadObject 方法。验证片断代码:

 public class User implements Serializable {
     private static final long serialVersionUID = 1L;
     private String password = "pass";//省略GET、SET
     private void writeObject(ObjectOutputStream out) {
     try {
        PutField putFields = out.putFields();
        System.out.println("原密码:" + password);
        password = "encryption";//模拟加密
        putFields.put("password", password);
        System.out.println("加密后的密码" + password);
        out.writeFields();
        } catch (IOException e) { e.printStackTrace();}
     }

     private void readObject(ObjectInputStream in) {
    try {
        GetField readFields = in.readFields();
        Object object = readFields.get("password", "");
        System.out.println("要解密的字符串:" + object.toString());
        password = "pass";//模拟解密,需要获得本地的密钥
  }   catch (IOException e) { e.printStackTrace(); } 
       catch (ClassNotFoundException e) { e.printStackTrace(); }   
      }

 public static void main(String[] args) {
     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj"));
         out.writeObject(new User());  out.close();
        ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj"));
       User t = (User) oin.readObject();
        System.out.println("解密后的字符串:" + t.getPassword());   oin.close();
      }
}
  使用案例 :RMI技术是完全基于 Java序列化技术的,服务器端接口调用所需要的参数对象来至于客户端,它们通过网络相互传输。这就涉及RMI 的安全传输的问题。一些敏感的字段,如用户名密码(用户登录时需要对密码进行传输),我们希望对其进行加密,这时,就可以采用本节介绍的方法在客户端对密 码进行加密,服务器端进行解密,确保数据传输的安全性

序列化存储规则

     Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用,增加 5 字节的存储空间就是新增引用和一些控制信息的空间。反序列化时,恢复引用关系,使得清单 3 中的 t1 和 t2 指向唯一的对象,二者相等,输出 true。该存储规则极大的节省了存储空间,如下代码片断:

    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result2.obj"));
        TestSerializable testS = new TestSerializable();
	testS.setName("1");
        out.writeObject(testS);
	out.flush();
        System.out.print(new File("result2.obj").length() +" ");
        testS.setName("2");
	out.writeObject(testS);
	System.out.print(new File("result2.obj").length()+" ");
	out.close();
	oin2 = new ObjectInputStream(new FileInputStream("result2.obj"));
	TestSerializable t1 = (TestSerializable) oin2.readObject();
	TestSerializable t2 = (TestSerializable) oin2.readObject();
	System.out.print(t1 == t2);
	System.out.println(" " +t1.getName() +" " + t2.getName());
输出:72 77 true 1 1

原理分析

  序列化方式一调用ObjectOutputStreamwriteObject方法序列化对象,将其写入磁盘,再次调用readObject时,根据wirteObject方法磁盘文件重新恢复对象

  序列化方式二Externalizable接口扩展Serializable,并增添了两个方法:writeExternal()readExternal()。在序列化和重新装配的过程中,会自动调用两个方法

方式一执行的详细如下

1)ObjectOutputStream的构造函数设置enableOverride = false

public ObjectOutputStream(OutputStream out) throws IOException {
    verifySubclass();
    bout = new BlockDataOutputStream(out);
    handles = new HandleTable(10, (float) 3.00);
    subs = new ReplaceTable(10, (float) 3.00);
    enableOverride = false;
    writeStreamHeader();
    bout.setBlockDataMode(true);
    if (extendedDebugInfo) {
        debugInfoStack = new DebugTraceInfoStack();
    } else {
        debugInfoStack = null;
    }
}

2)外部调用ObjectOutputStream.writeObject(序列化类对象)方法执行writeObject0(obj, false);

public final void writeObject(Object obj) throws IOException {
    if (enableOverride) {
        writeObjectOverride(obj);
        return;
    }
    try {
        writeObject0(obj, false);
    } catch (IOException ex) {
        if (depth == 0) {
            writeFatalException(ex);
        }
        throw ex;
    }
}

writeObject0(obj, false)重要代码片断:

// remaining cases
if (obj instanceof String) {
    writeString((String) obj, unshared);
} else if (cl.isArray()) {
    writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
    writeEnum((Enum<?>) obj, desc, unshared);
} else if (obj instanceof Serializable) {
    writeOrdinaryObject(obj, desc, unshared);
} else {
    if (extendedDebugInfo) {
        throw new NotSerializableException(
            cl.getName() + "\n" + debugInfoStack.toString());
    } else {
        throw new NotSerializableException(cl.getName());
    }
}

 从上可以看出,如果对象没有实现Serializable接口,在序列化的时候会抛出NotSerializableException异常

跟踪writeOrdinaryObject(obj, desc,unshared)方法代码片断:

desc.checkSerialize(); 
bout.writeByte(TC_OBJECT);
writeClassDesc(desc, false);
handles.assign(unshared ? null : obj);
if (desc.isExternalizable() && !desc.isProxy()) {
    writeExternalData((Externalizable) obj);
} else {
    writeSerialData(obj, desc);
}

  在检查Serialize后,如果对象实现Externalizable接口,执行writeExternalData((Externalizable) obj)方法如果实现的是Serializable接口,那么执行的是writeSerialData(obj, desc);

  首先看writeSerialData方法,主要执行方法:defaultWriteFields(obj, slotDesc);

private void writeSerialData(Object obj, ObjectStreamClass desc)
    throws IOException
{
    ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
    for (int i = 0; i < slots.length; i++) {
        ObjectStreamClass slotDesc = slots[i].desc;
        if (slotDesc.hasWriteObjectMethod()) {
            PutFieldImpl oldPut = curPut;
            curPut = null;
            SerialCallbackContext oldContext = curContext;

            if (extendedDebugInfo) {
                debugInfoStack.push(
                    "custom writeObject data (class \"" +
                    slotDesc.getName() + "\")");
            }
            try {
                curContext = new SerialCallbackContext(obj, slotDesc);
                bout.setBlockDataMode(true);
                slotDesc.invokeWriteObject(obj, this);
                bout.setBlockDataMode(false);
                bout.writeByte(TC_ENDBLOCKDATA);
            } finally {
                curContext.setUsed();
                curContext = oldContext;
                if (extendedDebugInfo) {
                    debugInfoStack.pop();
                }
            }

            curPut = oldPut;
        } else {
            defaultWriteFields(obj, slotDesc);
        }
    }
}

  slotDesc.hasWriteObjectMethod()检查序列化类是否存在自定义的writeObject(ObjectOutputStream outputStream),存在则执行 slotDesc.invokeWriteObject(obj,this);通过反射去执行自定义的writeObject(ObjectOutputStream outputStream)方法,否则执行默认的defaultWriteFields(obj, slotDesc),若执行默认的defaultWriteFields(obj, slotDesc),通过writeObject0循环将类属性写入文件中。代码片断:

private void defaultWriteFields(Object obj, ObjectStreamClass desc){
desc.checkDefaultSerialize();
    Object[] objVals = new Object[desc.getNumObjFields()];
    int numPrimFields = fields.length - objVals.length;
    desc.getObjFieldValues(obj, objVals);
for (int i = 0; i < objVals.length; i++) {
writeObject0(objVals[i], fields[numPrimFields + i].isUnshared());
....
}
}

 再次看一下writeExternalData的方法,重要代码如下:

private void writeExternalData(Externalizable obj) throws IOException {
try {
    curContext = null;
    if (protocol == PROTOCOL_VERSION_1) {
        obj.writeExternal(this);
    } else {
        bout.setBlockDataMode(true);
        obj.writeExternal(this);
        bout.setBlockDataMode(false);
        bout.writeByte(TC_ENDBLOCKDATA);
    }}

  obj.writeExternal(this)序列化接口类(interfaceExternalizable对象writeExternal方法,故必须在自定义的序列化类中重载实现writeExternal方法,即方式二执行过程。

反序列化

1) objectInputStream.readObject()方法执行readObject0(false)方法:主要代码:

switch (tc) {
                case TC_NULL:
                    return readNull();
              .....
                case TC_STRING:
                case TC_LONGSTRING:
                    return checkResolve(readString(unshared));
                case TC_ARRAY:
                    return checkResolve(readArray(unshared));
                case TC_ENUM:
                    return checkResolve(readEnum(unshared));
                case TC_OBJECT:
                    return checkResolve(readOrdinaryObject(unshared));
                case TC_EXCEPTION:
                    IOException ex = readFatalException();
                    throw new WriteAbortedException("writing aborted", ex);
                case TC_BLOCKDATA:
                .....
                default:
                    throw new StreamCorruptedException(
                        String.format("invalid type code: %02X", tc));
            }

 根据不同的对象类型做相应的处理,这里我们关注的是TC_OBJECT,执行的方法是:checkResolve(readOrdinaryObject(unshared));接着看readOrdinaryObject(unshared)执行了以下代码:

 ObjectStreamClass desc = readClassDesc(false);
 desc.checkDeserialize();
 Object obj;
      try {
            obj = desc.isInstantiable() ? desc.newInstance() : null;
       } catch (Exception ex) {
            throw (IOException) new InvalidClassException(
                desc.forClass().getName(),
                "unable to create instance").initCause(ex);
        }
......
       if (desc.isExternalizable()) {
           readExternalData((Externalizable) obj, desc);
       } else { readSerialData(obj, desc); }

  ObjectStreamClass默认构造函数:

private ObjectStreamClass(final Class<?> cl) {
    if (serializable) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    .....
                    suid = getDeclaredSUID(cl);//获取UID
                    try {
                        fields = getSerialFields(cl);//获取SerialFields
                        computeFieldOffsets();
                    } ......
                    if (externalizable) {
                        cons = getExternalizableConstructor(cl);
                    } else {
                        cons = getSerializableConstructor(cl);
//定义系列ObjectMethod
writeObjectMethod = getPrivateMethod(cl, "writeObject",
                            new Class<?>[] { ObjectOutputStream.class },
                            Void.TYPE);
                        readObjectMethod = getPrivateMethod(cl, "readObject",
                            new Class<?>[] { ObjectInputStream.class },
                            Void.TYPE);
                        readObjectNoDataMethod = getPrivateMethod(
                            cl, "readObjectNoData", null, Void.TYPE);
                        hasWriteObjectData = (writeObjectMethod != null);
                    }
                    ......
              });
          } 
}

 序列化类实现Externalizable 接口执行readExternalData((Externalizable)obj, desc);,实现Serializable接口则执行readSerialData(obj,desc);首先先看readSerialData(obj,desc);代码片断:

    ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
        for (int i = 0; i < slots.length; i++) {
            ObjectStreamClass slotDesc = slots[i].desc;
            if (slots[i].hasData) {
                if (obj == null || handles.lookupException(passHandle) != null) {
                    defaultReadFields(null, slotDesc); // skip field values
                } else if (slotDesc.hasReadObjectMethod()) {
               		 ......
                        slotDesc.invokeReadObject(obj, this);
                    }   ......
                } else { defaultReadFields(obj, slotDesc); }
            }
  if (obj != null && slotDesc.hasReadObjectNoDataMethod() && handles.lookupException(passHandle) == null)
            {slotDesc.invokeReadObjectNoData(obj);} 
       }

  序列化类中若存在ReadObject方法,则执行类中ReadObject方法,否则obj为空或默认情况下执行defaultReadFields方法。

其次看readExternalData((Externalizable)obj, desc);跟踪如以下主要代码片断:

private void readExternalData(Externalizable obj, ObjectStreamClass desc){...obj.readExternal(this);...}

obj.readExternal(this)序列化接口类(interfaceExternalizable对象readExternal方法,故必须在自定义的序列化类中重载实现readExternal方法,即方式二执行过程。



























本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA IO前言Comparable & Comparator & 序列化Serializable & 反序列化Deserializable 的相关文章

  • 一文彻底弄懂零拷贝原理

    零拷贝 零拷贝 Zero Copy 是一种 I O 操作优化技术 可以快速高效地将数据从文件系统移动到网络接口 而不需要将其从内核空间复制到用户空间 其在 FTP 或者 HTTP 等协议中可以显著地提升性能 但是需要注意的是 并不是所有的操
  • 各种注释总结

    jsp注释 html注释
  • [透彻]为什么要前后端分离?

    前后端分离的意义 前后端分离 已成为互联网项目开发的业界标准使用方式 前后端分离 会为以后的大型分布式架构 弹性计算架构 微服务架构打下坚实的基础 核心思想 前端页面调用后端的restuful api接口 并使用json数据进行交互 服务器
  • JAVA,异常

    异常概念 通常大家认为异常就是错误 但这个错误有很多种 1 语法错误 2 JVM虚拟机错误 3 平台错误 4 程序运行错误 平台或者资源或者逻辑 数值等错误 常见的异常 1 java lang NullPointerException 空指
  • JAVA 8 新特性及使用

    1 前言 2019年9月19日java13已正式发布 感叹java社区强大 经久不衰 由于国内偏保守 新东西总要放一放 让其他人踩踩坑 等稳定了才会去用 并且企业目的还是赚钱 更不会因为一个新特性去重构代码 再开发一套程序出来 甚者国内大多
  • JDK介绍

    JDK JRE和JVM之间的关系 JVM是运行环境 JRE是含运行环境和相关的类库 跟node环境是一个意思 JDK目录介绍 目录名称 说明 bin 该路径下存放了JDK的各种工具命令 javac和java就放在这个目录 conf 该路径下
  • java动态代理简单实例

    java动态代理简单实例 package hello import java lang reflect InvocationHandler import java lang reflect Method import java lang r
  • 将list集合的元素按照添加顺序的倒序进行排列取出

    将list集合的元素按照添加顺序的倒序进行排列取出 方法1 list add 0 object List
  • 为什么 Collections.sort 使用相同的参数调用 Comparator 两次?

    我正在运行一个示例来了解 Java 中比较器的行为 import java util ArrayList import java util Collections import java util Comparator class HDTV
  • 在java中按对象的属性对ArrayList进行排序[重复]

    这个问题在这里已经有答案了 我希望按照电子邮件地址的顺序对我的对象进行排序 这是我尝试过的方法 但它不起作用 但我什至不确定这是做我想做的事情的正确方法吗 public static ArrayList
  • Java:使用 >、< 和 == 比较对象

    是否可以使用运算符正确比较对象 gt lt and 在Java中 我已经实施了Comparable我的一个对象中的接口 这样可以节省一些时间 而且写起来也很好 if obj1 lt obj2 do sth 代替 if obj1 compar
  • 黑豹程序员-统一身份认证接口

    术语和定义 1 IAM Identity Access Manager 统一身份认证系统 2 IDM Identity Manager 身份管理 3 SSO Single Sign On 单点登录 4 AD Active Directory
  • 关于空值的可比合同和比较合同

    Comparable合同规定e compareTo null 必须扔NullPointerException From the API http java sun com javase 6 docs api java lang Compar
  • 如何在一个类中创建 2 个可比较的方法?

    我有一个类 我已经按一个属性对其进行了排序 现在我需要做另一件事 我需要创建另一种方法来对数据进行排序 我该怎么做呢 所以我可以选择两种方法 我知道的唯一命令是 Collections sort 它将从我想要比较其数据的类中获取方法comp
  • 如何在 Java 中编写实现 Comparable 的方法签名“T”?

    我的签名上应该有什么insert 方法 我正在与仿制药作斗争 在某种程度上 我两者都想要Comparable
  • 实现 Comparable 以使用字符串按字母顺序排序

    我希望有一个可比较的对象 在这种情况下在 TreeSet 中使用它 我的对象有一个名称字段 我希望它按字母顺序排序 我首先想到我可以使用字符串的 unicode 值并简单地进行减法 但是 AA 会在 Ab 之后 我是这样开始的 public
  • 将整数数组传递给java中的可比较对象

    public class Stack public static void main String args Strings names news ask man querty lang love poppye zebra hello in
  • 使用 Comparable 比较通用变量

    对于我班级中的一个作业 我们有一个名为 Pair 的类的集合 我们需要根据键的值按升序对其进行排序 如果键是字符串或整数 我可以应用此方法 但是如何编写代码来比较我的项目 当它们是通用的时 如下所示 我班上的教授解释了如何处理整数或字符串
  • 如何比较java中的多个类?

    现在 我已经编写了对整数和字符串数组进行排序的比较器 从代码中可以看出 如果两个类不相同 则 String 类将采用大于值 但是 这仅允许两个类 如果我想向数组添加另一个基本类型 例如 Float 怎么办 我必须向 if else 语句添加
  • C++ 判断类是否具有可比性

    我或多或少是Java程序员 所以这可能是一个愚蠢的问题 但我没有找到任何简单的解决方案 我在 C 中有一个这样的类 template

随机推荐

  • leveldb常见问题以及性能优化点

    本篇是leveldb最后一篇 这里主要把技术核心点 性能提升点或者面试可能会被问到进行总结 一 常见问题 1 leveldb key value内存 内存中保存的是所有key value吗 答 不是 搜索顺序 memtable immtab
  • 利用MATLAB中的newrb函数进行函数逼近

    RBF函数在神经网络控制中较为常见 MATLAB中早已集成了一个newrb的函数 在一些场景下使用起来还比较方便 尤其是涉及到进行函数逼近的时候 参考链接 http blog sina com cn s blog 9b8d0abd0101o
  • Android Studio连接自带模拟器失败怎么办?强烈建议使用第三方模拟器(含各类模拟器下载地址)

    学习安卓开发的小伙伴必然会碰到模拟器的启动问题 就算成功启动Android Studio自带的模拟器 使用起来也是十分缓慢 有时候卡起来是真想骂娘 服了他个老六 那么这个时候 如果有一个第三方模拟器 不仅简单好用 无需配置 而且美观快速零卡
  • 华为存储特性

    华为存储特性 1 SmartPartition SmartPartition是一种性能特性 根据不同业务特点分配存储系统的缓存资源来满足不同应用系统的服务质量要求 由于单个存储系统要面对的应用数量急剧增加 且各业务应用之间的I O特征不同
  • Android-第五节Menu菜单详解

    目录 一 Menu背景 二 Menu使用步骤 1 创建menu 2 设计menu 3 重写menu逻辑代码 4 运行效果 一 Menu背景 手机毕竟和电脑不同 它的屏幕空间非常有限 因此充分地利用屏幕空间在手机界面设计中就显得非常重要了 如
  • STM32 使用TIM2_CH1(PA15) 输出10K PWM信号

    PA15 gt TIM2 Remap CH1 1 apb init RCC APB1PeriphClockCmd RCC APB1Periph TIM2 ENABLE RCC APB2PeriphClockCmd RCC APB2Perip
  • JMM java内存模型

    java内存模型 即 java memory model 它定义了主存 工作内存抽象概念 底层对应着 CPU 寄存器 缓存 硬件内存 CPU 指令优化等 JMM 体现在以下几个方面 原子性 保证指令不会受到线程上下文切换的影响 可见性 保证
  • android 安装命令,【转载】android中APK包的安装以及adb命令的使用

    1 首先将 android sdk platform tools添加都path路径下 2 在控制台窗口中进入到你apk包所在的目录中 3 输入 abd unremount 第一次使用该命令的时候需要获取该命令的操作权限 4 打开androi
  • Filter、Interceptor的使用

    Filter Interceptor的使用 一 Filter Interceptor的区别 1 1 过滤器 Filter 1 2 拦截器 Interceptor 二 Filter Interceptor的使用 2 1 Filter 的实现步
  • 微信临时文件wxfile://tmp文件处理,微信小程序最新获取头像和昵称

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 分享一个使用比较久的 技术栈 taro框架 vue3版本 解决在微信小程序获取微信头像时控制台报错 找不着wxfile tmp 文件路径 失败 原因如下 因为微信提
  • JS合并数组对象中key相同的数据(将数组里某个属性相同的对象合并成一个数组)

    将数组里某个属性相同的对象合并成一个数组 原数组如下 let resData name 住院医疗最高报销 tagName 医疗 insuredAmount 6000 name 身故赔付 tagName 寿险 insuredAmount 36
  • 80后创业故事之:兄弟散伙,创业失败

    在开始今天的故事之前 首先感谢这么多朋友关注我的文章 实在让我受宠若惊 我定倍加珍惜大家对我的支持 同时我也留意到这些天有一些朋友对我的故事也提出了一些质疑 怀疑是否杜撰 编造或者太过夸大其辞 本来我想出说一箩筐的理由来证明我所说的都是我自
  • AIGC参数量节节攀升,对存储带来的挑战如何解决?

    引言 近期 AIGC 相关产品如同雨后春笋一般不断涌现 但在技术层面 大家普遍的关注点更多集中在性能方面 却经常忽略了存储对推理和训练效率的影响 以及 AIGC 内容可能带来的合规风险 我们特邀腾讯云存储的产品负责人 崔剑老师和益企研究院创
  • 性能自动化+locust

    性能自动化 locust 仅作为个人笔记 如有雷同 请联系删除 性能测试基础 1 性能测试相关概念 性能测试 测试软件的性能表现 考量软件运行的如何 一般关注时间 效率 资源占用等情况 响应时间 应用系统从用户发出请求开始 到客户端接收到所
  • 你想知道的大数据知识都在这里

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 毋庸置疑 现如今是属于大数据 Big Data 的 革命性的时代 从社交媒体到企业 每时每刻都在产生大量的数据 无所作为 从而把这样的宝藏白白浪费掉是及其愚蠢的 企业已经学会了收集大
  • OV7670配置和调试总结

    废话后面说 先直接上OV7670寄存器的配置部分 const uint8 t OV7670 Reg 2 Frame Rate Adjustment for 24Mhz input clock 30fps PCLK 24MHz 0x11 0x
  • tomcat部署时注意修改目录路径

    原文 https blog csdn net qq 15676547 article details 81208991 每次发布war包 都会把附件给覆盖了 为了解决这个问题 我们需要把目录给修改到别处 方法如下
  • SSH远程访问AWS EC2

    步骤1 启动Amazon EC2实例 视频演示 启动AWS EC2实例 导航到Amazon EC2并开始启动新实例 在本教程中 我将使用Amazon Linux 2 AMI HVM 操作系统 创建一个没有规则的新安全组 例如MediumSG
  • 利用Selenium(爬虫)爬取物流信息,并用邮件提醒自己物流更新

    受疫情影响 快递无法全面复工 商家在过年期间又压了一堆未发货的订单 现在下单一个快递 商家迟迟无法发货 就算发了货 物流也慢的跟蜗牛一样 每天就是打开淘宝看物流信息 物流信息又没更新 关淘宝 为了节省这些时间 不在焦虑中度过 写了这么一个功
  • JAVA IO前言Comparable & Comparator & 序列化Serializable & 反序列化Deserializable

    Comparable可认为是内比较器 可比较的 是接口类 类参数为泛型对象T 通常对比的类本身需实现继承Comparable接口类的唯一方法compareTo T o 对比指标为类的一个或多个属性 对比类与Comparable接口类耦合性强