企业网站的建设怎么收费定制网站开发设计

diannao/2026/1/23 20:56:30/文章来源:
企业网站的建设怎么收费,定制网站开发设计,苏州网站建设哪家做得好,wordpress 做企业网站在云原生时代和容器化浪潮中#xff0c;容器的日志采集是一个看起来不起眼却又无法忽视的重要议题。对于容器日志采集我们常用的工具有filebeat和fluentd#xff0c;两者对比各有优劣#xff0c;相比基于ruby的fluentd#xff0c;考虑到可定制性#xff0c;我们一般默认选…在云原生时代和容器化浪潮中容器的日志采集是一个看起来不起眼却又无法忽视的重要议题。对于容器日志采集我们常用的工具有filebeat和fluentd两者对比各有优劣相比基于ruby的fluentd考虑到可定制性我们一般默认选择golang技术栈的filbeat作为主力的日志采集agent。 相比较传统的日志采集方式容器化下单节点会运行更多的服务负载也会有更短的生命周期而这些更容易对日志采集agent造成压力虽然filebeat足够轻量级和高性能但如果不了解filebeat的机制不合理的配置filebeat实际的生产环境使用中可能也会给我们带来意想不到的麻烦和难题。 整体架构日志采集的功能看起来不复杂主要功能无非就是找到配置的日志文件然后读取并处理发送至相应的后端如elasticsearch,kafka等。 filebeat官网有张示意图如下所示 针对每个日志文件filebeat都会启动一个harvester协程即一个goroutine在该goroutine中不停的读取日志文件直到文件的EOF末尾。一个最简单的表示采集目录的input配置大概如下所示 filebeat.inputs: - type: log# Paths that should be crawled and fetched. Glob based paths.paths:- /var/log/*.log不同的harvester goroutine采集到的日志数据都会发送至一个全局的队列queue中queue的实现有两种基于内存和基于磁盘的队列目前基于磁盘的队列还是处于alpha阶段filebeat默认启用的是基于内存的缓存队列。 每当队列中的数据缓存到一定的大小或者超过了定时的时间默认1s)会被注册的client从队列中消费发送至配置的后端。目前可以设置的client有kafka、elasticsearch、redis等。 虽然这一切看着挺简单但在实际使用中我们还是需要考虑更多的问题例如 日志文件是如何被filbebeat发现又是如何被采集的 filebeat是如何确保日志采集发送到远程的存储中不丢失一条数据的 如果filebeat挂掉下次采集如何确保从上次的状态开始而不会重新采集所有日志 filebeat的内存或者cpu占用过多该如何分析解决 filebeat如何支持docker和kubernetes如何配置容器化下的日志采集 想让filebeat采集的日志发送至的后端存储如果原生不支持怎样定制化开发这些均需要对filebeat有更深入的理解下面让我们跟随filebeat的源码一起探究其中的实现机制。 一条日志是如何被采集的filebeat源码归属于beats项目而beats项目的设计初衷是为了采集各类的数据所以beats抽象出了一个libbeat库基于libbeat我们可以快速的开发实现一个采集的工具除了filebeat还有像metricbeat、packetbeat等官方的项目也是在beats工程中。 如果我们大致看一下代码就会发现libbeat已经实现了内存缓存队列memqueue、几种output日志发送客户端数据的过滤处理processor等通用功能而filebeat只需要实现日志文件的读取等和日志相关的逻辑即可。 从代码的实现角度来看filebeat大概可以分以下几个模块 input: 找到配置的日志文件启动harvester harvester: 读取文件发送至spooler - spooler: 缓存日志数据直到可以发送至publisher publisher: 发送日志至后端同时通知registrar registrar: 记录日志文件被采集的状态1. 找到日志文件对于日志文件的采集和生命周期管理filebeat抽象出一个Crawler的结构体 在filebeat启动后crawler会根据配置创建然后遍历并运行每个input for _, inputConfig : range c.inputConfigs {err : c.startInput(pipeline, inputConfig, r.GetStates())}在每个input运行的逻辑里首先会根据配置获取匹配的日志文件需要注意的是这里的匹配方式并非正则而是采用linux glob的规则和正则还是有一些区别。 matches, err : filepath.Glob(path)获取到了所有匹配的日志文件之后会经过一些复杂的过滤例如如果配置了exclude_files则会忽略这类文件同时还会查询文件的状态如果文件的最近一次修改时间大于ignore_older的配置也会不去采集该文件。 2. 读取日志文件匹配到最终需要采集的日志文件之后filebeat会对每个文件启动harvester goroutine在该goroutine中不停的读取日志并发送给内存缓存队列memqueue。 在(h *Harvester) Run()方法中我们可以看到这么一个无限循环省略了一些逻辑的代码如下所示for {message, err : h.reader.Next()if err ! nil {switch err {case ErrFileTruncate:logp.Info(File was truncated. Begin reading file from offset 0: %s, h.state.Source)h.state.Offset 0filesTruncated.Add(1)case ErrRemoved:logp.Info(File was removed: %s. Closing because close_removed is enabled., h.state.Source)case ErrRenamed:logp.Info(File was renamed: %s. Closing because close_renamed is enabled., h.state.Source)case ErrClosed:logp.Info(Reader was closed: %s. Closing., h.state.Source)case io.EOF:logp.Info(End of file reached: %s. Closing because close_eof is enabled., h.state.Source)case ErrInactive:logp.Info(File is inactive: %s. Closing because close_inactive of %v reached., h.state.Source, h.config.CloseInactive)default:logp.Err(Read line error: %v; File: %v, err, h.state.Source)}return nil}...if !h.sendEvent(data, forwarder) {return nil} }可以看到reader.Next()方法会不停的读取日志如果没有返回异常则发送日志数据到缓存队列中。 返回的异常有几种类型除了读取到EOF外还会有例如文件一段时间不活跃等情况发生会使harvester goroutine退出不再采集该文件并关闭文件句柄。 filebeat为了防止占据过多的采集日志文件的文件句柄默认的close_inactive参数为5min如果日志文件5min内没有被修改上面代码会进入ErrInactive的case之后该harvester goroutine会被关闭。 这种场景下还需要注意的是如果某个文件日志采集中被移除了但是由于此时被filebeat保持着文件句柄文件占据的磁盘空间会被保留直到harvester goroutine结束。 3. 缓存队列在memqueue被初始化时filebeat会根据配置min_event是否大于1创建BufferingEventLoop或者DirectEventLoop一般默认都是BufferingEventLoop即带缓冲的队列。 type bufferingEventLoop struct {broker *Brokerbuf *batchBufferflushList flushListeventCount intminEvents intmaxEvents intflushTimeout time.Duration// active broker API channelsevents chan pushRequestget chan getRequestpubCancel chan producerCancelRequest// ack handlingacks chan int // ackloop - eventloop : total number of events ACKed by outputsschedACKS chan chanList // eventloop - ackloop : active list of batches to be ackedpendingACKs chanList // ordered list of active batches to be send to the ackloopackSeq uint // ack batch sequence number to validate ordering// buffer flush timer statetimer *time.TimeridleC -chan time.Time }BufferingEventLoop是一个实现了Broker、带有各种channel的结构主要用于将日志发送至consumer消费。 BufferingEventLoop的run方法中同样是一个无限循环这里可以认为是一个日志事件的调度中心。for {select {case -broker.done:returncase req : -l.events: // producer pushing new eventl.handleInsert(req)case req : -l.get: // consumer asking for next batchl.handleConsumer(req)case count : -l.acks:l.handleACK(count)case -l.idleC:l.idleC nill.timer.Stop()if l.buf.length() 0 {l.flushBuffer()}}}上文中harvester goroutine每次读取到日志数据之后最终会被发送至bufferingEventLoop中的events chan pushRequest channel然后触发上面req : -l.events的casehandleInsert方法会把数据添加至bufferingEventLoop的buf中buf即memqueue实际缓存日志数据的队列如果buf长度超过配置的最大值或者bufferingEventLoop中的timer定时器触发了case -l.idleC均会调用flushBuffer()方法。 flushBuffer()又会触发req : -l.get的case然后运行handleConsumer方法该方法中最重要的是这一句代码req.resp - getResponse{ackChan, events}这里获取到了consumer消费者的response channel然后发送数据给这个channel。真正到这才会触发consumer对memqueue的消费。所以其实memqueue并非一直不停的在被consumer消费而是在memqueue通知consumer的时候才被消费我们可以理解为一种脉冲式的发送。 4. 消费队列实际上早在filebeat初始化的时候就已经创建了一个eventConsumer并在loop无限循环方法里试图从Broker中获取日志数据。for {if !paused c.out ! nil consumer ! nil batch nil {out c.out.workQueuequeueBatch, err : consumer.Get(c.out.batchSize)...batch newBatch(c.ctx, queueBatch, c.out.timeToLive)}...select {case -c.done:returncase sig : -c.sig:handleSignal(sig)case out - batch:batch nil}}上面consumer.Get就是消费者consumer从Broker中获取日志数据然后发送至out的channel中被output client发送我们看一下Get方法里的核心代码 select {case c.broker.requests - getRequest{sz: sz, resp: c.resp}:case -c.done:return nil, io.EOF}// if request has been send, we do have to wait for a responseresp : -c.respreturn batch{consumer: c,events: resp.buf,ack: resp.ack,state: batchActive,}, nilgetRequest的结构如下type getRequest struct {sz int // request sz events from the brokerresp chan getResponse // channel to send response to }getResponse的结构 type getResponse struct {ack *ackChanbuf []publisher.Event }getResponse里包含了日志的数据而getRequest包含了一个发送至消费者的channel。 在上文bufferingEventLoop缓冲队列的handleConsumer方法里接收到的参数为getRequest里面包含了consumer请求的getResponse channel。 如果handleConsumer不发送数据consumer.Get方法会一直阻塞在select中直到flushBufferconsumer的getResponse channel才会接收到日志数据。 5. 发送日志在创建beats时会创建一个clientWorkerclientWorker的run方法中会不停的从consumer发送的channel里读取日志数据然后调用client.Publish批量发送日志。 func (w *clientWorker) run() {for !w.closed.Load() {for batch : range w.qu {if err : w.client.Publish(batch); err ! nil {return}}} }libbeats库中包含了kafka、elasticsearch、logstash等几种client它们均实现了client接口 type Client interface {Close() errorPublish(publisher.Batch) errorString() string }当然最重要的是实现Publish接口然后将日志发送出去。 实际上filebeat中日志数据在各种channel里流转的设计还是比较复杂和繁琐的笔者也是研究了好久、画了很长的架构图才理清楚其中的逻辑。 这里抽出了一个简化后的图以供参考如何保证at least oncefilebeat维护了一个registry文件在本地的磁盘该registry文件维护了所有已经采集的日志文件的状态。 实际上每当日志数据发送至后端成功后会返回ack事件。filebeat启动了一个独立的registry协程负责监听该事件接收到ack事件后会将日志文件的State状态更新至registry文件中State中的Offset表示读取到的文件偏移量所以filebeat会保证Offset记录之前的日志数据肯定被后端的日志存储接收到。 State结构如下所示 type State struct {Id string json:- // local unique id to make comparison more efficientFinished bool json:- // harvester stateFileinfo os.FileInfo json:- // the file infoSource string json:sourceOffset int64 json:offsetTimestamp time.Time json:timestampTTL time.Duration json:ttlType string json:typeMeta map[string]string json:metaFileStateOS file.StateOS }记录在registry文件中的数据大致如下所示 [{source:/tmp/aa.log,offset:48,timestamp:2019-07-03T13:54:01.29899508:00,ttl:-1,type:log,meta:null,FileStateOS:{inode:7048952,device:16777220}}]由于文件可能会被改名或移动filebeat会根据inode和设备号来标志每个日志文件。 如果filebeat异常重启每次采集harvester启动的时候都会读取registry文件从上次记录的状态继续采集确保不会从头开始重复发送所有的日志文件。 当然如果日志发送过程中还没来得及返回ackfilebeat就挂掉registry文件肯定不会更新至最新的状态那么下次采集的时候这部分的日志就会重复发送所以这意味着filebeat只能保证at least once无法保证不重复发送。 还有一个比较异常的情况是linux下如果老文件被移除新文件马上创建很有可能它们有相同的inode而由于filebeat根据inode来标志文件记录采集的偏移会导致registry里记录的其实是被移除的文件State状态这样新的文件采集却从老的文件Offset开始从而会遗漏日志数据。 为了尽量避免inode被复用的情况同时防止registry文件随着时间增长越来越大建议使用clean_inactive和clean_remove配置将长时间未更新或者被删除的文件State从registry中移除。 同时我们可以发现在harvester读取日志中会更新registry的状态处理一些异常场景。例如如果一个日志文件被清空filebeat会在下一次Reader.Next方法中返回ErrFileTruncate异常将inode标志文件的Offset置为0结束这次harvester重新启动新的harvester虽然文件不变但是registry中的Offset为0采集会从头开始。 特别注意的是如果使用容器部署filebeat需要将registry文件挂载到宿主机上否则容器重启后registry文件丢失会使filebeat从头开始重复采集日志文件。 filebeat自动reload更新目前filebeat支持reload input配置module配置但reload的机制只有定时更新。 在配置中打开reload.enable之后还可以配置reload.period表示自动reload配置的时间间隔。 filebeat在启动时会创建一个专门用于reload的协程。对于每个正在运行的harvesterfilebeat会将其加入一个全局的Runner列表每次到了定时的间隔后会触发一次配置文件的diff判断如果是需要停止的加入stopRunner列表然后逐个关闭新的则加入startRunner列表启动新的Runner。 filebeat对kubernetes的支持filebeat官方文档提供了在kubernetes下基于daemonset的部署方式最主要的一个配置如下所示 - type: dockercontainers.ids:- *processors:- add_kubernetes_metadata:in_cluster: true即设置输入input为docker类型。由于所有的容器的标准输出日志默认都在节点的/var/lib/docker/containers/containerId/*-json.log路径所以本质上采集的是这类日志文件。 和传统的部署方式有所区别的是如果服务部署在kubernetes上我们查看和检索日志的维度不能仅仅局限于节点和服务还需要有podNamecontainerName等所以每条日志我们都需要打标增加kubernetes的元信息才发送至后端。 filebeat会在配置中增加了add_kubernetes_metadata的processor的情况下启动监听kubernetes的watch服务监听所有kubernetes pod的变更然后将归属本节点的pod最新的事件同步至本地的缓存中。 节点上一旦发生容器的销毁创建/var/lib/docker/containers/下会有目录的变动filebeat根据路径提取出containerId再根据containerId从本地的缓存中找到pod信息从而可以获取到podName、label等数据并加到日志的元信息fields中。 filebeat还有一个beta版的功能autodiscoverautodiscover的目的是把分散到不同节点上的filebeat配置文件集中管理。目前也支持kubernetes作为provider本质上还是监听kubernetes事件然后采集docker的标准输出文件。 大致架构如下所示 但是在实际生产环境使用中仅采集容器的标准输出日志还是远远不够我们往往还需要采集容器挂载出来的自定义日志目录还需要控制每个服务的日志采集方式以及更多的定制化功能。 在轻舟容器云上我们自研了一个监听kubernetes事件自动生成filebeat配置的agent通过CRD的方式支持自定义容器内部日志目录、支持自定义fields、支持多行读取等功能。同时可在kubernetes上统一管理各种日志配置而且无需用户感知pod的创建销毁和迁移自动完成各种场景下的日志配置生成和更新。性能分析与调优虽然beats系列主打轻量级虽然用golang写的filebeat的内存占用确实比较基于jvm的logstash等好太多但是事实告诉我们其实没那么简单。 正常启动filebeat一般确实只会占用3、40MB内存但是在轻舟容器云上偶发性的我们也会发现某些节点上的filebeat容器内存占用超过配置的pod limit限制一般设置为200MB并且不停的触发的OOM。 究其原因一般容器化环境中特别是裸机上运行的容器个数可能会比较多导致创建大量的harvester去采集日志。如果没有很好的配置filebeat会有较大概率导致内存急剧上升。 当然filebeat内存占据较大的部分还是memqueue所有采集到的日志都会先发送至memqueue聚集再通过output发送出去。每条日志的数据在filebeat中都被组装为event结构filebeat默认配置的memqueue缓存的event个数为4096可通过queue.mem.events设置。默认最大的一条日志的event大小限制为10MB可通过max_bytes设置。4096 * 10MB 40GB可以想象极端场景下filebeat至少占据40GB的内存。特别是配置了multiline多行模式的情况下如果multiline配置有误单个event误采集为上千条日志的数据很可能导致memqueue占据了大量内存致使内存爆炸。 所以合理的配置日志文件的匹配规则限制单行日志大小根据实际情况配置memqueue缓存的个数才能在实际使用中规避filebeat的内存占用过大的问题。 如何对filebeat进行扩展开发一般情况下filebeat可满足大部分的日志采集需求但是仍然避免不了一些特殊的场景需要我们对filebeat进行定制化开发当然filebeat本身的设计也提供了良好的扩展性。 beats目前只提供了像elasticsearch、kafka、logstash等几类output客户端如果我们想要filebeat直接发送至其他后端需要定制化开发自己的output。同样如果需要对日志做过滤处理或者增加元信息也可以自制processor插件。 无论是增加output还是写个processorfilebeat提供的大体思路基本相同。一般来讲有3种方式 直接fork filebeat在现有的源码上开发。output或者processor都提供了类似Run、Stop等的接口只需要实现该类接口然后在init方法中注册相应的插件初始化方法即可。当然由于golang中init方法是在import包时才被调用所以需要在初始化filebeat的代码中手动import。 复制一份filebeat的main.goimport我们自研的插件库然后重新编译。本质上和方式1区别不大。filebeat还提供了基于golang plugin的插件机制需要把自研的插件编译成.so共享链接库然后在filebeat启动参数中通过-plugin指定库所在路径。不过实际上一方面golang plugin还不够成熟稳定一方面自研的插件依然需要依赖相同版本的libbeat库而且还需要相同的golang版本编译坑可能更多不太推荐。

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

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

