当前位置: 首页 > news >正文

java中的垃圾收集机制

推荐

1

1 垃圾回收

1.1 java的gc堆中的对象而言,什么时候对象会从待回收状态变为激活状态(垃圾变成非垃圾对象)

当然可以。首先,为了使用 try-with-resources,您需要一个实现了 AutoCloseableCloseable 接口的类。这两个接口都有一个需要实现的方法:close()

以下是一个简单的示例:

  1. 定义一个实现 AutoCloseable 的类:
public class MyResource implements AutoCloseable {public MyResource() {System.out.println("Resource opened.");}public void use() {System.out.println("Resource is being used.");}@Overridepublic void close() {System.out.println("Resource closed.");}
}
  1. 使用 try-with-resources 结构:
public class TryWithResourcesDemo {public static void main(String[] args) {try (MyResource resource = new MyResource()) {resource.use();} catch (Exception e) {System.out.println("An exception occurred: " + e.getMessage());}}
}

当您运行上述代码,您会看到以下输出:

Resource opened.
Resource is being used.
Resource closed.

try-with-resources 结构中,资源 resourceclose() 方法自动在try块结束时被调用,确保资源得到适当的关闭,即使在使用资源时抛出异常。

这种结构的主要优势在于它确保了资源的正确和及时关闭,从而减少了资源泄漏和相关错误。

1.2 给我展示使用如try-with-resources和AutoCloseable接口复活对象的demo

try-with-resources的上下文中,复活对象是不常见的,也并不推荐的。这是因为这种机制的主要目的是确保资源被正确关闭,而不是管理对象的生命周期。

但为了说明,在close()方法内部,您可以尝试复活对象,虽然这样做并不是一个好的实践。

假设我们有一个类似于前面的MyResource,但这次它有一个静态引用来复活对象:

public class ResurrectingResource implements AutoCloseable {public static ResurrectingResource instance;public ResurrectingResource() {System.out.println("Resource opened.");}public void use() {System.out.println("Resource is being used.");}@Overridepublic void close() {System.out.println("Resource closed.");instance = this;  // 尝试复活对象}
}

您可以使用此资源与try-with-resources

public class ResurrectionDemo {public static void main(String[] args) {try (ResurrectingResource resource = new ResurrectingResource()) {resource.use();}// 检查对象是否已复活if (ResurrectingResource.instance != null) {System.out.println("Resource was resurrected!");ResurrectingResource.instance.use();} else {System.out.println("Resource was not resurrected.");}}
}

当您运行此代码时,您将看到:

Resource opened.
Resource is being used.
Resource closed.
Resource was resurrected!
Resource is being used.

虽然这里确实展示了如何在close()方法中复活对象,但要强调,这并不是try-with-resourcesAutoCloseable的推荐或普遍用法。在实际的应用程序设计中,复活对象的情况应该避免,因为这可能会引入意外的行为和难以调试的问题。

1.3 所以java堆中垃圾变成非垃圾的情况一般很少出现是吗?

是的,Java堆中一个被视为垃圾的对象变成非垃圾对象的情况(也称为对象复活)是很少见的,并且通常是因为finalize方法中的某些行为。正如前面所提到的,对象复活的情况并不推荐,因为这可能引入复杂性和难以预测的行为。大多数现代的Java程序或库很少依赖finalize方法,并可能完全避免使用它。

1.4 如果个方法刚开始创建了一个对象,到方法结束都没有被使用,方法执行时该对象会被回收吗

如果一个方法在开始时创建了一个对象,但直到方法结束之前都没有使用它,那么在方法执行的过程中,对象不会被垃圾回收。Java的垃圾回收器使用的是可达性分析算法来确定哪些对象可以被回收。简单地说,从GC Roots(如栈上的局部变量、静态变量、JNI引用等)开始,如果一个对象在分析时是可达的,那么它就不被视为垃圾。

在您描述的情况中,尽管对象在方法的大部分时间里没有被使用,但它在栈上的局部变量中仍然是可达的,所以它不会被视为垃圾并且不会在该方法执行时被回收。只有当方法结束后,局部变量超出了范围,该对象才可能被视为垃圾(前提是没有其他引用指向它)。

1.5 一个方法内创建的对象,执行完后也不会立即回收,而是等该方法执行完后才会被标记为垃圾对吗

一个方法内创建的对象在方法执行完毕后可能被标记为垃圾,但它并不会立刻被回收。对象的回收时机由垃圾回收器的策略和触发条件决定。例如,对象可能仍然存在于堆中,直到下一次GC周期开始。具体回收的时机取决于垃圾回收器的种类和配置(例如,使用的是Serial、Parallel、CMS、G1等)以及垃圾回收的触发条件(如内存使用阈值)。

1.6 只有当方法结束后,局部变量超出了范围,该对象才可能被视为垃圾,局部变量超出了范围是说栈帧上的引用已经不存在了,换成了另一个栈帧,所以新的gc roots向下遍历就搜索不到,最终会被回收是吗?

是的,当方法结束后,该方法的栈帧会被弹出,所以它上面的局部变量也都会超出范围。这意味着这些局部变量(如果是对象引用的话)不再被视为GC Roots。因此,如果这些局部变量是唯一引用某些对象的话,那么这些对象将变得不可达。在下次垃圾回收周期中,垃圾回收器将检查对象的可达性,不可达的对象将被标记为垃圾,待以后的回收阶段进行清理。

正如您所说,新的GC Roots开始遍历时,如果无法到达某个对象(即它不可达),那么该对象就会被标记,并在稍后的阶段中被回收。

1.7 死对象不是一种不可达对象吗,为什么又能够引用到他呢?

答:在cms的重新标记阶段,会重新扫描gc roots,这些gc roots存在于各个线程栈帧中的,如果一个线程在并发标记阶段复活了之前的待回收对象,那么在重新标记阶段这个阶段会扫描到这个新开线程的gc roots,通过gc roots向下遍历,则会发现之前死亡的对象又变活了。

您讲的是关于Java中的CMS(Concurrent Mark-Sweep)垃圾收集器的细节。在您提供的描述中,您讨论了在CMS重新标记阶段中可能发生的对象复活现象。

您的描述基本上是正确的,但我将对您的描述进行一些简单的澄清,以使其更加清晰。

