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

【2024秋招】2023-8-5-小红书-数据引擎团队后端开发提前批面经

1 面试官介绍

OLAP引擎,离线引擎,大数据分析中间件

2 自我介绍

缺点:

(1)面试官让重点介绍自己最在行的项目,我真的在自我介绍上扯了一些别的东西…

(2)在面试的时候因为想看简历屏幕在不断的切屏,被面试官提醒说系统会有记录…太频繁了会影响面评

(3)介绍了raft kv和rpc项目,但是做了扩展,但是面试官是让说一下整体的架构的,没有让进行细节处理。

3 raft kv项目

3.1 简述raft的原理

Raft是一种为了管理复制日志而设计的分布式一致性算法,它的目标是提供一个更容易理解和实现的替代方案,用于替换难以理解和正确实现的Paxos算法。Raft算法将复杂的分布式一致性问题分解为几个关键元素,并提供了一种解决这些元素的方法。

gpt4的版本:

Raft的关键元素包括领导人选举、日志复制、安全性和成员变更。以下是这些元素的简述:

  1. 领导人选举:Raft算法中的所有节点都是平等的,并可以担任领导者(也称为主节点)或者跟随者(也称为从节点)。当一个领导者节点宕机或与集群失去联系时,会触发领导者选举。所有的节点都会定期发送心跳消息,如果在一段时间内(称为选且超时期)没有接收到领导者的心跳消息,跟随者节点就会开始一轮新的选举。节点会投票选举新的领导者,获得半数以上投票的节点成为新的领导者。

  2. 日志复制:日志是分布式系统中重要的一部分,所有的变更都会记录在日志中。在Raft算法中,领导者节点负责管理复制日志。当领导者接收到客户端的请求后,会将请求作为新的日志条目添加到它的日志中,并向其他的跟随者节点复制该日志条目。当领导者收到多数节点的确认后,该日志条目就被认为已经提交,领导者会执行该日志条目,然后将结果返回给客户端。

  3. 安全性:Raft算法确保了系统在发生故障或网络分区的情况下仍然能够保持一致性。Raft通过在领导者选举和日志复制过程中实施一些限制来确保系统的安全性,例如,只有拥有最新日志的节点才能被选举为领导者,领导者在复制日志时必须包括其上一个日志条目的索引和任期号等。

  4. 持久化存储:在Raft协议中,所有节点都必须持久化存储一些关键的信息,例如当前的任期号(用于领导人选举)、已投票的候选人(用于避免在一个任期中多次投票)、日志条目(用于记录所有的操作和状态变更)等。持久化存储的目的是在发生节点故障和重新启动时,节点可以从持久化存储中恢复数据,继续参与集群的运作。

  5. 快照机制:快照是Raft协议用于处理日志可能无限增长的问题的一个机制。当日志的大小增长到一定程度时,可以通过创建一个快照(即对当前系统状态的完整拷贝),并删除早于这个快照的所有日志条目来减少日志的大小。当节点故障并需要恢复时,可以直接使用快照恢复最近一次持久化的数据,能极大的缩短故障恢复时间。

Raft算法的设计目标是易于理解和实现,同时也能满足分布式系统的需求。

3.1.1 结合gpt4,我的简化版本,有助于快速让面试官知道项目的架构:

1 项目架构:有一个配置中心,实时生成配置,每一个新生成的配置文件都包含了哈希槽到某一个复制组的映射,然后还有若干个复制组,每一个复制组会定期从配置中心拉取配置文件到本地,然后开始将已经不属于自己管理的分片迁移到目标分片,当一个复制组迁移完所有分片并且接收到了所有分片后就会转换配置文件。

2 介绍raft的几个章节:这个项目基于raft共识算法做,能保证读写的强一致性。raft从leader选举、日志复制、持久化上、快照机制上能够保证这些,其中最重要的是leader选举、日志复制和持久化。

3 稍微详细介绍一下raft的各个部分:

3.1 raft的leader选举上,通过设置差异化的选举超时时间,大概率能在前几轮就选举出一个leader,新leader当选后会立即向从节点发送心跳,各个节点收到会改变自己为follower状态并且重置超时选举定时器;