相关文章

深圳宝安区做网站照片制作动态图片软件

前言 ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青-CSDN博客 目的,学习offsetof宏计算结构体相对偏移量 1.offsetof宏 来我们看图…

wordpress建站实例公司名称预先核准官网

MFC控件编程之组合框跟列表框 一丶简介 如果要使用组合框跟列表框.那么就要知道.组合框列表框是最核心的东西就是索引. 索引是从0开始的. 二丶组合框列表框常用的方法 AddString(字符串) 添加一个字符串.放到最后面. DeleteString(索引); 删除指定索引的字符串. int GetCurSe…

自己有网站怎么赚钱中江建设银行网站

目录 简介 串口模块的选型要点 01 通信频点 02 芯片方案 03 通信距离 04 发射功率、接收灵敏度 发射功率 接收灵敏度 05 发射电流、接收电流、休眠电流 06 空中速率 07 天线接口形式 08 封装形式及尺寸 举例说明选型要点 总结 简介 无线模块:通过无线…

跨境电商工具类产品的网站陕西网站备案流程

用途 cp除了复制功能之外还可以建立快捷方式 全称 cp的全称为copy 参数 -a :相当于同时指定参数pdr -d :若文件为链接文件的属性(link file),则复制链接文件属性而非档案本身 -f :强制的意思(force),若目标档案已经存在且无法开启,则移除后再…