  1. 死对象与不可达对象:首先,死对象确实是指那些不再被引用的对象,也称为不可达对象。不可达意味着没有任何引用路径从GC Roots(如线程栈、静态变量等)指向这些对象。

  2. 对象复活:在Java中,特定的情况下,对象可以“复活”。具体来说,当对象的finalize()方法被调用时,该对象有机会重新被引用,从而使其复活。因此,在CMS并发标记阶段之后,如果某些对象的finalize()方法被执行并重新被引用,这些对象可能会在重新标记阶段中被视为活动对象。

  3. CMS的重新标记阶段:您提到的重新标记阶段确实是CMS中的一个阶段,它是为了确保并发标记阶段中可能被错过或状态已更改的对象被正确处理。在此阶段,GC会再次从GC Roots开始标记可达对象。因此,如果在此期间有对象从“死”状态复活,则它们会被正确地标记为活动对象。

综上所述,您的描述是正确的,对象在CMS的并发标记阶段之后确实有可能复活,而在重新标记阶段中,这些复活的对象会被正确地标记为活动对象。

1.9 死对象如何被引用:

正常情况下,一个死对象(即不可达对象)是不会再被程序引用到的。但在对象的 finalize 方法中,它可能将自己赋给某个还存活的静态变量或其他可达的变量,这样该对象就会再次变得可达,从而实现了“复活”。

这种“对象复活”的情况很少见,但确实是可能的。这也是为什么在 Java 中,一个对象的 finalize 方法只会被调用一次,即使它再次变得不可达。这是为了防止对象在每次被认为是垃圾时都通过 finalize 方法复活,导致永远不被回收。

因为 finalize 方法的这种潜在问题和其他一些性能考虑,它的使用通常不被推荐,并且在 Java 9 之后被标记为废弃。

1.10 CMS会回收那些本来是活着的,后来又死亡的对象吗

答案是会。但这需要一些解释。

在CMS的并发标记阶段中,对象可能仍然是活的(可达的)。但在后续的阶段中,例如在并发标记和重新标记之间,一些对象可能会变成死亡状态(不可达)。**CMS的重新标记阶段(Final Remark)会处理并发标记期间可能发生的变化,捕捉这些新的死亡对象。**因此,当CMS进入并发清扫阶段时,这些在并发标记后死亡的对象会被回收。

因此,CMS确实可以处理和回收那些在并发标记后变得不可达的对象。

1.11 cms的卡表标记在被引用对象的区域还是?比如年轻代指向老年代,是标记年轻代的卡表还是老年代

在HotSpot JVM中,当发生跨代引用时(例如年轻代对象指向老年代对象),这是通过在卡表中标记写入对象的区域(即修改引用的区域)来跟踪的。具体来说,如果一个年轻代对象引用了一个老年代对象,那么这个年轻代对象所在的卡表区域会被标记为“脏”(dirty)。因此,答案是:在年轻代的卡表上进行标记。

1.12 CMS为什么需要预留空间:

CMS(Concurrent Mark-Sweep)是一个主要针对老年代的收集器。由于其设计是为了最小化应用的停顿时间,CMS在大部分阶段都允许应用线程并发运行。但这种设计也带来了一个问题:在CMS清扫阶段与下一次GC之间,应用可能继续分配新对象。如果老年代的空间被完全用完,会导致一次Full GC,这样CMS的目标——减少停顿——就会失效。

为了避免这种情况,CMS设计了一个“预留空间”机制。当老年代的使用量超过某个阈值时,CMS会提前触发GC,而不是等到老年代完全用完。这样,它确保了有足够的空间可以在并发阶段处理新的对象分配。

这个预留空间的设置是通过JVM参数-XX:CMSInitiatingOccupancyFraction来控制的。默认值是68,表示当老年代使用率超过68%时,就启动CMS收集。

1.13 CMS的并发预处理要做的具体事情

1.14 CMS的重新标记要做的具体事情

2 资源释放

2.1 资源释放和垃圾回收之间的关系