3.2 选举成功后,就会进行日志复制操作,每次来一个新的put,append操作后都会将其转化为一条日志,并且将其传送给其他的节点,确保写的一致性;

3.3 同时,针对每一次的选举任期号、投票号以及日志变更操作,都会进行一次持久化,这样节点宕机重启后仍然能够根据日志进行恢复数据的操作,根据任期号和投票号可以继续加入集群中成为新的follower节点,避免出现两个leader

3.4 针对快照机制,各个节点每当数据达到一定长度的阈值后,就会对数据库中的kvMap进行一次持久化操作,存储完成后会截断一部分日志,故障恢复过程中加载快照能够极大的提高效率。

3.2 只要保证日志在多数节点就能保证一致性了嘛?

是的,只要保证日志在多数节点上一致,就可以保证系统的一致性。这是因为在Raft协议中,日志的复制是由领导者节点负责的,领导者节点接收到客户端的请求后,会先将请求记录到自己的日志中,然后复制到其他节点。当领导者收到大多数节点的确认后,这个操作就会被认为已经提交,并被应用到系统状态中。

这种机制确保了所有的节点都看到了相同的操作序列,达到了一致性。即使在领导者节点宕机的情况下,只要有一个新的领导者被选举出来,并且这个新领导者的日志包含了所有已经提交的日志条目,那么系统的一致性就可以得到保证。

但是需要注意的是,只有当日志条目在多数节点上一致,并且这些日志条目已经被提交时,才能保证一致性。如果一个日志条目只是被领导者节点记录,但还没有被复制到大多数节点,或者还没有被提交,那么这个日志条目的状态就是不确定的,不能保证一致性。

3.3 put,append请求发出到得到响应之前的大概流程

可能面试官只想听到简单版本的答案,比如是在没有分开写kv的情况下,客户端和一个raft集群的交互流程:

  • 客户端每次发送put,append请求都会自增seqId,这个id用于raft集群去重,保证操作的幂等性的。客户端会轮询raft的集群节点,当轮询到一个非leader节点时,会收到一个错误,然后再轮询下一个节点,直到这个节点是leader节点,轮询到这正确的leader后,leader会成功收取到这个节点,然后它不会立即执行这个操作,而是先把这个操作放到日志中作为一个日志项,并且leader的日志复制线程会在未来的某一个时间点将这个日志复制到其他的从节点,当大多数从节点接受了并且正确响应后leader节点才会执行这个命令,执行成功后再返回一个响应给客户端。

  • 客户端会通过哈希算法计算出put的key值存储于哪一个复制组,然后会从这个目标复制组中顺序选取一个raft的节点发送put请求,当被轮询的节点发现这个key不归自己管时会返回ErrWrongGroup,如果客户端接收到ErrWrongGroup状态码,它会觉得自己的配置有问题,于是去配置中心拉取最新的配置返回给客户端,客户端发送序列号不变的put请求到新的复制组,新目标复制组的节点可能会返回一些错误响应,比如可能会发现这个put的key正在迁移过程中时会返回ShardNotArrived状态码,此时客户端会等待一段时间重试直到分片到达,当发现自己不是leader时会响应一个ErrWrongLeader状态码给客户端,客户端会轮询该复制组的下一个节点直到找到正确的leader。客户端向正确的leader发送出请求后,leader会先把这个操作放到日志中作为一个日志项,并且leader的日志复制线程会在未来的某一个时间点将这个日志复制到其他的从节点,当大多数从节点接受了并且正确响应后leader节点才会执行这个命令,执行成功后再返回一个响应给客户端。(这也是3.5的答案)

3.4 这里的日志复制是指什么,WL嘛还是?(不知道wl是什么,但是我没有问为什么,而是说起了自己的东西)

"复制"在这里不是指磁盘写操作(Write I/O,WIO或者WL),而是指日志复制过程。这是Raft协议的核心,通过这种方式,Raft协议确保了分布式系统中的一致性。