wordpress修改页面标题显示不出来百度关键词优化送网站

Sora技术报告的核心总结 根据目前公开的一些信息,我个人将Sora技术报告一文中的核心内容总结如下,分别为训练过程的开创性优化技术、模型支持的能力、模型的缺陷。 一、训练过程开创性优化技术 1.ChatGPT的分词(token)处理取得了很好的一致性文本处理能力,Sora也借鉴了这…

新闻自动采集网站源码商标注册号查询入口官网

asp.net core2.2 用户验证 和授权有很详细和特贴心的介绍,我感兴趣的主要是这两篇:cookie身份验证基于角色的授权我的项目有两类用户:微信公众号用户,用户名为公众号的openid企业微信的用户,用户名为企业微信的userid每…

正规网站备案代理如何连接wordpress

JVM-Java内存区域 Java内存区域是Java虚拟机(JVM)管理的内存资源的逻辑划分,用于存储程序运行时所需的数据。Java内存区域的合理划分和管理对于程序的性能和稳定性具有重要影响。本文将深入探讨Java内存区域的各个部分,包括方法区…

网站建设与推广好做吗网站设计西安网站建设

全文链接!!!!!!! 1. UniApp和其他跨平台框架(如React Native、Flutter)有什么区别? 语言和技术栈:UniApp使用Vue.js作为开发语言和技术栈,而React Native使用React.js,Flutter使用Dart语言。开发者可以根据自己的技术背景和偏好选择合适的框架。 性能和体验:Uni…

