php mds函数,MDSRank类解析 - linux_hunter的个人页面 - OSCHINA - 中文开源技术交流社区...
MDSRank与MDSDaemon一起构成了MDS进程的核心处理类。
=====================MDSRankDispatcher相关=========================
MDSRankDispatcher是MDSRank与MDSDaemon的接口类,MDSRankDispatcher就是给MDSDaemon用的。
MDSRankDispatcher::init()
|__update_log_config() 从配置文件中读取log配置以及更新log配置
|__create_logger() 创建logger
|__创建PerfCounterBuilder类实例且初始化该类实例
|__MDLog::create_logger()
|__Server::create_logger()
|__MDCache::register_perfcounters()
|__handle_osd_map()
|__对于snapserver不为空,则调用SnapServer::check_osd_map()对已经purged的和未purge的snap进行处理
|__Server::handle_osd_map()
|__检查MDSRank::Objecter对应的OSDMap中所有的osd是否包含CEPH_OSDMAP_FULL标识
|__MDCache::notify_osdmap_changed()
|__StrayManager::update_op_limit()
|__Objecter::maybe_request_map()
|__MonClient::sub_want(“osdmap”)
|__MonClient::renew_subs() 调用MonClient向Monitor节点索取OSDMap
|__progress_thread.create() 创建ProgressThread线程
|__Finisher::start()
MDSRankDispatcher::tick()
|__heartbeat_reset()
|__g_ceph_context->get_heartbeat_map()->reset_timeout() 重置heartbeat超时时间,避免被monitor kill
|__check_ops_in_flight()
|__op_tracker.check_ops_in_flight() 从op_tracker中读取到所有in_flight的操作名称
|__遍历所有处于in_flight的操作名称且输出到clog
|__progress_thread.signal() 唤醒progress_thread线程
|__MDLog::flush() flush所有log
|__MDS进程状态处于active或stopping
|__MDCache::trim() 周期性的trim cache
|__MDLog::trim() 周期性的trim log
|__更新logger
|__对于当前处于active或stopping或clientreplay状态
|__Server::find_idle_sessions()
|__locker->tick()
|__对于当前处于reconnect状态
|__Server::reconnect_tick()
|__对于当前处于active状态
|__MDBalancer::tick()
|__MDCache::find_stale_fragment_freeze()
|__MDCache::migrator::find_stale_export_freeze()
|__SnapServer::check_osd_map()
|__Beacon::notify_health()
MDSRankDispatcher::shutdown()
|__设置stopping=true
|__SafeTimer::shutdown() 关闭定时器
|__MDLog::shutdown() 关闭MDLog
|__Finisher::stop() 关闭Finisher
|__MDCache::shutdown() 关闭MDCache
|__Objecter::shutdown() 关闭Objecter
|__MonClient::shutdown() 关闭MonClient
|__op_tracker.on_shutdown() 回调op_tracker的shutdown回调函数
|__Messenger::shutdown() 关闭Messenger
|__若heartbeat_handle_d不为空,则调用get_heartbeat_map()->remove_worker()来删除这个handle
MDSRankDispatcher::ms_dispatch()
|__inc_dispatch_depth()
|___dipsatch() 调用_dispatch()函数做核心分发处理
|__dec_dispatch_depth()
==========================消息dispatch相关===================================
MDSRank::retry_dispatch()
|__inc_dispatch_depth()
|___dispatch()
|__dec_dispatch_depth()
MDSRank::_dispatch()
|__若message不是从MDS发过来的,则直接返回
|__若MDS处于laggy状态
|__将message插入到waiting_for_nolaggy数组
|__若waiting_for_nolaggy数组不为空且此消息为新的消息
|__将message插入到waiting_for_nolaggy数组
|__handle_deferrable_message() 核心消息处理函数
|___advance_queues() 核心消息处理函数
|__此时若MDS处于laggy状态,则直接返回
|__若MDS处于CLIENTREPLAY状态且replay_queue为空
|__若此时没有client request
|__clientreplay_done()
|__若此时MDS处于stopping状态
|__MDLog::trim()
|__stopping_done()
MDRank::handle_deferrable_message()
|__获取待处理消息的类型
|__MDS_PORT_CACHE
|__MDCache::dispatch() 对于CACHE类型的消息,由MDCache负责分发处理
|__MDS_PORT_MIGRATOR
|__MDCache::migrator::dispatch() 对于是MIGRATOR类型的消息,由MDCache::migrator负责分发处理
|__CEPH_MSG_CLIENT_SESSION/CEPH_MSG_CLIENT_RECONNECT/CEPH_MSG_CLIENT_REQUEST
|__Server::dispatch() 对于client session相关的消息,由Server负责分发处理
|__MSG_MDS_SLAVE_REQUEST
|__Server::dispatch() 对于SLAVE相关的消息,由Server负责分发处理
|__MSG_MDS_HEARTBEAT
|__MDBalancer::proc_message() 对于HEARTBEAT相关的消息,由MDBalance负责处理
|__MSG_MDS_TABLE_REQUEST
|__若request的操作码<0,则说明请求client处理
|__get_table_client() 从client table中找到对应的client
|__client->handle_request() 由MDSTableClient负责处理消息请求
|__若request的操作码>=0,则说明请求server处理
|__get_table_server() 从server table中找到对应的server
|__server->handle_request() 由MDSTableServer负责处理消息请求
|__MSG_MDS_LOCK/MSG_MDS_INODEFILECAPS
|__Locker::dispatch() 对于LOCK类型的消息,由Locker负责分发处理
|__CEPH_MSG_CLIENT_CAPS/CEPH_MSG_CLIENT_CAPRELEASE/CEPH_MSG_CLIENT_LEASE
|__Locker::dispatch() 对于client caps相关的消息,由Locker负责分发处理
MDSRank::_advance_queues()
|__遍历finished_queue
|__finished_queue.front()->complete(0) 调用finished_queue中成员中的complete回调函数
|__heartbeat_reset()
|__遍历waiting_for_nolaggy
|__若waiting_for_nolaggy成员中的元素在有效的MDSMap中
|__handle_deferrable_message() 处理这些等待nolaggy的消息
MDSRank::heartbeat_reset()
|__若hb为空,则直接返回
|__g_ceph_context->get_heartbeat_map()->reset_timeout() 重置heartbeat定时器,避免MDS suicide
========================获取MDSRank类成员相关============================
MDSRank::get_metadata_pool()
|__MDSMap::get_metadata_pool() 返回MDRank类中MDSMap类实例对应的metadata pool
MDSRank::get_table_client() 目前只有SNAP使用MDSTable功能,其它模块没有使用
|__根据输入参数判断,若参数是TABLE_SNAP则返回snapclient,否则返回null
MDSRank::get_table_server() 目前只有SNAP使用MDSTable功能,其它模块没有使用
|__根据输入参数判断,若参数是TABLE_SNAP则返回snapserver,否则返回null
MDSRank::set_osd_epoch_barrier()
|__设置osd_epoch_barrier = e
MDSRank::get_laggy_until()
|__Beacon::get_laggy_until() 实际上返回的是Beacon的laggy时间
MDSRank::is_daemon_stopping()
|__返回stopping的当前值
MDSRank::reqeust_state()
|__Beacon::set_want_state() 设置Beacon的want state
|__Beacon::send() Beacon将状态发送给Monitor
==========================MDSRank启动/重启相关=============================
MDSRank::suicide()
|__若suicide_hook不为空,则调用suicide_hook->complete(0)函数
MDSRank::respawn()
|__若respawn_hook不为空,则调用respawn_hook->complete(0)函数
MDSRank::damaged()
|__Beacon::set_want_state(STATE_DAMAGED) 设置Beacon的状态为DAMAGED
|__MonClient::flush_log()
|__Beacon::notify_health()
|__respawn() 重新启动到standby模式
MDSRank::damaged_unlocked()
|__damaged()
MDSRank::handle_write_error()
|__若error==-EBLACKLISTED
|__respawn() 重新启动MDS
|__若mds_action_on_write_error>=2
|__respawn()
|__若mds_action_on_write_error==1 默认行为
|__MDCache::force_readonly()
MDSRank::is_stale_message()
|__消息源来自MDS进程
|__消息源MDS进程在mdsmap中没有inst信息/mdsmap中的inst信息与消息所带的inst信息不一致/mdsmap中消息源MDS进程已经down了
|__若消息的类型是CEPH_MSG_MDS_MAP,则不认为是stale message
|__若消息的类型是MSG_MDS_CACHEEXPIRE且mdsmap中的inst信息与消息所带的inst信息一致,则不认为是stale message
|__否则,认为是stale message
|__消息源不是来自MDS进程,则不认为是stale message
=========================send message相关=====================================
MDSRank::send_message()
|__Connection::send_message() 调用Connection的send_message()函数发送消息
MDSRank::send_message_mds()
|__检查mdsmap中对端MDS是否是up状态,若不是则直接返回
|__对于对端MDS的MDSMap不是最新的
|__messenger->send_message() 将最新的MDSMap发送给对端MDS
|__peer_mdsmap_epoch[mds] = mdsmap->get_epoch() 更新对端MDSMap所拥有的epoch值
|__messenger->send_message() 将消息发送给对端MDS
MDSRank::forward_message_mds()
|__对于消息类型是CEPH_MSG_CLIENT_REQUEST
|__messenger->send_message(MClientRequestForward()) 将client发送过来的消息转发到目的MDS处
|__对于对端MDS的MDSMap不是最新的
|__messenger->send_message() 将最新的MDSMap发送给对端MDS
|__peer_mdsmap_epoch[mds] = mdsmap->get_epoch() 更新对端MDSMap所拥有的epoch值
|__messenger->send_message() 将消息发送给对端MDS
MDSRank::send_message_client()
|__若session->connection不为空
|__session->connection->send_message() 发送消息到client端
|__若session->connection为空
|__session->reopen_out_queue.push_back() 将消息插入消息队列中等待connection重新建立完毕后再发送
============================ProgressThread线程相关==========================
MDSRank::ProgressThread::entry() ProgressThread核心处理函数
|__若当前没有需要处理的内容
|__cond.Wait()
|__若stopping==true
|__退出核心处理函数
|__MDSRank::_advance_queues()
MDRank::ProgressThread::shutdown()
|__调用线程库函数join()
=========================MDSRank boot相关======================================
MDSRank::boot_start() 作为类C_MDS_BootStart的回调函数
|__若返回值小于0(执行boot过程中有错误出现)
|__当前状态是STANDBY_REPLAY并且返回值是EAGAIN
|__respawn()
|__返回值是EINVAL或ENOENT
|__damaged()
|__返回值不是上述的情况
|__suicide()
|__判断当前所处的BootStep阶段
|__MDS_BOOT_INITIAL
|__MDCache::init_layouts()
|__创建MDSGatherBuilder类实例且设置下一个BootStep阶段为MDS_BOOT_ROOT
|__InoTable::set_rank() 设置InoTable的rank值
|__InoTable::load() 加载InoTable
|__SessionMap::set_rank() 设置SessionMap的rank值
|__SessionMap::load() 加载SessionMap
|__MDLog::open() 打开MDLog
|__SnapServer::set_rank() 设置SnapServer的rank值
|__SnapServer::load() 加载SnapServer
|__MDSGatherBuilder::activate()
|__MDS_BOOT_ROOT 打开或创建ROOT inode
|__创建MDSGatherBuilder类实例且设置下一个BootStep阶段为MDS_BOOT_PREPARE_LOG
|__MDCache::open_mydir_inode() 加载mydir的inode
|__当前处于Starting状态或者当前MDS节点是MDSMap的根节点
|__MDCache::open_root_inode()
|__当前不是处于Starting状态或者当前MDS节点不是MDSMap的根节点
|__MDCache::create_root_inode()
|__MDSGatherBuilder::activate()
|__MDS_BOOT_PREPARE_LOG
|__当前MDS处于replay状态
|__MDLog::replay() 执行replay操作
|__当前MDS不是处于replay状态
|__MDLog::append()
|__starting_done()
|__MDS_BOOT_REPLAY_DONE
|__replay_done()
MDRank::starting_done()
|__request_state(STATE_ACTIVE) 设置当前状态为ACTIVE
|__MDCache::open_root()
|__MDLog::start_new_segment()
MDSRank::creating_done()
|__request_state(STATE_ACTIVE)
MDSRank::boot_create()
|__创建MDSGatherBuilder类实例且执行完毕后执行回调函数creating_done()
|__MDCache::init_layouts()
|__SnapServer::set_rank()
|__InoTable::set_rank()
|__SessionMap::set_rank()
|__MDLog::create()
|__MDLog::prepare_new_segment()
|__若MDS节点是MDSMap的根节点
|__MDCache::create_empty_hierarchy()
|__MDCache::create_mydir_hierarchy()
|__InoTable::reset()
|__InoTable::save()
|__SessionMap::save()
|__SnapServer::reset()
|__SnapServer::save()
|__MDLog::journal_segment_subtree_map()
|__MDLog::flush()
|__MDSGatherBuilder::activate()
=====================replay相关=============================
MDSRank::calc_recovery_set()
|__MDSMap::get_recovery_mds_set() 从MDSMap中获取到处于recovery状态的所有MDS节点
|__从recovery状态下的MDS节点中删除此MDS节点
|__MDCache::set_recovery_set() 更新MDCache中的recovery_set值
MDSRank::replay_start()
|__设置standby_replaying=true
|__calc_recovery_set()
|__Objecter::wait_for_map() 获取上次失败前最新的osdmap
|__boot_start()
MDSRank::_standby_replay_restart_finish()
|__若处于standby MDS的journal小于active MDS的journal的expire_pos
|__respawn() 重新启动MDS
|__若处于standby MDS的journal大于active MDS的journal的expire_pos
|__MDLog::standby_trim_segments()
|__boot_start(MDS_BOOT_PREPARE_LOG) 调用boot_start()函数进行replay操作
MDSRank::standby_replay_restart()
|__standby_replaying==true
|__MDLog::get_journaler()->reread_head_and_probe() 得到journal的head和probe信息后,执行回调函数_standby_replay_restart_finish
|__standby_replaying==false
|__Objecter::wait_for_map() 获取上次失败前最新的osdmap
|__成功获取最新的osdmap
|__MDLog::get_journaler()->reread_head_and_probe() 得到journal的head和probe信息后,执行回调函数_standby_replay_restart_finish
MDSRank::replay_done()
|__若处于standby replay状态
|__设置定时器,当定时器超时后执行standby_replay_restart()
|__若此时正处于replaying(standby_replaying==true)
|__设置standby_replaying=false
|__standby_replay_restart() 重新启动standby replay
|__若处于replay完成状态
|__journal read的位置应该和journal write的位置重合
|__设置MDS journal writable
|__SessionMap::save() 保存SesionMap
|__InoTable::save() 保存InoTable
|__若此时只有一个MDS
|__request_state(STATE_RECONNECT) 设置当前状态为RECONNECT
|__若此时有多个MDS
|__request_state(STATE_RESOVE) 设置当前状态为RESOLVE
==================resolve相关===========================
MDSRank::reopen_log()
|__MDCache::rollback_uncommitted_fragments() 在MDCache中回滚未提交的fragments
MDSRank::resolve_start()
|__reopen_log()
|__MDCache::resolve_start() 调用MDSCache之行resolve,当之行完毕后调用回调函数resolve_done()
MDSSRank::resolve_done()
|__request_state(STATE_RECONNECT) 设置当前状态为RECONNECT
====================reconnect相关==========================
MDSRank::reconnect_start()
|__若last_state==STATE_REPLAY
|__reopen_log()
|__Server::reconnect_client() 调用Server重新与client进行连接,连接成功后执行回调函数reconnect_done()
MDSRank::reconnect_done()
|__request_state(STATE_REJOIN) 设置当前状态为REJOIN
=====================rejoin相关============================
MDSRank::rejoin_joint_start()
|__MDCache::rejoin_send_rejoins()
MDSRank::rejoin_start()
|__MDCache::rejoin_start() 调用MDCache之行rejoin操作,之行完毕后执行回调函数rejoin_done()
MDSRank::rejoin_done()
|__MDCache::show_subtrees()/show_cache()
|__若replay_queue为空
|__request_state(STATE_ACTIVE)
|__若replay_queue不为空
|__request_state(STATE_CLIENTREPLAY)
=======================clientreplay相关==============================
MDSRank::clientreplay_start()
|__queue_one_replay()
MDSRank::queue_on_replay()
|__若replay_queue为空
|__若MDSCache::get_num_client_requests()==0
|__clientreplay_done() client replay完成
|__replay_queue不为空
|__queue_waiter() 从replay_queue队列中取出一个请求待处理
MDSRank::clientreplay_done()
|__request_state(STATE_ACTIVE)
==========================active相关================================
MDSRank::active_start()
|__若last_state==STATE_CREATING
|__MDCache::open_root()
|__MDCache::clean_open_file_lists()
|__MDCache::export_remaining_imported_caps()
|__MDCache::reissue_all_caps()
==========================recovery相关==========================
MDSRank::recovery_done()
|__若MDSMap中的tableserver==whoami
|__从MDSMap中得到clientreplay/active/stopping状态下的MDS节点
|__SnapServer::finish_recovery()
|__MDSCache::start_recovered_truncates()
|__MDSCache::do_file_recover()
|__MDSCache::populate_mydir()
=======================stopping相关========================
MDSRank::stopping_start()
|__MDCache::shutdown_start()
MDSRank::stopping_done()
|__request_state(STATE_STOPPED)
=========================handle mdsmap相关==============================
MDSRankDispatcher::handle_mds_map(MMDSMap *m, MDSMap *oldmap)
|__得到MDS进程的当前状态oldstate = state
|__从MDSMap中得到最新的state
|__更新peer_mdsmap_epoch[] = epoch 更新对端mdsmap的epoch值
|__根据oldstate和state判断更新的状态是否有效
|__无效,则调用respawn()
|__Beacon::set_want_state(state) 更新Beacon的当前state值
|__之前的状态是recover,现在的状态是active或clientreplay
|__recovery_done() 表示完成了recover
|__active状态
|__active_start()
|__replay状态
|__replay_start()
|__resolve状态
|__resolve_start()
|__reconnect状态
|__reconnect_start()
|__rejoin状态
|__rejoin_start()
|__clientreplay状态
|__clientreplay_start()
|__creating状态
|__boot_create()
|__starting状态
|__boot_start()
|__stopping状态
|__stopping_start()
|__oldmap不是resolving而mdsmap是resolving
|__MDSMap::get_mds_set(STATE_RESOLVE)
|__calc_recovery_set()
|__MDCache::send_resolves()
|__oldmap不是rejoining而mdsmap是rejoining
|__rejoin_joint_start()
|__oldstate>=STATE_REJOIN
|__从old mdsmap和new mdsmap中分别取出STATE_ACTIVE/STATE_CLIENTREPLAY/STATE_REJOIN的MDS
|__遍历new mdsmap中的这些MDS
|__MDS不在old mdsmap中 新的MDS
|__MDCache::kick_recovers()
|__MDCache::kick_open_ino_peers()
|__oldstate>=STATE_CLIENTREPLAY
|__从old mdsmap和new mdsmap中分别取出STATE_ACTIVE/STATE_CLIENTREPLAY的MDS
|__遍历new mdsmap中的这些MDS
|__MDS不在old mdsmap中 新的MDS
|__handle_mds_recovery()
|__从old mdsmap和new mdsmap中分别取出down的MDS
|__遍历new mdsmap中的这些MDS
|__MDS不在old mdsmap中 新的down掉的MDS
|__Messenger::mark_down()
|__handle_mds_failure()
|__从new mdsmap中得到所有up状态的MDS
|__遍历new mdsmap中的这些MDS
|__在old mdsmap中存在但是inst内容不一致 新的MDS修改了inst
|__Messenger::mark_down()
|__handle_mds_failure()
|__从old mdsmap和new mdsmap中得到所有stopped状态的MDS
|__遍历new mdsmap中的这些MDS
|__在old mdsmap中不存在 新的MDS stopped了
|__MDCache::migrator::handle_mds_failure_or_stop()
|__当前没有replay状态的MDS
|__MDBalancer::try_rebalance()
|__遍历waiting_for_mdsmap数组
|__唤醒该数组中所有成员
|__当前状态是active
|__set_osd_epoch_barrier()
|__MDCache::noteify_mdsmap_changed()
MDSRank::handle_mds_recovery()
|__MDCache::handle_mds_recovery()
|__SnapServer::handle_mds_recovery()
|__queue_waiter(waiting_for_active_peer[who])
MDSRank::handle_mds_failure()
|__MDCache::handle_mds_failure()
|__SnapClient::handle_mds_failure()
php mds函数,MDSRank类解析 - linux_hunter的个人页面 - OSCHINA - 中文开源技术交流社区...相关推荐
- java中加载窗口的函数_Java函数调用 - playgame的个人页面 - OSCHINA - 中文开源技术交流社区...
Java函数调用和存储过程一样步骤如下: 1. 编写自定义的函数,或调用系统函数,为简单起见,我调用Mysql CONCAT()函数. 2.编写java调用测试类,可以是main方法,也可以JUnit ...
- linux fflush函数,fflush - wwliu的个人页面 - OSCHINA - 中文开源技术交流社区
概述 函数名: fflush 功 能: 清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件 头文件: #include 原型:int fflush(FILE *stream) #include # ...
- java的异常解析_java异常解析 - liop的个人空间 - OSCHINA - 中文开源技术交流社区...
抛出异常,捕捉异常,输出异常. /** * 自定义异常类 */ public class CustomerException extends RuntimeException { private St ...
- php 原理 淘口令 解密_淘口令解析 - super19911115的个人空间 - OSCHINA - 中文开源技术交流社区...
淘口令解析 通过程序解析淘口令,无需联盟开发者权限,只需几行代码就可实现自动识别淘口令: def query_password(sign_server, share_password): data = ...
- java绘制统计直方图取平均_统计学——直方图解析 - osc_lv8qb16y的个人空间 - OSCHINA - 中文开源技术交流社区...
直方图(Histogram),又称质量分布图,是一种统计报告图, 由一系列高度不等的纵向条纹或线段表示数据分布的情况. 一般用 横轴表示数据类型,纵轴表示分布情况. 直方图是数值数据分布的精确图形表示 ...
- 泊松分酒 java课件_泊松分酒原理 - 我类个擦的个人空间 - OSCHINA - 中文开源技术交流社区...
有一个12品脱(pint)的酒瓶,里面装满葡萄酒,另有8品脱和5品脱的瓶子各一个.问如何从中分出6品脱的酒出来? 传说泊松年轻时成功解决了该问题,勾起了他对数学的兴趣而投身数学研究,因此该问题被称为泊 ...
- 三个瓶子分酒c语言源码,泊松分酒原理 - 我类个擦的个人空间 - OSCHINA - 中文开源技术交流社区...
有一个12品脱(pint)的酒瓶,里面装满葡萄酒,另有8品脱和5品脱的瓶子各一个.问如何从中分出6品脱的酒出来? 传说泊松年轻时成功解决了该问题,勾起了他对数学的兴趣而投身数学研究,因此该问题被称为泊 ...
- java回调函数的生命_Java的回调函数 - choaklin 的个人空间 - OSCHINA - 中文开源技术交流社区...
暂且不提回调函数的各种定义,如我本人,虽然知道JavaScript的回调的使用,但是百科了回调的定义,还是觉得云里来雾里去.所以大可先从已熟悉的入手,旁推侧引它的原理,再引出Java版的实现. 因为博 ...
- C语言调用自定义交换函,C语言函数篇 - personal page of Msingwen - OSCHINA - 中文开源技术交流社区...
函数(一): 函数知识点 函数:能实现某种特定功能的代码 分为系统函数(内置函数) (例如printf scanf getchar putchar time ..) 和 自定义函数 两类! ...
最新文章
- 【Android 逆向】Android 中常用的 so 动态库 ( libdvm.so | libart.so | libandroid_runtime.so | libandroidfw.so )
- 作为本科大学生比较适合的水准比较好的,嵌入式软件系统的会议
- windows 10安装gensim、nltk
- C++ Primer 7.33 练习编写成员函数
- 怎样用php写入数据库表,PHP如何将数据写入到MYSQL数据库
- cocos2dx打飞机项目笔记二:BulletLayer类
- 笔记本电脑自带麦克风吗_想让声音变得好听吗,不花一分钱,让你的电脑拥有外置麦克风...
- 《云服务器》与《传统服务器》的区别
- 剑指offer(C++)-JZ77:按之字形顺序打印二叉树(数据结构-树)
- 开课吧:数据分析的价值体现在哪些方面?
- 第一节 MongoDB介绍及下载与安装
- 微信购物商城系统怎样吸引住客户,来转换为商城系统的粉丝?
- 北斗卫星定位系统原理
- 降雨量等值线图(一)——底图整饬
- PTA 乙级 1003 我要通过! (20 分) C++
- 云计算开发技术Python自动化运维开发实战二
- PCB布局和绘制的关键操作
- 曹翱,我永远爱你(FOR循环和WHILE循环讲解)
- android手机备份恢复出厂设置密码,手机恢复出厂设置 如何让安卓手机恢复出厂设置经验分享...
- ASO优化:为什么要做APP竞品分析
热门文章
- hive Cannot truncate non-managed table
- Unity 托管内存(Managed Memory)
- linux cpu 查看微码,intel cpu微码 intel官网下的cpu微码 - 下载 - 搜珍网
- Apollo星火计划学习笔记——Control 专项讲解(PID)
- Java医院预约挂号系统
- narwal机器人_中国黑科技扫地机器人云鲸NARWAL将强势回归国内市场
- ts定义数组类型_ts中类型
- 程序员的四个等级:菜鸟、普通、大牛、大神
- 苹果浏览器无法边下边播MP4(谷歌浏览器可以)
- oracle 数据库锁 lock mode 的几种类型