3.5 raft leader什么时候该返回响应给客户端呢?(我只回答了正确收到命令的响应时间点,但是没谈到发生错误时的响应状态码)

答:3.3就是答案

3.6 如果我要查找的时候,必须走leader节点嘛(讲解了)

对,我提到了查的时候怎么四种保证一致性读的方案,性能主键提高:一致性读,

可以查看我的这篇博客的第39个问题

3.7 用读日志去处理读是个什么原理,难道我瞬时高并发10w个读请求,还要写10w个读日志吗?(面试官当时觉得这个点很差劲,最好应该直接写性能最高的那种)

答:是这样的,这是最笨的一种方法。

3.8 不是说最笨,我是指为什么要这样做?(其实没回答清楚,其实都是3.6回答冗余留下的坑)

答:因为机器可能发生故障,或者可能发生网络分区,在主分区中,新的leader会产生,但是它还不知道自己的日志提交索引,这个时候需要发送一个no-op entry去确认自己的commitIndex

正确回答:因为机器可能发生故障,或者可能发生网络分区,在主分区中,新的leader会产生,但是它还不知道自己的日志提交索引,如果leader直接读的话,可能会产生不一致,所以我采取的是也将读请求进行日志化操作,这样就一定能保证读请求在之前的写请求后面完成。

3.9 其实我多副本复制日志后再告诉用户你ok了,那我读取的时候至少多数实例能正常工作,知道哪个是最新的,那我是不是没必要这个操作?

答:对的

3.10 我目前的理解是,目前还没见到一个系统是会把这个读请求给存下来的(雷:这里的回答感觉给面试官一种你写需求会应付不关注质量)

答:只是为了解决读一致性,我采取了最简单的这种方案

3.11 对于readIndex机制,我需要每次读请求都要发送一次心跳给所有从节点,然后还需要等待过半数的响应吗?

答:第一次获取到了no-op entry的响应后,还可以使用lease read给它一个续期,在这个期间内,我得到的commitIndex都认为是有效的,一般这里的lease read时间和选举超时时间相等,就不需要每次都发送心跳,而是直接返回给客户端

4 rpc框架

本部分的所有总结都在深度思考rpc框架面经 一文中的第1,第5以及第6部分

4.1 出于什么目的?

答:了解分布式框架

4.2 简单介绍一下架构

项目架构:大概分为四个模块,服务提供者、消费者、rpc框架以及对消费者暴露出的集成接口模块

系统架构:

Apache Dubbo是一个高性能、轻量级的开源Java RPC框架。Dubbo主要提供了三个关键功能,包括接口级别的远程方法调用,容错与负载均衡,以及自动服务注册与发现。

Dubbo架构的主要流程如下:

  1. 启动服务提供者:服务提供者启动后,向注册中心注册其提供的服务。

  2. 启动服务消费者:服务消费者启动后,向注册中心查询其需要的服务信息,并建立与服务提供者的连接。

  3. 服务调用:服务消费者通过建立的连接调用服务提供者的服务。如果调用失败,Dubbo支持多种容错机制,例如failover(失败后重试其他服务器)。

  4. 加载平衡:在有多个服务提供者的情况下,Dubbo支持多种负载均衡策略,例如随机(Random)、轮询(RoundRobin)、最少活跃数(LeastActive)等。

  5. 服务监控:Dubbo可以记录服务的调用次数和调用时间等信息,以供开发者分析。

Dubbo的这些特性使其成为一个可靠、高性能的RPC框架,广泛用于服务间的远程方法调用。

4.3 rpc的调用过程(也是调用关系)详细讲讲

4.4 讲讲调用原理,比如服务怎么发现,怎么调用,提供者怎么响应?(我很容易跑到旁路的细枝末节,没有讲解到主干,面试官比较关注所有操作都成功的情况下编码解码的过程)