  1. 资源释放:

    • 指的是对象使用完毕后,及时地释放其所持有的外部资源,如文件句柄、网络连接、数据库连接等。
    • 在Java中,可以通过实现 CloseableAutoCloseable 接口并覆写 close 方法来进行资源释放。使用 try-with-resources 语句可以确保资源得到适当的释放。
    • 资源释放是开发者的责任。如果不妥善处理,可能会导致资源泄漏,从而引发各种问题(如文件无法打开,因为文件句柄已耗尽)。
  2. 垃圾回收:

    • 垃圾回收是自动的过程,其目的是找出那些不再被使用的对象并回收其内存。
    • 在Java中,垃圾回收由垃圾回收器(Garbage Collector, GC)负责。GC会周期性地运行,标记并回收不可达的对象。
    • 开发者通常无需直接管理内存或手动释放对象,但了解其工作原理有助于编写更高效的代码。

它们之间的关系:

  • 资源释放关注的是外部资源,而垃圾回收关注的是内部的内存资源。
  • 资源释放应当尽早进行,以确保系统资源得到适时的释放。但一个对象的内存是否被回收是由GC决定的,这可能在资源释放后的任何时间点发生。
  • 不妥善的资源释放可能导致资源泄漏,尽管对象的内存最终可能被GC回收。但反过来,即使对象的外部资源已经被适当释放,如果对象仍然可达,它的内存还不会被GC回收。

总之,资源释放和垃圾回收都是为了确保资源的有效管理。资源释放确保外部资源得到释放,而垃圾回收确保不再使用的内存得到回收。

2.2 假设这个try语句在方法中,try执行完但是方法没有执行完,它会被回收掉吗?

try (BufferedReader br = new BufferedReader(new FileReader("filename.txt"))) {// ... read from the file
} 

在上述 try-with-resources 语句中,BufferedReader 实例 brtry 代码块结束后会自动调用其 close 方法,释放其占用的资源。但这与 Java 垃圾回收的行为是两回事。

关于您的问题,具体答案如下:

  1. 资源释放:在 try 代码块结束后,因为 BufferedReader 实现了 CloseableAutoCloseable 接口,其 close 方法会被自动调用,关闭文件资源。这与 br 对象是否被回收无关,只是相关的资源(如文件句柄)被适时释放了。

  2. 对象回收:尽管资源已经释放,但 br 对象本身在堆中的占用的内存并没有立即被回收。br 对象何时被垃圾回收取决于垃圾回收器的行为。在 try-with-resources 语句结束后,br 的引用超出了范围,使得 br 对象不再可达,因此它可以被标记为垃圾,等待后续的垃圾回收。

总结:在 try 语句结束后,BufferedReaderclose 方法确保文件资源得到释放,而 br 对象何时被回收则取决于垃圾回收器。

2.3 try-with-resource和try-catch/throws exception抛异常是两个完全不同的概念,虽然它们的关键字有重合

2.3.1 try-with-resources会捕获异常吗?

答:不会,
如果在一个方法中使用到了try-with-resource语句,并且这个语句有可能抛出异常,比如FileNotFoundException,也就是说这个语句既是申请资源又会抛出异常;那么最终,还是得给他加上一个catch捕获,或者在方法签名上添加throws Exception
比如下面所示:这里的try被复用了,既是try-wth-resouce的try,也是try-catch的try