网站开发的产品用什么形容词形容wordpress企业网站定制教程 一

安卓Android校园淘(二手交易)APP设计与实现(MySQL)(任务书,开题报告,中期检查表,文献综述,外文翻译,毕业论文14000字,程序代码,MySQL数据库)本项目就是一个基于Android平台的校园淘APP设计,采用了Struts技术,JDBC技术和Android的基础技术完成开发。收录了…

为什么要做网站首页设计上海公司名义买房条件

文章目录 1、网卡接受数据2、网络设备层接收数据3、ip层接受数据4、tcp层接受数据5、上层应用读取数据6、数据从网卡到应用层的整体流程 1、网卡接受数据 当网卡收到数据时,会触发一个中断,然后就会调用对应的中断处理函数,再做进一步处理。…

当涂城乡建设局的网站营销的三个基本概念是什么

添加链接描述 Mysql 安装流程 常见问题 一、环境配置了很久了,不知道装没装过Mysql? 三种方法查:1. cmd中指令where is mysql 2.windows 环境变量中找MYSQL_HOME 3. 打开MySQL的配置文件my.cnf(Windows系统路径为C:\ProgramDat…

中文域名注册官网百度推广的优化软件

在如今快节奏的生活中,游戏作为一种娱乐方式,早已融入了人们的生活,成为许多人放松心情、释放压力的方式之一。然而,与此同时,游戏中的孤独感也成为一些玩家所面临的问题。为了解决这个问题,陪玩系统圈子系…

什么网站做学校设计华为云网站建设怎么设置选择项

让JavaFX运行到移动平台一直是社区努力完成的事。当然,目前已经可以让JavaFX运行到Android和IOS平台了,下面我们来看看如何打包自己的JavaFX项目到Android平台。这个示例是我从打包官方示例的例子里修改而来,用于打包一个简单的JavaFX程序。示…

dedecms做的网站网站中的图片总是被同一ip恶意点击关于网站图片

新品播报!米尔电子发布了基于海思Hi3093高性能MPU的MYC-LHi3093核心板及开发板, 此款核心板支持openEuler embedded OS欧拉系统,丰富生态,可实现100%全国产自主可控。不仅如此,米尔基于Hi3093的核心板及开发板,配套提供…

济南网站怎么做seo网站建设信息模板下载

本案例实现一个简单的登陆服务器。步骤步骤一、搭建LAMP环境,也就是 linuxapachemysqlphp,如果不习惯用linux可以在window下搭建web服务器,具体的搭建方法可以在网上搜一下,很多相关的文章,在此不赘述。步骤二、在mysq…

郑州网站优化哪家好邢台做网站价位

SSH密钥登陆过程 客户端通过ssh-keygen生成自己的公钥和私钥。手动将客户端的公钥放入远程服务器的指定位置。客户端向服务器发起 SSH 登录的请求。服务器收到用户 SSH 登录的请求,发送一些随机数据给用户,要求用户证明自己的身份。客户端收到服务器发来…

餐饮设计公司网站高德地图无目的地导航

js怎么获取指定css属性的值?下面本篇文章给大家介绍一下。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。js怎么获取指定css属性的值?1、通过dom.style.属性 来获取但是这种方法无法获取id、class里的属性例子:…

网站制作topwordpress搭建外贸

参考:《Python编程从入门到实践》 前言1、安装、配置 Git1.1 在Linux系统中安装Git1.2 在OS X系统中安装Git1.3 在Windows系统中安装Git1.4 配置Git 2、创建项目3、忽略文件4、初始化仓库5、检查状态6、将文件加入到仓库中7、执行提交8、查看提交历史 前言 版本控制…

专业外贸网站商城网站建设方案电子版

题目 题目链接: https://www.nowcoder.com/practice/6fbe70f3a51d44fa9395cfc49694404f 思路 直接模拟2个数组有顺序放到一个数组中,然后返回中间的数参考答案java import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 pu…

宜春网站建设公司哪家好京东网站网站建设是什么

今天谈谈类型转换的问题吧,之前我们也遇到过类型转换,比如c语言中这样的赋值: 显然,i和j是不同类型的变量,但是却可以完成赋值,结果是这样的: 其实它们是做了隐式的类型转换,相当于&…