一个RPC(远程过程调用)框架的核心目的是允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的程序或服务,就像调用本地的方法或函数一样。以下是一个典型的RPC框架如何处理请求的概述:

  1. 服务定义和接口

    • 通常,开发者首先定义服务和它们的接口。这些接口定义了可以远程调用的方法。
    • 使用IDL(接口定义语言)描述服务,生成客户端和服务器的存根。
  2. 服务注册

    • 服务提供者启动后,将自己的地址和提供的服务信息注册到注册中心。
  3. 服务发现

    • 服务消费者(或客户端)启动时,从注册中心订阅它想要调用的服务。
    • 注册中心返回服务提供者的地址给消费者。为了提高效率,这些地址通常会在消费者本地进行缓存。
  4. 远程调用

    • 当客户端要调用某个远程方法时,它会通过本地代理或存根发起这个调用。
    • 存根负责将方法调用转换为网络请求。这通常涉及序列化方法名称、参数等,然后发送到网络。
    • 负载均衡策略(如轮询、随机或最少活跃调用)可以在这一步中应用,以选择最合适的服务提供者实例。
  5. 请求处理

    • 服务提供者接收到网络请求后,反序列化请求数据以获得原始的方法名称和参数。
    • 服务提供者然后在本地执行这个方法,并获得结果。
  6. 响应返回

    • 服务提供者将执行结果序列化后,通过网络返回给服务消费者。
    • 服务消费者的存根反序列化返回的数据,将其转换回原始的方法调用结果,并返回给调用方。
  7. 容错处理

    • 如果在RPC过程中发生错误(如网络中断、服务提供者崩溃等),RPC框架可能提供容错机制。
    • 容错策略可能包括重新路由、重试、返回默认结果等。
  8. 监控和日志

    • 为了跟踪和监控远程调用的性能和可靠性,RPC框架通常提供日志记录和监控功能。

这个过程描述的是一个典型的同步RPC调用。但现代RPC框架也支持异步调用,其中客户端可以在不等待响应的情况下继续其它操作。

4.4.1 假设所有操作都成功,其调用链是什么样子的?怎么路由(这里的路由是指本地负载均衡的方法,但是我答成了去api网关进行路由,然后再经过网关返回的这么一个过程)

服务路由:
在有多个服务提供者提供相同服务的情况下,客户端需要决定调用哪一个服务提供者。这时,路由策略(如轮询、随机、最少活跃调用等)会被应用。负载均衡策略会根据本地缓存的服务提供者地址列表选择一个。

4.4.2 涉及到的HTTP协议以及自定义的MRF协议

1 在HTTP协议中,可以通过以下方式来区分请求报文和响应报文:

. 起始行的格式:

  • 请求报文的起始行是一个请求行,它的格式为:<HTTP方法> <请求URI> <HTTP版本>。例如:
    GET /index.html HTTP/1.1

  • 响应报文的起始行是一个状态行,它的格式为:<HTTP版本> <状态码> <状态描述>。例如:
    HTTP/1.1 200 OK

综上,最直接和可靠的方式是查看起始行。请求行和状态行的格式是唯一的,它们可以明确地告诉你报文是请求还是响应。

2 选择HTTP协议作为netty的上层应用协议

1 版本1:选择了HTTP协议作为我们的应用层协议,对于发送请求,有请求行、请求头、请求行以及请求体,其中请求头包含了一个content-type字段,这个字段包含了具体的序列化协议,比如常用的web服务器序列化方式application/json,还有一个content-length字段,为了区分包类型,即让服务器知道一个调用请求还是调用响应,我们可以利用http的请求行和状态行做区分。此外利用http请求的空行和content-length字段可以防止粘包和拆包问题。

3 自定义MRF协议(能跟面试官吹牛逼)

在这里插入图片描述
这几个字段的作用就如图所示,跟HTTP协议一对比,发现有很多相似之处。

4.6 比如我现在想要调用服务端的methodA方法,服务端怎么知道客户端想要调用的就是这个方法呢?

客户端会定一个类,叫RpcRequest,这个类定义了需要调用远程方法的所有属性,包括接口名、方法名、方法所需要的参数及其类型,同时还包含了一个请求号(这里的请求号可以不说,因为是旁路,会影响面试官的听到主要答案),然后通过客户端本地存根(也就是代理),会给我们自动创建相应的RpcRequest对象并且进行属性填充,这里的属性是根据我们调用的具体方法、消费者提供的参数进行填充的,

