• logback详解及入门案例

    1. logback 日志的作用 记录系统和接口的使用情况,比如请求日志 记录和分析用户的行为,比如网站访问日志 调试程序,和控制台的作用类似,但是控制台中的内容并不会保存到文件中,而日志可以长期保存。 帮助我们排查和定位错误。比如在系统抛出异常时,将异常信息记录到日志,可以事后复盘。 通过分析日志还能够优化代码逻辑、提升系统性能、稳定性等。 1.1. logback介绍 Logback继承自log4j。Logback的架构非常的通用,适用于不同的使用场景。 通过上图可以看到logback和Log4j都是slf4j规范的具体实现,我们在程序中直接调用的API其实都是slf4j的api,底层则是真正的日志实现组件—logback或者log4j。 Logback 构建在三个主要的类上:Logger,Appender 和 Layout。这三个不同类型的组件一起作用能够让开发者根据消息的类型以及日志的级别来打印日志。 Logger作为日志的记录器,把它关联到应用的对应的context后,主要用于存放日志对象,也可以定义日志类型、级别。各个logger 都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各 logger。 Appender主要用于指定日志输出的目的地,目的地可以是控制台、文件、 数据库等。 Layout 负责把事件转换成字符串,输出格式化的日志信息。 logback的maven坐标: <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.12</version> </dependency> 1.2. logback层级 在 logback中每一个 logger 都依附在 LoggerContext 上,它负责产生 logger,并且通过一个树状的层级结构来进行管理。 一个 Logger 被当作为一个实体,它们的命名是大小写敏感的,并且遵循以下规则: 如果一个logger的名字加上一个**.**作为另一个logger名字的前缀,那么该logger就是另一个logger的祖先。如果一个logger与另一个logger之间没有其它的logger,则该logger就是另一个logger的父级。 举例: 名为com.zbbmeta的logger是名为com.zbbmeta.service的logger的父级 名为com的logger是名为com.zbbmeta的logger的父级,是名为com.zbbmetat.service的logger的祖先 在logback中有一个root logger,它是logger层次结构的最高层,它是一个特殊的logger,因为它是每一个层次结构的一部分。 1.3. logback日志输出等级 logback的日志输出等级分为:TRACE, DEBUG, INFO, WARN, ERROR。 如果一个给定的logger没有指定一个日志输出等级,那么它就会继承离它最近的一个祖先的层级。 为了确保所有的logger都有一个日志输出等级,root logger会有一个默认输出等级 — DEBUG。 1.4 logback初始化步骤 logback会在类路径下寻找名为logback-test.xml的文件 如果没有找到,logback会继续寻找名为logback.groovy的文件 如果没有找到,logback会继续寻找名为logback.xml的文件 如果没有找到,将会在类路径下寻找文件META-INFO/services/ch.qos.logback.classic.spi.Configurator,该文件的内容为实现了Configurator接口的实现类的全限定类名 如果以上都没有成功,logback会通过BasicConfigurator为自己进行配置,并且日志将会全部在控制台打印出来 最后一步的目的是为了保证在所有的配置文件都没有被找到的情况下,提供一个默认的配置。 2. logback入门案例 2.1. 案例一 本案例是一个logback简单应用,并且不提供配置文件而使用其提供的默认配置。 第一步:创建maven工程logback-demo并配置pom.xml文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zbbmeta</groupId> <artifactId>logback-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project> 第二步:编写单元测试 package com.zbbmeta.logback; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.core.util.StatusPrinter; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 测试logback日志组件的使用 */ public class LogbackTest { //简单使用 @Test public void test1(){ //通过工厂对象获得一个logger日志记录器对象 Logger logger = LoggerFactory.getLogger("com.zbbmeta.test"); //当前logger对象的日志输出级别为debug,从root logger继承来的 //使用trace级别记录日志 logger.trace("trace..."); logger.debug("debug..."); logger.info("info..."); logger.warn("warn..."); logger.error("error..."); } //打印日志内部状态 @Test public void test2(){ //通过工厂对象获得一个logger日志记录器对象 Logger logger = LoggerFactory.getLogger("com.zbbmeta.test"); //当前logger对象的日志输出级别为debug,从root logger继承来的 //使用trace级别记录日志 logger.trace("trace..."); logger.debug("debug..."); logger.info("info..."); logger.warn("warn..."); logger.error("error..."); // 打印内部的状态 LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory(); StatusPrinter.print(lc); // 说明找文件步骤-->logback-test.xml-->logback.xml-->configuration /* |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml] |-INFO in ch.qos.logback.classic.BasicConfigurator@691a7f8f - Setting up default configuration.*/ } /* * 日志输出级别:ERROR > WARN > INFO > DEBUG > TRACE * */ //测试默认的日志输出级别 @Test public void test3(){ Logger logger = LoggerFactory.getLogger("com.zbbmeta.logback.HelloWorld"); logger.error("error ..."); logger.warn("warn ..."); logger.info("info ..."); logger.debug("debug ..."); //因为默认的输出级别为debug,所以这一条日志不会输出 logger.trace("trace ..."); } //设置日志输出等级 @Test public void test4(){ ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.zbbmeta.logback.HelloWorld"); logger.setLevel(Level.DEBUG);//设置当前日志记录器对象的日志输出级别 logger.error("error ..."); logger.warn("warn ..."); logger.info("info ..."); logger.debug("debug ..."); //因为默认的输出级别为debug,所以这一条日志不会输出 logger.trace("trace ..."); } //测试Logger的继承 @Test public void test5(){ ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("com.zbbmeta"); logger.setLevel(Level.TRACE);//设置当前日志记录器对象的日志输出级别 //当前记录器对象是上面记录器对象的子级,从父级继承输出等级---INFO Logger logger1 = LoggerFactory.getLogger("com.zbbmeta.test"); logger1.error("error ..."); logger1.warn("warn ..."); logger1.info("info ..."); logger1.debug("debug ..."); logger1.trace("trace ..."); } //Logger获取,根据同一个名称获得的logger都是同一个实例 @Test public void test6(){ Logger logger1 = LoggerFactory.getLogger("com.zbbmeta.test"); Logger logger2 = LoggerFactory.getLogger("com.zbbmeta.test"); System.out.println(logger1 == logger2); } //参数化日志 @Test public void test7(){ Logger logger = LoggerFactory.getLogger("com.zbbmeta"); String value = "world"; logger.info("参数值为:" + value); logger.debug("hello {}","world"); } } 2.2 案例二 本案例是logback中Spring Boot项目中的应用。 第一步:创建maven工程springboot-logback-demo并配置pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.7.15</version> </parent> <groupId>com.zbbmeta</groupId> <artifactId>springboot-logback-demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> </dependencies> </project> 第二步:在resources下编写logback配置文件logback-base.xml和logback-spring.xml logback-base.xml:作为基础配置 <?xml version="1.0" encoding="UTF-8"?> <included> <contextName>logback</contextName> <!-- name的值是变量的名称,value的值时变量定义的值 定义变量后,可以使“${}”来使用变量 --> <property name="log.path" value="logs" /> <!-- 彩色日志 --> <!-- 彩色日志依赖的渲染类 --> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <!-- 彩色日志格式 --> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> <!--输出到控制台--> <appender name="LOG_CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--输出到文件--> <appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/logback.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 每天日志归档路径以及格式 --> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> </appender> </included> logback-spring.xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <!--引入其他配置文件--> <include resource="logback-base.xml" /> <!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。<logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 如果未设置此属性,那么当前logger将会继承上级的级别。 addtivity:是否向上级logger传递打印信息。默认是true。 --> <!--开发环境--> <springProfile name="dev"> <logger name="com.zbbmeta.controller" additivity="false" level="debug"> <appender-ref ref="LOG_CONSOLE"/> </logger> </springProfile> <!--生产环境--> <springProfile name="pro"> <logger name="com.zbbmeta.controller" additivity="false" level="info"> <appender-ref ref="LOG_FILE"/> </logger> </springProfile> <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF 默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 --> <root level="info"> <appender-ref ref="LOG_CONSOLE" /> <appender-ref ref="LOG_FILE" /> </root> </configuration> 第三步:编写application.yml server: port: 8999 #logging: # #在Spring Boot项目中默认加载类路径下的logback-spring.xml文件 # config: classpath:logback.xml logging: #在Spring Boot项目中默认加载类路径下的logback-spring.xml文件 config: classpath:logback-spring.xml spring: profiles: active: dev 第四步:创建TutorialController package com.zbbmeta.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import java.util.Objects; /** * @author springboot * @description: TODO */ @RestController @RequestMapping("/api") public class TutorialController { private static final Logger log = LoggerFactory.getLogger(TutorialController.class); /** * 根据ID查询Tutorial * @param id * @return */ @GetMapping("/tutorials/{id}") public void getTutorialById(@PathVariable("id") long id) { log.trace("trace..."); log.debug("debug..."); log.info("info..."); log.warn("warn..."); log.error("error..."); } } 第五步:创建启动类 package com.zbbmeta; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author springboot * @description: TODO */ @SpringBootApplication public class LogbackDemoApplication { public static void main(String[] args) { SpringApplication.run(LogbackDemoApplication.class,args); } } 启动项目,访问地址:http://localhost:8999/api/tutorials/1 可以看到控制台已经开始输出日志信息。 修改application.yml文件中的开发模式为pro,重启项目这日志输出到了文件中。 ...

    2023-12-22 257
  • Java8 reduce操作详解

    什么是reduce Java8 中有两大最为重要的改变,其一是 Lambda 表达式,另一个就是 Stream API 了。 Stream 是 Java8 中处理集合的关键抽象概念,它将数据源流化后,可以执行非常复杂的查找、过滤和映射数据、排序、切片、聚合统计等操作。操作之后会产生一个新的流,而数据源则不会发生改变。 在使用 Stream 操作的过程中,往往有三个步骤, 1. 创建Stream 从一个数据源(集合,数组)中,新建一个 Stream 流。 2. 中间操作 一个中间操作链,对 Stream 流的数据进行处理。比如查找、过滤、映射转换等。 3. 终止操作 一个终止操作,执行中间操作链,并产生结果。常用的终止操作有 forearch、collect、match、count、min、max、reduce 等。 其中本文主要讲解的 reduct 操作就属于是 Stream 流操作中的终止操作。 reduce 操作是一种通用的归约操作,它可以实现从 Stream 中生成一个值,其生成的值不是随意的,而是根据指定的计算模型。 比如终止操作中提到 count、min 和 max 方法,因为常用而被纳入标准库中。事实上这些方法都是一种 reduce 操作。 本文大纲如下, reduce 操作三要素 为了方便大家理解 reduce (规约)操作,先给大家演示一下 reduce 操作的相关代码示例, List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); int result = numbers .stream() .reduce(0, (subtotal, element) -> subtotal + element); assertThat(result).isEqualTo(21); 可以看到,我们的 reduce 操作接受了三个参数,返回了一个 int 基本类型。 在 Stream API 中,提供了三个 reduct 操作方法,根据参数不同进行区分。 对应上方代码示例,也就是使用了接受两个参数的 reduce 方法,但其实接受两个参数的 reduce 方法的代码逻辑是和接受三个参数的 reduce 方法是一致的。通过上方截图可以看出。 所以这里,我就直接给大家介绍下 reduce 操作的三个参数分别有什么作用即可。 identiy 参数 identiy(初始值)是 reduce 操作的初始值,也就是当元素集合为空时的默认结果。对应上方代码示例,也就是说 reduce 操作的初始值是 0。 accumulator 参数 accumulator(累加器)是一个函数,它接受两个参数,reduce 操作的部分元素和元素集合中的下一个元素。它返回一个新的部分元素。在这个例子中,累加器是一个 lambda 表达式,它将集合中两个整数相加并返回一个整数:(a, b) -> a + b。 combiner 参数 combiner(组合器)是一个函数,它用于在 reduce 操作被并行化或者当累加器的参数类型和实现类型不匹配时,将 reduce 操作的部分结果进行组合。在上面代码示例中,我们不需要使用组合器,因为上面我们的 reduce 操作不需要并行,而且累加器的参数类型和实现类型都是 Integer。 为了方便大家理解 reduce 操作的内部逻辑,我给大家绘制了上面代码示例的执行示意图,如下, 如何使用 reduce 操作 为了更好地理解初始值,累加器和组合器的功能,让我们看一些基本的例子。 使用 reduce 查询整数集合的最小值 // 创建一个整数集合 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); // 找出集合中的最小值 Integer min = numbers.stream().reduce((integer, integer2) -> { if (integer < integer2) { return integer; } else { return integer2; } }).get(); // 输出结果 System.out.println(min); // 1 在这个例子中,我们使用了一个参数的 reduce 操作,它接受一个累加器函数。累加器函数会返回集合两个元素中,较小的元素。 最终我们就可以找出集合中最小值 1。 使用 reduce 操作拼接字符串列表 我们可以对一个字符串列表使用 reduce 操作,将它们拼接成一个单一的字符串: // 创建一个字符串列表 List<String> letters = Arrays.asList ("a", "b", "c", "d", "e"); // 使用 reduce 操作拼接字符串列表 String result = letters .stream () .reduce ("", (partialString, element) -> partialString + element); // 输出结果 System.out.println (result); // abcde 在这个例子中,我们将初始值设为 “”,累加器函数设为 (a, b) -> a + b,它表示将两个字符串拼接起来。 我们可以看到,reduce 操作将累加器函数反复应用到列表中的每个元素上,得到最终的结果 abcde。 使用并行流计算整数列表的总和 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5,6); // 使用并行流和 reduce() 方法计算整数列表的总和 int result = numbers.parallelStream() .reduce(0, (a, b) -> a + b, Integer::sum); // 输出结果 System.out.println(result); // 21 在这个例子中,我们使用 parallelStream() 方法将列表转换为并行流,再使用 reduce() 方法对整数列表进行 reduce 操作,并使用 Integer::sum 作为合并函数 combiner,将并行计算的结果合并。 使用并行流的好处能够充分利用多核 CPU 的优势,使用多线程加快对集合数据的处理速度。 不过并行流也不是任何时候都可以使用的,并行流执行过程中实际按照多线程执行,多线程编程有的问题,并行流都有。 比如多线程的线程安全,执行顺序等问题,并行流都是有的。这一点需要大家注意。 最后聊两句 本文介绍了 Java8 Stream 流中,reduce 操作的相关概念和接收参数,包含初始值,累加器和组合器,最后介绍了 reduce 操作如何使用,希望大家喜欢。 ...

    2023-12-22 223
  • 什么是缓存,策略有哪些?

    什么是缓存? 缓存就像是一个超快速的存储区域,保存了计算机或手机经常使用的内容的副本,这样可以在不访问较慢的主存储器的情况下快速获取。 一个现实中的例子可以是,每当我们购买杂货时,通常会倾向于大量购买,这样可以让杂货多存放一段时间,避免频繁去市场购买,这其实就是将杂货缓存在我们附近,而不是每次都从市场购买。 在系统设计中,如果缓存得当,它可以显著提升系统的性能。 缓存策略取决于数据访问模式,即数据是如何读取或写入的。 例如: 系统是读取密集型还是写入密集型? 系统是否需要高一致性? 等等…… 因此,选择正确的写入缓存策略非常关键,下面是一些不同的缓存策略: 1. 缓存旁路(懒加载) 在这种设置中,应用程序缓存被分离出来,应用程序显式地与缓存和数据库一起工作。 这是一种技术,应用程序代码负责管理缓存。 当需要时,应用程序会将数据显式加载到缓存中,而缓存不会主动参与数据获取。 该图示了其工作原理。 使用场景: 适用于读取密集型系统,Redis 或 Memcached 非常受欢迎,我曾经在缓存旁路设置中使用过 Redis 以及 Mongo-db,效果非常显著。 这种读取技术可以与诸如写入旁路缓存之类的数据写入技术相结合,我接下来会解释。 优点: 灵活性:允许选择性缓存特定数据。 控制:应用程序控制数据何时加载到缓存中。 缺点: 提供过期数据:可能会提供过期数据,但如果我们实现了缓存的TTL(生存时间),则可以避免这种情况。 2. 写入旁路 跳过缓存,直接将数据写入数据库,并在读取用户请求的数据时更新缓存。 使用场景: 写入旁路可以与读取通过结合,对于数据写入一次,读取频率较低或几乎不读取的情况下提供良好的性能,例如实时日志或聊天室消息。 同样,这种模式也可以与缓存旁路结合使用。 3. 读取穿透缓存 读取穿透缓存是一种策略,当发生缓存未命中时,缓存会自动从底层数据源检索数据并填充自身。 这种技术与应用程序的数据访问层无缝集成,确保缓存与数据源保持同步。 使用场景、优点和缺点: 读取穿透缓存适用于读取密集的工作负载,当同一数据被多次请求时,例如,一个新博客。 缺点是,当首次请求数据时,总是会导致缓存未命中,并造成额外的数据加载开销。 4. 写入穿透缓存 写入穿透缓存是一种策略,其中写操作同时应用于缓存和底层数据源。 这确保了缓存和数据源保持同步,但与写入后缓存相比可能会引入额外的延迟,它同步应用更新。 使用场景、优点和缺点: 当与读取穿透缓存结合时,写入穿透缓存可以保证每次读取和写入的数据一致性。 但它会增加写操作的额外开销,因为每次写入都需要两次写入操作(缓存和数据库)。 它以异步方式应用更新。 5. 写入后缓存 写入后缓存,也称为写回缓存,涉及在写操作发生时延迟对数据源的更新。 系统不会立即更新底层存储,而是首先更新缓存,然后异步将更改传播到数据源。 使用场景、优点和缺点: 写回缓存提高了写入性能,非常适用于写入密集型任务。 当与读取穿透结合时,适用于混合工作负载,确保最近的数据可用。 ...

    2023-12-22 215
  • c++零基础怎么学

    C++ 是一种通用的、面向对象的编程语言,可以用于开发操作系统、游戏、图形用户界面、后端、高性能系统应用程序、以及各种嵌入式设备固件。 它是世界上最流行的编程语言之一,给程序员提供了对系统资源和内存的高度控制,以用于开发运行在多个平台上的应用程序,如服务器、个人计算机、基于云的系统和移动设备等。 学习 C++ 可以帮助你进入计算机游戏、高端计算项目的软件工程、加密货币挖掘程序以及开发运行在移动设备上的操作系统和其他软件等领域。 C++ 历史简介 C++ 是由丹麦计算机科学家 Bjarne Stroustrup 创建、设计和开发的。设计之初,Stroustrup 希望创建一种类似于 C 的灵活和动态的语言,但具有更多的功能。 最初被称为“带类的C”,1983 年改名为C++,大致意思是“比 C 多一点”的意思。 国际标准化组织的 C++ 联合技术委员会在 1998 年至 2017 年间对 C++ 进行了五次升级。C++20 也已发布。 C 与 C++ 的区别 C++ 是 C 的演变,虽然它们有一些相似之处,但现在它们已经有了很大的不同。虽然 C 广泛被使用,但它不支持 C++ 所支持的抽象、泛型编程和面向对象编程。 如果你想做一些需要大量代码的庞大工程,那么你就需要能够以非常高级的抽象方式思考。这是 C++ 所擅长的:支持这些高级抽象。 抽象层指的是观察或编程系统的复杂程度。较低级别的抽象具有更多的细节,而高级别的抽象可以包含整个系统。 C 是一种过程化语言;其代码由直接告诉计算机或其组件以逻辑步骤完成任务的指令组成。C++ 也可以做到这一点,但它还支持类和面向对象等高级特性,这使得程序员可以创建包含数据和函数的“对象”。这种方法的优势在于,软件对象执行速度更快,比过程命令更容易执行,面向对象编程使得代码更容易修改、维护和调试。 学习 C++ 起步步骤 由于 C++ 很受欢迎,对于初学者来说,有许多资源可供选择,包括在线教程、网站和书籍。 在决定学习 C++ 或任何计算机语言时,初学者应该对自己的专业目标有一定的设想。 大多数使用 C++ 的人都是专业软件工程师。这是一个重要的标志,特别是对于最近从大学毕业或具有计算机科学背景的人来说。计算机科学家研究更多的是理论性的课题,而专业软件工程师必须处理解决技术问题的细节相关,而 C++ 非常适合这种工作。 如果你选择使用 C++ 是因为你面临着非常苛刻的情况。比如你在开发游戏,性能绝对是关键因素。或者你可能在开发某种系统软件,性能同样很关键。靠近机器的底层硬件的操纵能力也很重要,C++ 具有这种能力。 开始学习 C++ 之前 虽然任何人都可以学习 C++ 编程,但具有一些基础的编程经验可能会有所帮助。对于 C++ 和 JavaScript、Python 等语言常见的语句、for 循环、while 循环和其他代码结构等基本计算机术语的了解会对快速学习很有用。 对于初学者来说,我认为理解语法,能够编写一个简单的程序,然后打印一些内容,并能够解释每行代码都在做什么,以及了解数据类型这些都很有帮助。 学习资源和参考资料 但是如果你没有这些基本技能怎么办?不要害怕,目前在互联网上有非常多资源可以帮助你入门。 比如 W3Schools.com 和 Codecademy 等入门教程网站。 第一步:学习语法并上手一些教程 语法是编程语言的表达文法,也是所有代码的基础。语法还定义了代码的组成和理解方式。 以下是一些例子,创建一个简单的代码行来打印文本 “Hello World”: #include <iostream> using namespace std; // main () 程序开始执行的地方 Int main () { cout << “Hello World\n” ; // 输出到屏幕 Hello World return 0; } #include <iostream> 这是一个头文件库,将其中包含的特性导入程序。该命令要求程序从一个名为 <iostream> 的文件中复制内容,iostream 代表输入和输出流。 Using namespace std 声明将引用标准库(std)中的对象和变量名称,应用时经常缩写为关键字 std 和操作符 ::。 int main( ) 指定一个主函数。函数是 C++ 程序的重要部分,因为它们定义了代码中的一个动作。包含在这些大括号 { } 中的命令将被执行。 cout(读作see-out)是一个定义输出的对象,可输出代码中的一串文字。利用操作符 << 可串行输出多个字符串。\n 将使后边的文本输出换行。 return 0 指示程序不会返回任何内容,上面的文本字符串将是唯一的输出。 << 是一个命名对象的操作符而 ;(分号)作为代码行的结束符。 第二步:练习基础知识 掌握语法后,一个初学者应该了解语言的更多方面。比如: 函数:函数是一组语句,共同完成一个任务。每个 C++ 程序至少有一个函数– main 函数。 数组:数组是一种数据结构,用于存储相同类型元素的数据集合,大小固定,而且数据排列顺序。 字符串:字符串是以空字符‘\0’结尾的字符的一维数组。 指针:指针一种变量,其值为其他变量地址。指针有助于更灵活地执行 C++ 任务,有些任务非常依赖指针来完成。 引用:引用是变量的别名,是已经存在的变量的另一个名称。如果引用已通过变量初始化,那么变量的名称和引用名称可以互换使用。 类和对象:类是 C++ 的一个关键特性,通过将数据表示和操作数据的方法结合成一个包来指定对象的形式。类提供了用于创建对象的蓝图或者抽象概念。 多态性:多态性意味着具有多种形式。在 C++ 中,形象地理解指的是调用一个函数,但执行的却是不同的函数,具体取决于调用函数的对象类型。 第三步:将知识付诸实践 学习了一些 C++ 编程技能后,就应该将它们应用到实践中了。其中一种方法是通过开展项目来了解语言的各个方面是如何结合在一起的。有许多网上的开源项目可以提供想法,比如编写简单的游戏或构建银行应用程序。 此外,还有许多在线社区专门讨论和应用 C++,因此你可以与业余爱好者、兼职程序员或专业人士联系。 第四步:深入学习高级 C++ 中级和高级 C++ 编程技能建立在基础知识之上,同时为程序员提供了一系列辅助工具。在中级水平时,程序员需要理解引用和指针的工作原理。支持强大的 C++ 函数的其他核心概念包括对象生命周期和多态性。对这些概念的深刻理解以及如何创建和使用库函数将使程序员能够学习高级技术。 在高阶水平,优秀的 C++ 程序员可以摆脱面向对象编程,利用更通用的泛型编程。面向对象编程并没有错,仍然有数以百万计的程序员在使用这些编程思想,但是优秀的程序员会将他们的技能提升到一个新的水平。 已经进阶的程序员正在使用泛型编程,并且使用编译时来增强代码的运行时控制。高阶开发人员正在编写通用的代码,以便可以轻松地适应多个平台。 C++ 与 Java,有何不同? C++ 和 Java 经常被认为是竞争关系的两种编程语言,但它们用于不同类型的编程。Java 使用虚拟机——模仿硬件的软件——来执行各种功能,因此无需重新编译的情况下,它开发的程序就可在多个平台上直接运行,比如 Windows、Linux、Mac、Android 和 Apple iOS 等。 C++ 也是跨平台的,但它需要为每个系统单独编译一个程序才能运行。C++ 的优势在于它能够编写内存高效的应用程序,这些应用程序直接操作内存地址也可能带来安全隐患。 现实是,互联网时代更看重通用兼容性,这使得 Java 非常受欢迎。而专注在内存和性能效率时的,就是 C++ 的优点所在。 如何成功学习 C++ 学好语法。 掌握基础知识,如函数、数组、字符串、类等。 利用在线教程、书籍和讲座等资源。 坚持不懈。编码和许多其他技能一样,需要时间学习,所以犯错误很正常,不要害怕。 ...

    2023-12-22 233
  • 抖音直播间用户ID采集协议3.0

    本软件暴力 仅供学习研究  请勿用于任何非法操作  否则一切后果与作者无关 ! ! ! 软件新增功能:用户ID数据实时一键导出 用户ID名称及消息对应一键数据导出 ...

    2023-12-19 242
  • HTTP报文格式详解

    HTTP报文分为请求报文和响应报文来说明。 请求报文 请求行:包含请求方法、请求目标(URL或URI)和HTTP协议版本。 请求头部:包含关于请求的附加信息,如Host、User-Agent、Content-Type等。 空行:请求头部和请求体之间用空行分隔。 请求体:可选,包含请求的数据,通常用于POST请求等需要传输数据的情况。 响应报文 状态行:包含HTTP协议版本、状态码和状态信息。 响应头部:包含关于响应的附加信息,如Content-Type、Content-Length等。 空行:响应头部和响应体之间用空行分隔。 响应体:包含响应的数据,通常是服务器返回的HTML、JSON等内容。 ...

    2023-12-18 283
  • Windows【自动配置IPv4地址】的问题

    问题描述: Windows电脑的网卡明明已经配置了静态的IP地址,但是还会出现自动配置IPv4地址的情况。 解决方法: 这个问题大部分是地址冲突导致的,还有一种可能就是网卡默认配置。 地址冲突解决办法:修改本机电脑的IP地址,或者找到冲突的设备修改它的IP。 网卡默认配置解决方法:管理员运行CMD,输入netsh winsock reset catalog按回车、输入netsh int ip reset reset.log按回车,然后就能配置地址、掩码、网关了。 小知识: 【169.254.×.×】这个是广播地址不是正常获取到的IP地址。 ...

    2023-11-19 280
  • Linux认证 | RHCE是中级还是高级,含金量如何?

    红帽认证是一个完善的认证体系,分为三个等级:初级、中级和高级。 其中,RHCE认证是中级认证。 这意味着,获得RHCE认证需要先通过初级认证,即Red Hat Certified System Administrator(RHCSA)认证。 通过RHCE认证后,可以进一步挑战高级认证,即Red Hat Certified Architect(RHCA)认证。 下面我们就来了解一下RHCE认证吧。 RHCE是中级还是高级 红帽认证分为了三个等级 ★ 红帽认证系统管理员(RHCSA): 是红帽的初级认证,它证明你完全可以对Linux系统进行基础管理和维护工作。如:创建用户、管理磁盘、文件权限等。 ★ 红帽认证工程师(RHCE): 是红帽Linux的中级水平认证,它证明你具有红帽企业Linux系统高级系统管理员所需的知识、技能和能力。 既能对服务器进行基础管理,还可以配置注入WEB、邮件、DNS等服务器,并且实现其安全运行。 ★ 红帽认证架构师(RHCA): 是红帽Linux最高级别认证,也是公认的更受欢迎、更成熟的认证。 它主要是面向那些负责部署和管理大型企业环境中众多系统的高级Linux系统管理员提供深入的实际操作培训。 RHCE证书含金量如何 一、市场需求:Linux人才需求持续升温 随着Linux系统的普及,企业对Linux人才的需求也在不断增长。 据相关数据显示,我国每年至少会有60万的缺口,而红帽认证出来的网络工程师工作并不难找。 此外,许多企业和机构也纷纷采用Linux系统,这也进一步加剧了对Linux人才的需求。 因此,拥有RHCE证书将为你在就业市场上增加不少竞争力。 二、就业前景:高薪就业,职业发展前景广阔 拥有RHCE证书的求职者可以从事Linux系统管理、网络管理、系统集成等方面的工作。 这些职位不仅薪资待遇优厚,而且职业发展前景也十分广阔。 随着工作经验和技能的提升,你可以逐步晋升到更高的职位,例如系统架构师、项目经理等。 三、考试难度:通过率维持在40—60%,物以稀为贵 RHCE认证的考试难度较大,通过率通常维持在40—60%。 这是因为红帽认证的考试全部都是上机操作,配置试验考试,没有题库的帮助。 因此,通过RHCE认证的考生不仅需要具备扎实的理论基础,还需要具备熟练的操作技能和解决问题的能力。 好了,以上就是给大家介绍的RHCE是中级还是高级以及含金量如何的攻略。 ...

    2023-11-14 312
  • 什么是企业级防火墙

    企业级防火墙是专为满足大型组织的需求而设计的防火墙。 与为小型办公室或家庭网络设计的基本防火墙不同,企业级防火墙具有更高级的功能和更大的处理能力,可以处理大量的网络流量,同时提供更深入的安全检查。 企业级防火墙通常包括以下功能: 入侵防御系统(IDS)和入侵防止系统(IPS):这些系统可以检测并阻止恶意活动和攻击。 虚拟私人网络(VPN):企业级防火墙通常包括VPN支持,允许远程用户安全地访问企业网络。 深度包检查:这是一种防火墙技术,可以检查网络流量的每个数据包的内容,以阻止恶意软件和攻击。 高可用性和负载均衡:企业级防火墙通常支持这些功能,以确保网络的持续可用性和性能。 集中管理和报告:这些功能使网络管理员能够更容易地管理防火墙,监控网络活动,并在发生安全事件时接收通知。 ...

    2023-11-13 299
  • 企业级防火墙的工作原理是什么

    企业级防火墙的工作原理,你就记住这几个关键字: 企业级防火墙通过访问控制和安全策略来管理网络流量。访问控制列表(ACL)是其中的一种常见机制,根据源地址、目标地址、端口号等因素,允许或禁止数据的传输。安全策略则定义了企业对网络流量的整体管理方针,规定了允许和禁止的活动。 虚拟专用网络是企业级防火墙中的一项关键功能。通过使用加密通道,VPN使得远程用户可以安全地访问企业网络。这对于分布式团队和远程办公的企业来说尤为重要,保障了远程用户的数据传输的安全性。 企业级防火墙具备深度数据包检查的高级功能。这意味着防火墙不仅仅停留在简单的报文头部检查,还能深入分析数据包的内容,以便更全面地识别和阻止潜在的威胁。这种深度的检查使得防火墙更加智能化和适应性强。 一些企业级防火墙集成了入侵检测和防御系统。这意味着防火墙不仅仅阻止已知的威胁,还能主动监测网络中的异常活动,及时响应和防范潜在的攻击。 企业级防火墙记录网络流量和安全事件的日志。这些日志对于审计、分析和识别潜在的安全威胁非常重要。通过仔细分析日志,企业可以更好地了解网络活动,及时发现异常并采取相应措施。 保护网络免受病毒、蠕虫和其他恶意软件的传播是企业级防火墙的重要任务之一。这通常包括实时的病毒扫描、恶意软件识别和隔离感染节点等功能,以确保网络的整体健康和安全。 ...

    2023-11-13 282
  • 企业级防火墙的类型有哪些

    企业级防火墙主要有以下几种类型: 硬件防火墙 这种防火墙是一种物理设备,通常安装在网络的边缘,作为网络和外部世界之间的主要防线。 硬件防火墙通常具有高性能,可以处理大量的网络流量,同时提供各种高级安全功能。 软件防火墙 这种防火墙是一种可以安装在服务器或其他网络设备上的软件。 软件防火墙提供了与硬件防火墙相同的基本功能,但通常更易于定制和管理。 虚拟防火墙 这种防火墙是一种软件防火墙,可以在虚拟化环境中运行,如云计算平台。 虚拟防火墙可以提供与硬件和软件防火墙相同的功能,同时还提供了更高的灵活性和可扩展性。 ...

    2023-11-13 321
  • ping和telnet有什么区别

    Ping和Telnet有什么区别 ping 是ICMP协议,只包含控制信息没有端口;telnet是TCP协议,有端口能承载数据; 不能telnet并不代表不能ping, 这是两种不同的数据包, 防火墙可以设置哪种数据包可以通过; 能telnet通,但是不能ping通,有可能是对方主机关闭了ping回显或者是对方防火墙阻止了ping发送的数据包; 如果别人不能telnet本机,最简单的测试办法是:telnet 127.0.0.1 如果失败说明本机的telnet服务没有开启,如果成功说明本机防火墙做了限制; Ping和Telnet的界面 下边这张图是使用了ping和telnet两个命令的效果图,可以看出使用ping更多返回的是对方机器的数据包,延时这类信息。 而使用telnet则是尝试远程连接对方的服务,所以两者其实还是有很明显的本质区别。 小结 ping是icmp探查消息,用于确定两个ip端点的网络层导通性。 telnet是一种远程登录软件工具,是运行在tcp层,使用23端口。 一般计算机部署的时候都会关闭掉telnet端口,以保证安全性,如果真的需要进行远程连接的话,建议使用ssh的方式去访问。 ...

    2023-11-13 297
  • HTTP和HTTPS的区别

    HTTPS是HTTP的安全版本,两者都用于在客户端和服务器之间传输数据,但HTTPS添加了加密和安全性层,以保护数据的机密性和完整性。 区别: 安全性: HTTP:HTTP是一种不安全的协议,数据在传输过程中以明文形式传输,容易受到窃听和篡改的风险。 HTTPS:HTTPS通过使用加密机制(通常是TLS/SSL)来保护数据的机密性,使数据在传输过程中加密,从而提供更高的安全性。 端口: HTTP:HTTP默认使用端口80进行通信。 HTTPS:HTTPS默认使用端口443进行通信。 加密: HTTP:HTTP不提供加密,数据可以在网络上传输时被窃听。 HTTPS:HTTPS使用TLS/SSL协议进行数据加密和解密,确保数据在传输过程中的保密性。 证书: HTTP:HTTP不涉及数字证书的使用。 HTTPS:HTTPS需要服务器获得数字证书,并由权威的证书颁发机构(CA)签发,以验证服务器的身份。客户端可以使用证书来确保它们正在连接到合法的服务器。 认证和身份验证: HTTP:HTTP不提供身份验证机制,任何人都可以发送HTTP请求。 HTTPS:HTTPS提供了对服务器和(可选)客户端的身份验证,确保双方的合法性。 SEO(搜索引擎优化): HTTP:搜索引擎可能更喜欢使用HTTPS的网站,因为它们提供了更高的安全性,可以影响搜索排名。 ...

    2023-11-11 312
  • HTTP和TCP的关系和区别

    关系: HTTP建立在TCP之上:HTTP是一个应用层协议,而TCP是传输层协议。HTTP通常使用TCP作为它的传输层协议,以在网络上传输数据。HTTP与TCP之间的关系可以类比为在实体之上建立一个通信通道。 HTTP利用TCP的可靠性:TCP提供了可靠的、面向连接的数据传输。HTTP利用TCP的可靠性来确保数据的正确传递,包括数据的分段和重新组装、错误检测和重传等。 区别: 层次:TCP是传输层协议,负责在两台计算机之间建立连接、可靠地传输数据流,以及处理数据分段和重传等传输细节。HTTP是应用层协议,负责定义数据的格式和如何在客户端和服务器之间传输数据。 功能:TCP关注于数据传输的可靠性和流控制,而HTTP关注于定义如何呈现和传输文档、图像、视频等内容。HTTP通过请求-响应模型允许客户端请求网络资源,并服务器响应这些请求。 端口:TCP使用端口来标识不同的应用程序或服务,允许多个不同的应用程序在同一台计算机上共享网络连接。HTTP默认使用TCP端口80(HTTP)或443(HTTPS)。 通信模式:TCP是一种点对点的通信协议,即两台计算机之间的通信。HTTP是一种客户端-服务器通信模式,客户端发送请求,服务器返回响应。 状态:TCP是无状态的协议,它不保留关于连接的持久状态信息。HTTP也是无状态的,每个HTTP请求和响应之间是相互独立的,不保留客户端之间的状态。 ...

    2023-11-11 274
  • 常见协议端口号

    HTTP:80(HTTP)和443(HTTPS)。 80端口用于HTTP通信,通常是未加密的。 443端口用于HTTPS通信,加密的HTTP通信。 FTP:21(控制连接)和20(数据连接)。 21端口用于FTP的控制连接,用于命令和控制操作。 20端口用于FTP的数据连接,用于实际文件传输。 SSH:22端口用于安全的远程登录和文件传输。 SMTP:25端口用于发送电子邮件。 POP3:110端口用于接收电子邮件。 IMAP:143端口也用于接收电子邮件,但提供了更多的功能和灵活性。 DNS:53端口用于域名解析,将域名映射到IP地址。 Telnet:23端口用于远程终端连接,通常是明文传输。 SMTPS:465端口用于通过加密通信的SMTP。 SNMP:161(SNMP)和162(SNMP Trap)。 161端口用于SNMP通信,允许管理和监视网络设备。 162端口用于SNMP陷阱,用于通知管理站点的事件。 HTTP Proxy:3128(常见代理端口)端口通常用于HTTP代理服务器。 RDP:3389端口用于远程桌面连接。 ...

    2023-11-11 252
  • 美国司法部称,两名南加州男子在暗网上销售了12.4万个芬太尼药丸

    两名南加州男子因涉嫌在暗网上销售提供含有芬太尼的药丸和甲基苯丙胺而面临数十年甚至终身监禁的联邦监禁。 美国司法部在一份新闻稿中表示,来自洛杉矶南部38岁的奥马尔·纳维亚(Omar Navia)和来自加登格罗夫27岁的阿丹·鲁伊斯(Adan Ruiz)被指控提供“含有芬太尼和其他麻醉品的假冒M30羟考酮药丸”在暗网上出售。 他们上个月被起诉,并于周四被捕。美国司法部表示,两人均对“串谋分发和持有并意图分发芬太尼和甲基苯丙胺”的指控表示不认罪。鲁伊斯还面临分销芬太尼的额外指控。 据检察官称,纳维亚和鲁伊斯充当贩毒组织的供应商,在暗网上并通过“Session”和“Signal”等加密消息应用程序进行交易。他们与两名已经认罪的人合作:38岁的休斯顿人拉吉夫·斯里尼瓦桑(Rajiv Srinivasan)和25岁的威斯敏斯特人迈克尔·塔(Michael Ta),他们去年因相关指控被联邦大陪审团起诉。检察官称,他们今年认罪,预计明年被判刑。 美国司法部表示,斯里尼瓦桑和塔均承认从事贩毒活动,并“承认他们的贩毒活动导致三人死亡,并且他们向另外两人出售了含有芬太尼的药片,两人很快就因吸毒过量死亡”。 据称,斯里尼瓦桑和塔从纳维亚和鲁伊斯那里采购毒品,然后使用在各个暗网市场上运营的供应商帐户“redlightlabs”将毒品出售给全美国50个州的买家。 调查人员发现的文件显示,该团伙据称在2022年销售了近124,000粒芬太尼药丸,以及20磅冰毒和“根据起诉书,少量芬太尼粉末、黑焦油海洛因和可卡因”。 纳维亚和鲁伊斯被关押,不得保释。他们的审判定于12月26日开始。 对于共谋罪,他们可能被判处终身监禁联邦监狱,而鲁伊斯的分配罪可能被判处最高20年徒刑。 据称,他们作为毒品供应商的报酬是通过各种货币渠道获得的。这些渠道包括加密货币、通过加密货币交易所传输的资金以及Apple Cash、CashApp、PayPal、Venmo和Zelle等移动支付​​应用程序。斯里尼瓦桑和塔将于明年在美国圣安娜地方法院法官戴维·卡特(David O. Carter)面前接受宣判。 斯里尼瓦桑和塔维护的一份电子文档记录了交付给全美国约1400个独特客户的约3800笔药品交易。该记录反映了2022年5月至11月的销售情况,包括123,688颗芬太尼药丸、略低于20磅的甲基苯丙胺以及少量的芬太尼粉末、黑焦油海洛因和可卡因。 对纳维亚和鲁伊斯的起诉是持续打击贩毒工作的一部分。由FBI管理的阿片类暗网犯罪联合执法小组(JCODE)为打击暗网供应商提供了大力帮助。FBI领导的团队自2018年成立以来,已逮捕了300多名在暗网上活动的毒贩,没收了超过4200万美元的毒品相关资金,缴获了800多公斤毒品,并查获了约145支枪支。这些统计数据可以在美国司法部新闻稿中找到。...

    2023-11-11 278
  • 塞尔维亚人承认经营暗网市场Monopoly Market,赚取了1800万美元

    根据美国司法部DoJ 周三发布的一份声明,一名 33 岁的塞尔维亚男子承认在暗网上经营一个名为“垄断市场Monopoly Market的贩毒平台,该市场通过出售超过 30 公斤的冰毒和大量其他毒品来换取各种加密货币,从而赚取了 1800 万美元。 33 岁的 Milomir Desnica 据称从 2019 年底开始启动并运营暗网市场 Monopoly Market,根据法庭记录,该市场是一个典型的网上贩毒商店,用户可以在其中浏览并购买大麻、摇头丸、阿片类药物、处方药和兴奋剂等类别的毒品。 客户被要求用加密货币(例如比特币或门罗币)从个体供应商那里购买药物,这些供应商对每笔销售都收取佣金。Milomir Desnica 的职责包括批准想要在暗网市场成为“供应商”的毒品供应商。 Desnica正在哥伦比亚特区受审,定于明年2月宣判。他可能面临最高终身监禁和经济处罚。 警方使用加密货币购买毒品并找到暗网市场的经营者 2021 年,美国执法部门在Monopoly Market中向不同供应商提交订单,当局在Monopoly Market暗网市场上订购了 100 多克甲基苯丙胺。通过调查,FBI 确定Monopoly Market在全球范围内促成了价值超过 1800 万美元的毒品销售,其中包括向美国客户出售了超过 30 公斤的甲基苯丙胺。 2021 年 12 月,美国执法部门与德国和芬兰的外国执法合作伙伴协调,查获了托管“Monopoly Market”暗网市场的计算机服务器并将其下线。通过对被扣押的服务器的分析,执法部门确定了毒品销售记录、记录Monopoly Market(与Monopoly Market相关的在线论坛)上加密货币支付的财务记录、Monopoly Market运营者与供应商的通信记录、佣金付款发票等。通过对这些记录的广泛分析,Desnica被确定为大富翁的运营商。 尽管Monopoly Market试图混淆其轨迹,但联邦调查局随后能够使用比特币支付的供应商发票来追踪非法资金。 奥地利当局于 2021 年 11 月找到并逮捕了 Desnica,没收了他的房子、汽车、超过 18,000 欧元、866 美元的 Tether (USDT) 和超过 400 美元的 ETH。Desnica承认,他被扣押的资金与加密货币全部来自Monopoly Market的收益。 这次取缔行动是针对暗网市场采取的最大规模的执法行动之一,最终逮捕了 288 名供应商,超过了 2021 年取缔 DarkMarket 后逮捕的 150 名供应商和 2019 年取缔 Wall Street Market 后逮捕的 179 名商贩。 执法部门除了没收了超过 5340 万美元的现金和虚拟货币,还查获了 850 公斤毒品。 Desnica去年 11 月在奥地利被捕,2023 年 6 月 23 日,Desnica被从奥地利引渡到美国,面临贩毒指控。 据称,Desnica至少使用了两种加密货币兑换服务来洗钱其非法收益。检察官在 6 月份的一份声明中表示,他随后将加密货币出售给塞尔维亚的点对点交易员,以换取法定货币,以“清洗”自己的收入。...

    2023-11-11 248
  • 浅拷贝和深拷贝的区别

    浅拷贝 浅拷贝仅复制对象本身,而不会递归复制其内部包含的对象或数据结构。 对于复杂对象,如包含指针或引用的对象,浅拷贝会导致多个对象共享相同的内部数据。 浅拷贝通常是通过复制对象的成员变量来实现的,但对于内部指针或引用,只是复制了指针或引用本身,而不是它们引用的对象。 深拷贝 深拷贝会递归地复制对象本身及其内部的所有对象和数据结构,确保每个复制的对象都是全新的,没有共享内部数据。 对于复杂对象,深拷贝可以消除共享数据的问题,每个对象都有自己的拷贝。 深拷贝需要在拷贝过程中为每个内部对象或数据结构创建全新的副本,通常需要更多的时间和内存。 总结 使用浅拷贝时,多个对象可能会出现数据不一致的问题,因为它们共享相同的内部数据。 深拷贝确保了每个对象都是独立的,但可能需要更多的资源。 ...

    2023-11-10 270
  • 索引失效场景有哪些

    使用函数或运算符处理列 当在查询条件中对列进行函数调用或进行运算时,索引通常会失效。 例如,WHERE DATE_FORMAT(column, '%Y-%m-%d') = '2023-11-10',这种情况下,无法使用列上的索引。 使用通配符前缀 当在查询条件中使用通配符前缀(如LIKE 'prefix%')时,通常无法使用索引。 使用OR条件 在WHERE子句中使用多个OR条件时,如果每个条件都没有适用的索引,那么索引可能会失效。 不等于条件 当使用不等于条件(!=或<>)时,索引通常会失效。 数据分布不均匀 如果索引列上的数据分布极不均匀,即某些值出现非常频繁,而其他值出现很少,索引可能会失效。这会导致查询优化器认为扫描整个表更快。 大数据表 当表非常大时,即使索引存在,查询优化器可能会选择执行全表扫描,因为扫描整个表可能比使用索引更快。 列数据类型不匹配 当查询条件中的列数据类型与索引列数据类型不匹配时,索引可能会失效。例如,对字符串列应用数值函数。 连接操作(JOIN) 在连接操作中,如果没有适用的索引来支持连接条件,索引可能会失效。 类型转换 当查询条件中的列需要进行类型转换以与索引列匹配时,索引通常会失效。 子查询 子查询可能会导致索引失效,尤其是当子查询结果集非常大时。 ...

    2023-11-10 247
  • b树与b+树的区别

    数据存储方式 B树:B树的每个节点既存储数据也存储索引。这意味着B树的非叶子节点既包含索引键也包含对应的数据。 B+树:B+树的非叶子节点仅存储索引键,而数据全部存储在叶子节点。B+树的所有叶子节点通过指针连接成一个有序链表,便于范围查询。 叶子节点关联性 B树:B树的叶子节点和非叶子节点没有直接关联,各自独立存在。 B+树:B+树的叶子节点之间通过链表相连,形成了一个有序的链表。这有助于范围查询,因为数据按顺序排列。 范围查询效率 B树:在B树上进行范围查询相对较慢,因为需要访问非叶子节点和叶子节点。 B+树:B+树在范围查询时非常高效,因为只需遍历叶子节点的链表。 非叶子节点的索引键 B树:非叶子节点的索引键可以是重复的,可能导致不必要的冗余数据。 B+树:B+树的非叶子节点的索引键一般是不重复的,确保了索引的唯一性。 叶子节点个数 B树:B树的叶子节点数量和数据记录数量相等。 B+树:B+树的叶子节点数量比数据记录数量多,因为叶子节点主要用于存储数据和维护链表,而非叶子节点用于索引。 B+树 B树 ...

    2023-11-10 242

联系我们

在线咨询:点击这里给我发消息

QQ交流群:KirinBlog

工作日:8:00-23:00,节假日休息

扫码关注