    public void method(String[] args) {try (BufferedReader br = new BufferedReader(new FileReader("filename.txt"))) {// ... read from the file} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

2.3.2 try-with-resource必须和try-catch同时使用吗?

答:不一定,要看申请的资源语句本身的逻辑是否存在抛异常的可能,比如sc就不需要我们主动抛异常。

void sc(){try (Scanner scanner = new Scanner(System.in)) {}}

2.3.3 如果在方法中throws 异常呢或者try-catch捕获异常呢,会正确关闭资源吗?

如果在打开资源的语句中没有使用try-with-resource语句或者没有显示的掉哟close方法关闭资源,则即使抛异常了也不会关闭资源,因为它们是两个独立的概念。

如果你在方法签名中使用了 throws 来声明可能抛出的异常,并且你在方法体中使用了 try-with-resources 来管理资源,那么即使方法抛出了异常,try-with-resources 仍然会确保资源被正确关闭。

例如:

public void readFile() throws IOException {try (BufferedReader br = new BufferedReader(new FileReader("filename.txt"))) {// ... read from the file, which might throw IOException}// other code that might throw IOException
}

在上述例子中,如果 BufferedReader 的使用过程中出现了 IOException,或者在后续的代码中抛出了 IOExceptionBufferedReader 对象 br 仍然会被正确关闭。

这就是 try-with-resources 的优势:它确保声明在其代码块内的资源总是被关闭,不论是否发生异常。

2.3.4 throw和throws的区别

throwthrows 在Java中都与异常处理有关,但它们的用途和用法是不同的。以下是它们之间的主要区别:

  1. 用途:

    • throw: 是一个语句,用于在代码中显式地抛出一个异常。你可以使用 throw 来抛出自定义的异常或已存在的异常。
    • throws: 用于声明一个方法可能会抛出的异常。这不会真正抛出异常,而是告诉调用者这个方法可能会抛出这些异常,因此调用者应该处理它们或继续声明这些异常。
  2. 位置:

    • throw: 用在方法体内。
    • throws: 用在方法签名上,紧跟在方法的参数列表之后。
  3. 后跟内容:

    • throw: 后面跟一个异常对象,例如 throw new Exception("Error message");
    • throws: 后面跟一个或多个异常类名,用逗号分隔,例如 throws IOException, SQLException
  4. 示例:

    使用 throw:

    public void someMethod() {if (someCondition) {throw new RuntimeException("Some error occurred!");}
    }
    

    使用 throws:

    public void readFile() throws IOException {// ... code that might throw an IOException
    }
    
  5. 使用场景:

    • 你可以使用 throw 来在特定条件下抛出异常,或在 catch 块中重新抛出捕获到的异常。
    • 你可以使用 throws 在方法签名上声明异常,以告知调用者需要处理或传播这些异常。
  6. 处理方式:

    • 一个方法内部使用 throw 抛出的异常需要在该方法内部使用 try-catch 处理,或者可以通过 throws 在方法签名上声明该异常,使得调用者来处理它。
    • 使用 throws 声明的异常可以在方法内部被捕获并处理,也可以不被处理并传播给该方法的调用者。

相关文章:

java中的垃圾收集机制

推荐 1 1 垃圾回收 1.1 java的gc堆中的对象而言,什么时候对象会从待回收状态变为激活状态(垃圾变成非垃圾对象) 当然可以。首先,为了使用 try-with-resources,您需要一个实现了 AutoCloseable 或 Closeable 接口的…...

TCP网络服务器设计

最近设计了一个网络服务器程序,对于4C8G的机器配置,TPS可以达到5W。业务处理逻辑是简单的字符串处理。服务器接收请求后对下游进行类似广播的发送。在此分享一下设计方式,如果有改进思路欢迎大家交流分享。 程序运行在CentOS7.9操作系统上&a…...

4. C++构造函数和析构函数

一、对象的初始化和清理 C中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置,对象的初始化和清理也是两个非常重要的安全问题 一个对象或者变量没有初始状态,对其使用后果是未知的使用完一个对象或变量&#x…...

【Spring Cloud 四】Ribbon负载均衡

Ribbon负载均衡 系列文章目录背景一、什么是Ribbon二、为什么要有Ribbon三、使用Ribbon进行负载均衡服务提供者A代码pom文件yml配置文件启动类controller 服务提供者Bpom文件yml配置文件启动类controller 服务消费者pom文件yml文件启动类controller 运行测试 四、Ribbon的负载均…...

“星闪”:60%能耗 6倍速度 1/30时延**

蓝牙技术的诞生与挑战 蓝牙技术,由爱立信公司于1994年发明,最初旨在实现无线音频传输,使无线耳机成为可能。这项技术成为过去20多年里最主流的近距离无线通讯技术,广泛应用于手机、耳机、手柄、键盘等设备。然而,尽管…...

cocosCreator 之 i18n多语言插件

版本: v3.4.0 环境: Mac 简介 i18n是国际化的简称, 全名:internationalization;取首尾字符i和n,18代表单词中间的字符数目。 该插件不需要产品做太多的改变,通过语言的设置,实现不…...

redis 如何保证数据一致性

前言 日常开发中常会使用redis作为项目中的缓存,只要我们使用 Redis 缓存,就必然会面对缓存和数据库间的一致性保证问题。而且如果数据不一致,那么应用从缓存中读取的数据就不是最新数据,可能会导致严重的业务问题。 为什么会数…...

因果推断(三)双重差分法(DID)

因果推断(三)双重差分法(DID) 双重差分法是很简单的群体效应估计方法,只需要将样本数据随机分成两组,对其中一组进行干预。在一定程度上减轻了选择偏差带来的影响。 因果效应计算:对照组y在干预…...

neo4j入门实例介绍

使用Cypher查询语言创建了一个图数据库,其中包含了电影《The Matrix》和演员Keanu Reeves、Carrie-Anne Moss、Laurence Fishburne、Hugo Weaving以及导演Lilly Wachowski和Lana Wachowski之间的关系。 CREATE (TheMatrix:Movie {title:The Matrix, released:1999,…...

CGAL-2D和3D线性几何内核-点和向量-内核扩展

文章目录 1.介绍1.1.鲁棒性 2.内核表示2.1.通过参数化实现泛型2.2.笛卡尔核2.3.同质核2.4.命名约定2.5.内核作为trait类2.6.选择内核和预定义内核 3.几何内核3.1.点与向量3.2.内核对象3.3.方位和相对位置 4.谓语和结构4.1.谓词4.2.结构4.3.交集和变量返回类型4.4.例子4.5.构造性…...

Ubuntu 22.04 安装docker

参考: https://docs.docker.com/engine/install/ubuntu/ 支持的Ubuntu版本: Ubuntu Lunar 23.04Ubuntu Kinetic 22.10Ubuntu Jammy 22.04 (LTS)Ubuntu Focal 20.04 (LTS) 1 卸载旧版本 非官方的安装包,需要先卸载: docker.io…...

电脑维护进阶:让你的“战友”更强大、更持久!

前言 无论是学习还是工作,电脑已经成为了IT人必不可少的得力助手。然而,电脑的性能和寿命需要经过细心的维护来保证。本文将详细探讨如何维护你的电脑,延长它的寿命,以及一些实用建议。 硬件保养篇 内部清洁 灰尘会导致电脑散热…...

【Leetcode】75.颜色分类

一、题目 1、题目描述 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情况下解决这个问…...

Pytesseract学习笔记

函数 pytesseract.image_to_string(image: Any, lang: Any None, …) 识别图像中的文本。 Parameters image(Any):输入图像,不接受bytes类型。...

cnvd通用型证书获取姿势

因为技术有限,只能挖挖不用脑子的漏洞,平时工作摸鱼的时候通过谷歌引擎引擎搜索找找有没有大点的公司有sql注入漏洞,找的方法就很简单,网站结尾加上’,有异常就测试看看,没有马上下一家,效率至上…...

elasticsearch的副本和分片的区别

es/elasticsearch的副本和分片的区别 一:概念 (1)集群(Cluster): ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互…...

Docker部署Gitlab

Docker部署Gitlab 文章目录 Docker部署Gitlab前置环境部署步骤初始化配置文件80端口部署方式(二选一)非80端口需要的部署方式(二选一)修改 gitlab.rb修改 gitlab.yml刷新配置 前置环境 docker 19.03.13 es 7.2.0 部署步骤 初始…...

ABeam News | ABeam大中华区新人入社式,开启崭新的职场探索之旅吧!

ABeam News | ABeam大中华区新人入社式,开启崭新的职场探索之旅吧! 隔空投送 很高兴认识你 7月3日,FY24 ABeam大中华区新人入社式在西安隆重举办,ABeam大中华区董事长兼总经理中野洋辅先生专程莅临入社式现场,与89名…...

【C++】开源:sqlite3数据库配置使用

😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍sqlite3数据库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下…...

[Docker实现测试部署CI/CD----Jenkins集成相关服务器(3)]

目录 7、 Jenkins 集成 SonarQubeJenkins 中安装 SonarScanner下载移动修改配置文件 8、Jenkins配置SonarQube安装插件添加SonarQube添加 SonarScanner 9、Jenkins集成目标服务器 7、 Jenkins 集成 SonarQube Jenkins 中安装 SonarScanner SonarScanner 是一种代码扫描工具&am…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

PHP和Node.js哪个更爽?

先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes&#xff0…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...