填充完成后,代理类还会帮我们根据选择的序列化器将实际的请求体进行序列化操作,序列化后的rpcRequest数据会放到请求体中,然后再通过网络发给服务提供者。

生产端拿到请求后会先进行反序列化请求体,拿到实际的RpcRequest的数据后会根据接口名、接口方法以及参数列表会进行反射得到一个可执行的方法,然后进行条用就行了。

4.7 编解码协议是什么(序列化和反序列化),想问你什么协议去序列化的

我用的google的protocol buffer

4.8 假设现在服务的provider想要下线了,如何做到让服务调用端感知?(本来应该是很简单的一个问题,我答非所问了)

在服务调用端设置一个超时时间,如果在相应的时间内没有回应,则认为这个服务实例不可用,然后轮询下一个实例。

当服务提供者(Service Provider)想要下线时,为了保证服务的可用性和避免服务调用失败,通常采取以下策略让服务消费者(Service Consumer)或调用端感知:

当服务提供者(Service Provider)想要下线时,为了保证服务的可用性和避免服务调用失败,通常采取以下策略让服务消费者(Service Consumer)或调用端感知:

  1. 使用服务注册与发现机制(涉及到注册中心、消费者和提供者三方的交互机制):

    • 在许多RPC和微服务框架中,都采用了服务注册与发现的机制,如Zookeeper、Consul、Eureka等。
    • 当服务提供者打算下线时,首先从服务注册中心撤销或下线其服务。
    • 服务消费者定期从服务注册中心拉取服务列表,这样当提供者下线后,消费者会感知到这一变化,并不再向该提供者发送请求。
  2. 优雅关闭(服务提供者):

    • 服务提供者在停机前,首先停止接收新的请求,但继续处理已经接收的请求。
    • 一旦所有已接受的请求都处理完毕,再完全关闭服务。这确保了没有请求在中途被突然中断。
  3. 使用负载均衡器或API网关(利用第三方网关阻断流量):

    • 如果你使用了负载均衡器或API网关来路由请求,当服务提供者想要下线时,首先在负载均衡器或API网关中移除该提供者。
    • 通过这种方式,即使服务提供者还在运行,消费者的请求也不会被路由到该提供者。
  4. 健康检查(注册中心的机制):

    • 服务提供者通常会提供健康检查的接口,用于报告其健康状态(consul)。
    • 当服务提供者计划下线时,可以修改健康检查的响应,表示其不再健康或即将下线。
    • 服务消费者或负载均衡器定期检查服务的健康状态,感知到该变化后,会停止向提供者发送请求。
  5. 通知和告警(预计的维护或下线):

    • 当服务提供者计划下线时,可以手动通知所有已知的服务消费者。
    • 这通常适用于预计的维护或下线,确保消费者有足够的时间来做出响应或备份方案。
  6. 使用熔断器和重试机制(熔断重试,会造成多余的请求):

    • 熔断器可以检测到连续的请求失败,并自动切断到提供者的请求,避免向已下线的服务发送请求。
    • 重试机制会在请求失败时尝试其他可用的服务提供者。

结合上述策略,可以确保当服务提供者下线时,服务消费者能够及时感知并作出相应的处理,避免服务中断或大量的请求失败。

4.9 假设现在服务端处理一个请求需要一秒钟,服务端本身还有很多请求没有处理完毕,但是在某一秒钟的时候我把服务端的机器给关了,那用户就报错了嘛,这块怎么处理让它不报错,因为报错就会对业务产生消极影响。

如果客户端(用户的设备或应用)在等待服务端响应时突然关机或断开连接,确保用户不看到错误是一项挑战。以下是一些建议的处理方法:

  1. 服务端冗余与故障转移

    • 在服务端部署多个实例,当一个实例发生故障时,流量可以自动切换到另一个健康的实例。
    • 使用负载均衡器来分发请求,同时检查各个服务实例的健康状态。
  2. 客户端策略

    • 延迟显示错误:客户端可以增加一个较长的超时时间,在此时间内,如果没有收到服务端的响应,可以认为服务端出现了问题。但在此时间内,用户界面可以显示一个“处理中”或“稍等”的提示。
    • 重试机制:客户端在收到错误响应或超时后,可以尝试再次发送请求,但要注意不要无限次地重试,以避免资源耗尽或不必要的网络流量。
    • 本地缓存和备份对于某些可预测的请求,客户端可以缓存之前的结果,并在服务端无响应时返回这些缓存的数据(这是我的答案,但是面试官似乎不是很认可,它提到了put,累加之类的操作就不能缓存)。
  3. 使用离线策略

    • 对于某些应用,可以考虑使用离线策略,即在无法立即处理的情况下,将请求保存到本地,等到网络稳定或服务端可用时再处理。
  4. 友好的用户界面

    • 即使在错误发生时,也应该展示友好的提示,例如:“网络不稳定,请稍后重试”或“我们正在处理您的请求,请稍候”等,避免直接展示技术性错误信息。
  5. 后台处理与通知

    • 对于不需要立即响应的请求,可以让客户端提交请求后立即返回,而实际的处理则在服务端后台进行。完成后,通过通知或其他方式告诉客户端。
  6. 数据一致性

    • 保证服务端的数据处理逻辑具有幂等性,这样即使客户端发送了多次请求,也不会影响数据的一致性。
  7. 使用消息队列或事件驱动模型

    • 客户端发送的请求先存入消息队列,由服务端异步处理。客户端可以轮询或等待通知来获取结果。

在设计系统时,应该从用户体验的角度出发,尽量减少错误的展示,但同时也要确保系统的稳定性和数据的准确性。

4.10 重试是一种机制,但是会导致响应变长呢?,了解注册和反注册嘛?服务端下线后会反注册,向注册中心注销对应的服务,然后摘流就好了,不让客户端的请求进来就好了

答:对,确实

4.11 本地注册中心是个什么操作?

答:相当于本地缓存,因为远程注册中心可能会宕机,本地注册中心还能正常工作一段时间,毕竟微服务实例变化的不是那么频繁,这段时间足够远程注册中心灾备恢复了

5 场景设计题目-线程池

详细的面经和设计可以参考:深度思考线程池面经

5.1 实现一个线程池,效果是这样的:当流量大的时候,线程数要多一点,当流量小的时候,缩的小一些,如果说线程数过多,线程池又不要炸掉,然后客户端可以阻塞,并且要完全站在用户的角度去考虑(没有答好)

我的回答(面试官做出了肯定):可以加一个定时探测机制,探测流量的大小,如果流量大就将允许的最大线程数增加,如果流量小,将最大线程数设置的和核心线程数一样大,cpu核心的两倍就行,但是这样回答其实太简单了

详细的回答:

主要是动态改变maxPoolSize的粒度上的区别,其他的几乎没变:

1 首先需要一个有界队列,同时设置一个corePoolSize和一个maxPoolSize参数,分别表示核心线程数以及支持的最大线程数,corePoolSize设置为OS支持的核心线程数+1,根据内存允许的情况设置maxPoolSize参数;另外会为每一个非核心线程设置一个超时时间,当执行完任务后的一段时间没有被分配新任务就自我注销;

2 主线程一般负责将任务分发给线程池中的线程或者添加任务到阻塞队列,同时我还给主线程一个任务那就是每隔一段时间监测当前的流量情况,如果当前的maxPoolSize设置的比较大,但是发现流量在明显降低,则粗粒度的减少maxPoolSize的值;如果发现当前的流量比较小,但是流量越来越大,则会一次性粗粒度的加大maxPoolSize,直到maxPoolSize达到一个系统内存的临界值,这里的检测机制是不断判断当前的等待队列是否已满,并且总线程数是否快要到达maxPoolSize,如果都是则扩容;如果等待队列都没满甚至为空,则可以慢慢减少maxPoolSize。

3 当maxPoolSize加大到系统的临界值并且阻塞队列已经满时,不会执行拒绝策略,主线程不再分配任务给本地的线程池,而是先放入到消息队列中,等待本地的队列中的任务执行了大部分时才将其从消息队列中预取一部分到本地队列。

6 算法题

6.1 " word1 word2 word3 “变成"word3 word2 word1”

思路:先使用trim()函数去除掉两端的空串,然后使用split函数将他们切割成数组,在数组中使用首尾双指针,同时向中间靠拢,同时分别交换它们,直到相遇

6.2 你这种的话,如果这个字符串有一个g,会同时占用2个g的内存,数组一个g,输入字符串一个g; 另一个问题是对于1g大的字符串进行split的时候,能不能run也是一个问题,就算run了,是不是多了一次处理时间为n的复杂度

改进:可以使用stingBuilder,从字符串尾部开始遍历,每次碰到一个单词就将其顺序加入到stingBuilder中,这样的话就不会立即占用两个g的内存了,而且只需要处理一次

7 反问

7.1 数据引擎主要是用java写的嘛,写什么呢

mq,flink都有

7.2 流量级别呢?

亿级的tps,一秒一个亿

相关文章:

【2024秋招】2023-8-5-小红书-数据引擎团队后端开发提前批面经

1 面试官介绍 OLAP引擎&#xff0c;离线引擎&#xff0c;大数据分析中间件 2 自我介绍 缺点&#xff1a; &#xff08;1&#xff09;面试官让重点介绍自己最在行的项目&#xff0c;我真的在自我介绍上扯了一些别的东西… &#xff08;2&#xff09;在面试的时候因为想看简…...

【Docker从入门到入土 4】使用Harbor搭建Docker私有仓库

私有仓库 一、Harbor简介1.1 什么是Harbor?1.2 Harbor的特性1.3 Harbor和docker registry的关系1.4 Harbor的构成1.4 Harbor 配置文件中的两类参数1.4.1 所需参数1.4.2 可选参数 二、Harbor部署2.1 部署Docker-Compose服务2.2 部署 Harbor 服务Step1 下载或上传 Harbor 安装程…...

监控易一体化运维:打造机房环境监控的卓越典范

随着信息技术的飞速发展&#xff0c;机房作为企业数据和业务的中心&#xff0c;其运行状态和管理的重要性日益凸显。为确保机房的稳定性和可靠性&#xff0c;越来越多的企业选择使用一体化运维管理软件来进行实时监控。在这方面&#xff0c;监控易品牌提供了一款全面而高效的机…...

【X3m】DDR压力测试

Index of /downloads/unittest/ 设置CPU模式和降频温度# 若设备重启需再次配置这两条指令 echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor echo 105000 > /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp #1 cpu test ec…...

【Linux】32条指令带你玩转 Linux !

目录 1&#xff0c;whoami 2&#xff0c;who 3&#xff0c;pwd 4&#xff0c;ls 1&#xff0c;ls 2&#xff0c;ls -l 3&#xff0c;ls -a 4&#xff0c;ls -al 5&#xff0c;ls -d 6&#xff0c;ls -ld 5&#xff0c;clear 6&#xff0c;cd 1&#xff0c;cd 2&…...

高效恢复丢失的文件的10 款Android数据恢复工具

在当今快节奏的数字时代&#xff0c;从Android设备丢失重要数据可能是一场噩梦。 您需要一个可靠的恢复工具来取回您的数据&#xff0c;例如令人难忘的照片&#xff0c;重要的联系人&#xff0c;重要的工作文档等。 值得庆幸的是&#xff0c;有许多高效的Android数据恢复工具可…...

Python数据挖掘 | 升级版自动查核酸

&#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于恒川的日常汇报系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏C语言初阶、C…...

港联证券:哪家证券公司开户好?

在现代社会&#xff0c;出资理财已经成为了一个不可或缺的部分。出资者在进行股票生意时&#xff0c;不可避免地需求选择一家证券公司进行开户。可是&#xff0c;哪家证券公司开户好&#xff1f;这是每个出资者都需求考虑的问题。本文将从多个角度分析&#xff0c;为您供给一些…...

RabbitMQ官方案例学习记录

官方文档&#xff1a;RabbitMQ教程 — RabbitMQ (rabbitmq.com) 一、安装RabbitMQ服务 直接使用docker在服务器上安装 docker run -it -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management 安装完成后&#xff0c;访问15672端口&#xff0c;默认用户…...

Ikigai: 享受生命的意义

你为什么而活&#xff1f;你的存在意义是什么&#xff1f;除了工作、挣钱&#xff0c;还有什么值得投入人生&#xff1f;Ikigai是来自日本的哲学思想&#xff0c;意味着带给你快乐、让你享受生活的东西。知道自己的Ikigai&#xff0c;也许人生可以减少很多焦虑、痛苦和烦恼。世…...

ios 实现PDF,Word,Excel等文档类型的读取与预览

文章目录 一、前言二、iCould相关配置三、功能实现3.1 UIDocumentPickerViewController 选取控制器3.2 读取文件3.3 文档预览3.3.1 下载并保存3.3.2 QLPreviewController预览文档四、总结一、前言 最近正在研发的项目有一个需求: 允许用户将iCloud中的文档上传,实现文件的流…...

速锐得解码匹配特斯拉电动汽车安全性能检测车架号及BMS电池数据

电动汽车三大件分别是电池、电机和电控。到目前为止&#xff0c;电机技术已经非常成熟&#xff0c;直流永磁电机、永磁同步电机已经取代了异步电机&#xff0c;成为电动汽车的主流。很多人认为电动汽车最后一道技术门槛是电池&#xff0c;但在我国&#xff0c;汽车制造商在制造…...

mysql视图中转换表字段的数据类型

需求: 开发框架中需要视图c_smelt_group字段类型是字符串的&#xff0c;而数据库表中c_smelt_group字段是int类型。 解决办法: wt是表的别名&#xff0c;通过cast函数&#xff0c;将wt.c_smelt_group字段转成字符串类型&#xff0c; AS c_smelt_group 是给字段取别名。 cast( …...

深入理解Java中的Synchronized关键字

文章目录 &#x1f4dd; 定义&#x1f4dd; JDK6以前&#x1f525; 对象从无锁到偏向锁转化的过程&#x1f525; 轻量级锁升级&#x1f525; 自旋锁&#x1f525; 重量级锁 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专…...

力扣每日一题58:最后一个单词的长度

题目描述&#xff1a; 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1&#xff1a; 输入&#xff1a;s "Hello World&q…...

mybatis书写

mybatis <select id"selectUserList" resultType"map"> select * from user </select><!--根据主键查询一条--> <select id"selectById" resultType"map" parameterType"java.lang.Integer"> sele…...

Win32 命名管道

命名管道简单封装 CNamedPipe.h #pragma once #include <string> #include <windows.h> #include <tchar.h>#pragma warning(disable:4200)class CNamedPipe { public:CNamedPipe();~CNamedPipe();CNamedPipe(const CNamedPipe& r) delete;CNamedPipe&…...

Flutter 填坑录 (不定时更新)

一&#xff0c;内存爆表 > 图片缓存 /// State基类 class BaseState<T extends StatefulWidget> extends State<T>withAutomaticKeepAliveClientMixin,WidgetHelper,DialogHelper,EventListener {mustCallSupervoid initState() {if (isListenEvent()) {EventMa…...

如何提高webpack的构建速度?

一、背景 随着我们的项目涉及到页面越来越多&#xff0c;功能和业务代码也会随着越多&#xff0c;相应的 webpack 的构建时间也会越来越久 构建时间与我们日常开发效率密切相关&#xff0c;当我们本地开发启动 devServer 或者 build 的时候&#xff0c;如果时间过长&#xff…...

Linux:实用操作

Linux&#xff1a;实用操作 1. 各类小技巧1.1 controlc(ctrl c) 强制停止1.2 可以通过快捷键&#xff1a;control d(ctrl d)&#xff0c;退出账户的登录1.3 历史命令搜索1.4 光标移动快捷键 2. 软件安装2.1 介绍2.2 yum命令(需要root权限)在这里插入图片描述 3. systemctl4.…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...