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

C++ 网络编程项目fastDFS分布是文件系统(一)

目录

1.项目架构图

1. 项目架构图

1.1 一些概念

1.2 项目架构图

2. 分布式文件系统

2.1 传统文件系统

2.2 分布式文件系统

3. FastDFS

3.1 fastDFS介绍

3.2 fastDFS安装

3.3 fastDFS配置文件

3.4 fastDFS的启动

4. fastDFS状态检测

4.1 对file_id的解释

4. 2上传下载代码实现

5. 源码安装 - 回顾


1.项目架构图

        

1. 项目架构图

1.1 一些概念

  1. 什么是服务器

    • 硬件: 一台配置高的电脑
    • 软件: 电脑必须有一个能够解析http协议的软件
  2. 常见的Web服务器

    • tomcat服务器

      • apache组织产品, 开源的免费服务器
    • weblogic 服务器

      • bea公司, 收费的服务器
      • 不交费, 访问量受限制
    • IIS服务器

      • Internet Information Server

      • 微软公司主推的服务器

    • nginx

      • 小巧且高效的HTTP服务器
      • 也可以做一个高效的负载均衡反向代理
      • 邮件服务器
        • pop3/smtp/imap

1.2 项目架构图

        

 

 

1. 客户端

   - 网络架构:

     - b/s

       - 必须使用http协议

     - c/s

       - 协议可以随意选择

       - Qt -> http

2. 服务器

   - Nginx

     - 能处理静态请求 -> html, jpg

     - 动态请求无法处理

     - 服务器集群之后, 每台服务器上部署的内容必须相同

   - fastCGI

     - 帮助服务器处理动态请求

3. 反向代理服务器

   - 客户端并不能直接访问web服务器, 直接访问到的是反向代理服务器

   - 客户端静请求发送给反向代理服务器, 反向代理将客户端请求转发给web服务器

4. 关系型数据库

   - 存储文件属性信息

   - 用户的属性信息

5. redis - 非关系型数据库 (内存数据库)

   - 作用提出程序效率

   - 存储是服务器经常要从关系型数据中读取的数据

6. FASTDFS - 分布式文件系统

   - 存储文件内容

   - 供用户下载

2. 分布式文件系统

2.1 传统文件系统

- 传统的文件系统格式:

  - ntfs / fat32 / ext3 / ext4

- 可以被挂载和卸载

2.2 分布式文件系统

> 文件系统的全部, 不在同一台主机上,而是在很多台主机上,多个分散的文件系统组合在一起,形成了一个完整的文件系统。

分布式文件系统:

 1. 需要有网络

   2. 多台主机

     - 不需要在同一地点

> 3. 需要管理者

> 4. 编写应用层的管理程序

     - 不需要编写

        

3. FastDFS

3.1 fastDFS介绍

1. fastDFS概述

   > - 是用**c语言**编写的一款开源的分布式文件系统。

   >   - 余庆 - 淘宝的架构师

   > - 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,注重高可用、高性能等指标

   >   - 冗余备份: 纵向扩容

   >   - 线性扩容: 横向扩容

   > - 可以很容易搭建一套高性能的文件服务器集群提供文件==**上传、下载**==等服务。

   >   - 图床

   >   - 网盘

2. fastDFS框架中的三个角色

   - 追踪器 ( Tracker ) - 管理者 - 守护进程

     - 管理存储节点

   - 存储节点 - storage - 守护进程

     - 存储节点是有多个的

   - 客户端 - 不是守护进程, 这是程序猿编写的程序

     - 文件上传

     - 文件下载

3. fastDFS三个角色之间的关系

 

 

1. 追踪器

      - 最先启动追踪器

   2. 存储节点

      - 第二个启动的角色

      - 存储节点启动之后, 会单独开一个线程

        - 汇报当前存储节点的容量, 和剩余容量

        - 汇报数据的同步情况

        - 汇报数据被下载的次数

   3. 客户端

      - 最后启动

        - 上传

          - 连接追踪器, 询问存储节点的信息

            - 我要上传1G的文件, 询问那个存储节点有足够的容量

            - 追踪器查询, 得到结果

            - 追踪器将查到的存储节点的IP+端口发送给客户端

            - 通过得到IP和端口连接存储节点

            - 将文件内容发送给存储节点

        - 下载

          - 连接追踪器, 询问存储节点的信息

            - 问一下, 要下载的文件在哪一个存储节点

            - 追踪器查询, 得到结果

            - 追踪器将查到的存储节点的IP+端口发送给客户端

            - 通过得到IP和端口连接存储节点

            - 下载文件

4. fastDFS集群

 

1. 追踪器集群

  •       - 为什么集群?
  •         - 避免单点故障
  •       - 多个Tracker如何工作?
  •         - 轮询工作
  •       - 如何实现集群?
  •         - 修改配置文件

   2. 存储节点集群

  •       - fastDFS管理存储节点的方式?
  •         - 通过分组的方式完成的
  •       - 集群方式(扩容方式)
  •         - 横向扩容 - 增加容量
  •           - 添加一台新的主机 -> 容量增加了
  •           - 假设当前有两个组: group1, group2
  •             - 需要添加一个新的分组 -> group3
  •               - 新主机属于第三组
  •           - 不同组的主机之间不需要通信
  •         - 纵向扩容 - 数据备份
  •           - 假设当前有两个组: group1, group2
  •             - 将新的主机放到现有的组中
  •             - 每个组的主机数量从1 -> N
  •               - 这n台主机的关系就是相互备份的关系
  •               - 同一个组中的主机需要通信
  •               - 每组的容量 == 容量最小的这台主机
  •       - 如何实现?
  •         - 通过修改配置文件可实现

3.2 fastDFS安装

1. fastDFS安装

   - libfastcommon-1.36.zip

     - fastdfs的基础库包

     - unzip xxx.zip

     - ./make.sh

     - ./make.sh install

   - fastdfs-5.10.tar.gz

     - tar zxvf xxx.tar.gz(x表示解压缩,z 表示gz)

     - ./make.sh

     - ./make.sh install

2. 测试

   ```shell

   #fastDFS安装的所有的可执行程序:

   /usr/bin/fdfs_*

   fdfs_test

   ```

        进入到root用户 sudo su-   退出exit

1. fastDFS安装

   - libfastcommon-1.36.zip

     - fastdfs的基础库包

     - unzip xxx.zip

     - ./make.sh

     - ./make.sh install

   - fastdfs-5.10.tar.gz

     - tar zxvf xxx.tar.gz(x表示解压缩,z 表示gz)

     - ./make.sh

     - ./make.sh install

2. 测试

   ```shell

   #fastDFS安装的所有的可执行程序:

   ls /usr/bin/fdfs_*

   (ls fdfs_* 是一个命令,用于列出以 "fdfs_" 开头的文件或目录)

   fdfs_test

   ```

 

3.3 fastDFS配置文件

配置文件默认位置:  /etc/fdfs

 

> client.conf.sample  storage.conf.sample  storage_ids.conf.sample  tracker.conf.sample

1. tracker 配置文件

   ```shell

   # 将追踪器和部署的主机的IP地址进程绑定, 也可以不指定

   # 如果不指定, 会自动绑定当前主机IP, 如果是云服务器建议不要写(ctrl+shift +v )在vi 编辑器里面复制内容

   bind_addr=192.168.247.135

   # 追踪器监听的端口

   port=22122

   # 追踪器存储日志信息的目录, xxx.pid文件, 必须是一个存在的目录

   base_path=/home/yuqing/fastdfs

   ```

2. storage 配置文件

   ```shell

   # 当前存储节点对应的主机属于哪一个组

   group_name=group1

   # 当前存储节点和所应该的主机进行IP地址的绑定, 如果不写, 有fastdfs自动绑定

   bind_addr=

   # 存储节点绑定的端口

   port=23000

   # 存储节点写log日志的路径

   base_path=/home/yuqing/fastdfs

   # 存储节点提供的存储文件的路径个数

   store_path_count=2

   # 具体的存储路径

   store_path0=/home/yuqing/fastdfs

   store_path1=/home/yuqing/fastdfs1

   # 追踪器的地址信息

   tracker_server=192.168.247.135:22122

   tracker_server=192.168.247.136:22122

   ```

3. 客户端配置文件

   ```shell

   # 客户端写log日志的目录

   # 该路径必须存在

   # 当前的用户对于该路径中的文件有读写权限

   # 当前用户robin

   # 指定的路径属于root

   base_path=/home/yuqing/fastdfs

   # 要连接的追踪器的地址信息

   tracker_server=192.168.247.135:22122

   tracker_server=192.168.247.136:22122

   ```

vi 编辑器撤销的快捷键

在Vi编辑器中,撤销操作通常由以下快捷键完成:

  1. 撤销上一步操作:

    • 在普通模式下,按下 u 键。
  2. 撤销多个操作:

    • 在普通模式下,输入数字加上 u 键。例如,要撤销最近的两个操作,可以按下 2u

请注意,撤销操作是逐步递减的,意味着每次按下 u 键,都会撤销先前的操作,直到没有更多的操作可撤销为止。

如果你误操作或者需要撤销更多的步骤,你可以重复按下 u 键来连续执行撤销操作。记住,这些操作都是在普通模式下完成的。

总结:

  • 进入普通模式。
  • 按下 u 键来逐步撤销操作。
  • 按下数字加上 u 键来撤销多个操作。

这些快捷键可帮助你在Vi编辑器中轻松地进行撤销操作。

vi 编辑器反撤销的快捷键

在Vi编辑器中,反撤销操作通常由以下快捷键完成:

  1. 反撤销上一步操作:
    • 在普通模式下,按下 Ctrl + r 键。

与撤销操作类似,反撤销操作也是逐步递减的。每次按下 Ctrl + r 键,都会重新应用之前被撤销的操作,直到没有更多的操作可反撤销为止。

请注意,反撤销操作是在普通模式下完成的。

总结:

  • 进入普通模式。
  • 按下 Ctrl + r 键来逐步进行反撤销操作。

这些快捷键可以帮助你在Vi编辑器中进行反撤销操作,恢复之前被撤销的更改

 

 

3.4 fastDFS的启动

1. 第一个启动追踪器  - 守护进程

   ```shell

   # 启动程序在 /usr/bin/fdfs_*

   # 启动

   fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf)

   # 关闭

   fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf)  stop

   # 重启

   fdfs_trackerd 追踪器的配置文件(/etc/fdfs/tracker.conf) restart

   ```

查看

ps aux|grep fdfs_*

2. 第二个启动存储节点 - 守护进程

   ```shell

   # 启动

   fdfs_storaged 存储节点的配置文件(/etc/fdfs/stroga.conf)

   # 关闭

   fdfs_storaged 存储节点的配置文件(/etc/fdfs/stroga.conf) stop

   # 重启

   fdfs_storaged 存储节点的配置文件(/etc/fdfs/stroga.conf) restart

   ```

3. 最后启动客户端 - 普通进程

   ```shell

   # 上传

   fdfs_upload_file 客户端的配置文件(/etc/fdfs/client.conf) 要上传的文件

 

 

 

   # 得到的结果字符串: group1/M00/00/00/wKj3h1vC-PuAJ09iAAAHT1YnUNE31352.c

   # 下载

   fdfs_download_file 客户端的配置文件(/etc/fdfs/client.conf) 上传成功之后得到的字符串(fileID)

   ```

4. fastDFS状态检测

    - 命令

      ```shell

      fdfs_monitor /etc/fdfs/client.conf

      ```

    - [Storage Server的7种状态](https://blog.csdn.net/u014723529/article/details/46048411)

      https://blog.csdn.net/u014723529/article/details/46048411

      ```shell

      # FDFS_STORAGE_STATUS:INIT      :初始化,尚未得到同步已有数据的源服务器

      # FDFS_STORAGE_STATUS:WAIT_SYNC :等待同步,已得到同步已有数据的源服务器

      # FDFS_STORAGE_STATUS:SYNCING   :同步中

      # FDFS_STORAGE_STATUS:DELETED   :已删除,该服务器从本组中摘除

      # FDFS_STORAGE_STATUS:OFFLINE   :离线

      # FDFS_STORAGE_STATUS:ONLINE    :在线,尚不能提供服务

      # FDFS_STORAGE_STATUS:ACTIVE    :在线,可以提供服务

      ```

 

4.1 对file_id的解释

        

  • - group1

  - 文件上传到了存储节点的哪一个组

  - 如果有多个组这个组名可变的

  • - M00 - 虚拟目录

  - 和存储节点的配置项有映射

    - store_path0=/home/yuqing/fastdfs/data    ->  M00

      store_path1=/home/yuqing/fastdfs1/data   -> M01

  • - 00/00

  - 实际的路径

  - 可变的

- wKhS_VlrEfOAdIZyAAAJTOwCGr43848.md

  - 文件名包含的信息

  - 采用Base64编码

    - 包含的字段包括

      - 源storage server Ip 地址  

      - 文件创建时间  

      - 文件大小  

      - 文件CRC32效验码

        - 循环冗余校验  

      - 随机数

4. 2上传下载代码实现

1. 使用多进程方式实现

   - exec函数族函数

     - execl

     - execlp

  •    - 父进程

     - 子进程 -> 执行

       execlp("fdfs_upload_file" , "xx", arg, NULL), 有结果输出, 输出到终端

       - 不让它写到终端 -> 重定向dup2(old, new)

         - old-> 标准输出

         - new -> 管道的写端

         - 文件描述符

         - 数据块读到内存 -> 子进程

                   - 数据最终要给到父进程

       - pipe -> 读端, 写端

         - 在子进程创建之前创建就行了

  •      - 父进程

       - 读管道 -> 内存

       - 内存数据写数据库

2. 使用fastDFS API实现

     

5. 源码安装 - 回顾

安装流程:

1. 以下文件, 里边有安装步骤

   - readme

   - readme.md

   - INSTALL

2. 找 可执行文件 <font color=green>configure</font>

   - 执行这个可执行文件

     - 检测安装环境

     - 生成 makefile

3. 执行**make**命令

   - 编译源代码

     - 生成了动态库

     - 静态库

     - 可执行程序

4. 安装 **make install** (需要管理员权限)

   - 将第三步生成的动态库/动态库/可执行程序拷贝到对应的系统目录

 

相关文章:

C++ 网络编程项目fastDFS分布是文件系统(一)

目录 1.项目架构图 1. 项目架构图 1.1 一些概念 1.2 项目架构图 2. 分布式文件系统 2.1 传统文件系统 2.2 分布式文件系统 3. FastDFS 3.1 fastDFS介绍 3.2 fastDFS安装 3.3 fastDFS配置文件 3.4 fastDFS的启动 4. fastDFS状态检测 4.1 对file_id的解释 4. 2上传…...

PoseiSwap 开启“Poseidon”池,治理体系或将全面开启

PoseiSwap 曾在前不久分别以 IDO、IEO 的方式推出了 POSE 通证&#xff0c;但 PoseiSwap DEX 中并未向除 Zepoch 节点外的角色开放 POSE 资产的交易。而在前不久&#xff0c;PoseiSwap 推出了全新的“Poseidon”池&#xff0c;该池将向所有用户开放&#xff0c;并允许用户自由的…...

【C/C++】重载运算符特性

重载运算符是 C 中的一个重要特性&#xff0c;它允许程序员自定义类类型的运算符行为。重载运算符的使用场景包括&#xff1a; 使类类型的对象能够像内置类型一样进行运算&#xff1a;例如&#xff0c;可以重载加号运算符&#xff0c;使两个对象相加时能够像两个整数相加一样。…...

HTML+JavaScript构建一个将C/C++定义的ANSI字符串转换为MASM32定义的DWUniCode字符串的工具

公文一键排版系统基本完成&#xff0c;准备继续完善SysInfo&#xff0c;增加用户帐户信息&#xff0c;其中涉及到Win32_Account结构&#xff0c;其C定义如下&#xff1a; [Dynamic, Provider("CIMWin32"), UUID("{8502C4CC-5FBB-11D2-AAC1-006008C78BC7}"…...

24届近3年南京信息工程大学自动化考研院校分析

今天给大家带来的是南京信息工程大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、南京信息工程大学 学校简介 南京信息工程大学位于南京江北新区&#xff0c;是一所以大气科学为特色的全国重点大学&#xff0c;由江苏省人民政府、中华人民共和国教育部、中国气…...

【LeetCode】1572.矩阵对角线元素的和

题目 给你一个正方形矩阵 mat&#xff0c;请你返回矩阵对角线元素的和。 请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。 示例 1&#xff1a; 输入&#xff1a;mat [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;25 解释&#xff1a;对角线的和为&a…...

2023-08-08 Ubuntu 挂载U盘 fdisk -l 、sudo mount /dev/sdb1 /mnt/mydisk

一、基本命令 1、插入U盘&#xff0c;查看U盘是否被系统识别&#xff1a; 打开终端&#xff0c;输入&#xff1a; sudo fdisk -l 查看系统是否识别U盘&#xff0c;如果识别&#xff0c;会显示U盘的相关信息&#xff0c;如果没有识别&#xff0c;则说明系统没有识别U盘。 2…...

make/makefile/cmake/nmake

最近&#xff0c;有没有被make、cmake、makefile... ... 这些东西绕晕了&#xff0c;看看下面的文章&#xff0c;也许就可以理解清楚了。 1. gcc 它是GNU Compiler Collection&#xff08;就是GNU编译器套件&#xff09;&#xff0c;也可以简单认为是编译器&#xff0c;它可以…...

实用的开源应用全新开源源码Vue3+TS的前后台分离的开发平台源码开源技术社区平台

开源全新开源源码Vue3TS的前后台分离的开发平台源码。创意、新奇、有趣、实用的开源应用、系统、软件、硬件及技术&#xff0c;一个探索、发现、分享、使用与互动交流的开源技术社区平台。致力于打造活力开源社区&#xff0c;共建开源新生态&#xff01; 功能简介 个人办公&a…...

C++复习笔记——primer第五版

文章目录 一、引用和指针1.引用2.指针2.1利用指针访问对象2.2指针的值或指针所指对象的值的改变 3.赋值和指针4.指向指针的引用 二、String1.初始化String对象的方式2. string对象上的操作3.使用getline读取一整行4.字面值和字符串相加5.使用for循环改变字符串中的字符 三、Vec…...

ElasticSearch:项目实战(2)

ElasticSearch: 项目实战 (1) 需求&#xff1a; 新增文章审核通过后同步数据到es索引库 1、文章服务中添加消息发送方法 在service层文章新增成功后&#xff0c;将数据通过kafka消息同步发送到搜索服务 Autowiredprivate KafkaTemplate<String,String> kafkaTemplate;/…...

Eleastisearch5.2.2利用镜像迁移构建实例后ES非健康状态

正常迁移完成后启动服务&#xff0c;查看ES非健康状态 此时观察ES集群状态&#xff1a;curl -XGET -u elastic:xxx localhost:9200/_cluster/health?pretty 注意到"active_shards_percent_as_number" : 88.8888 该项的值不产生变化;集群状态"status" : “…...

sealos安装k8s

一、前言 1、我前面文章有写过使用 kubeadm 安装的方式&#xff0c;大家可以去参考 &#xff08;二&#xff09;k8s集群安装&#xff0c;有一系列的k8s文章说明 2、安装k8s的方式有很多 kubeadmsealoskubespray等等 3、关于sealos来安装 k8s &#xff0c;也是非常建议大家去…...

经典贪吃蛇游戏 - 用 C 语言实现控制台版

在本篇博客中&#xff0c;我们将一起来实现经典的贪吃蛇游戏&#xff0c;使用 C 语言编写&#xff0c;并在控制台中运行。这个小游戏会让你回忆起童年的经典游戏体验。我们将从游戏的初始化开始&#xff0c;逐步实现游戏的各个功能&#xff0c;包括蛇的移动、食物的生成、得分的…...

安灯Andon系统的应用与优势

安灯系统是一款与硬件相结合&#xff0c;实时了解机台与工位状态&#xff0c;让异常的信息得到快速、高效的解决的系统软件&#xff0c;同时记录每次异常报警的种类、响应时间和处理问题用时&#xff0c;提供改善生产管理和人员考核的数据参考&#xff0c;实现透明、快速的生产…...

2023年的C++基础笔记

C 基本语法 对象 - 对象具有状态和行为。例如&#xff1a;一只狗的状态 - 颜色、名称、品种&#xff0c;行为 - 摇动、叫唤、吃。对象是类的实例。 类 - 类可以定义为描述对象行为/状态的模板/蓝图。 方法 - 从基本上说&#xff0c;一个方法表示一种行为。一个类可以包含多个…...

综合能源系统(6)——综合能源综合评估技术

综合能源系统关键技术与典型案例  何泽家&#xff0c;李德智主编 综合能源系统是多种能源系统非线性耦合的、多时间与空间尺度耦合的“源-网-荷一储”一体化系统&#xff0c;通过能源耦合、多能互补&#xff0c;能够实现能源的高效利用&#xff0c;并提高新能源的利用水平。对…...

华为OD机试真题 Java 实现【寻找相同子串】【2023 B卷 100分】,附详细解题思路

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…...

软件外包开发的桌面客户端开发

跨平台桌面客户端开发工具允许开发者在多个操作系统上构建应用程序&#xff0c;从而实现一次编码、多平台运行的目标。以下是几个常见的跨平台桌面客户端开发工具以及它们的特点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&a…...

PAT(Advanced Level) Practice(with python)——1058 A+B in Hogwarts

Code A,B map(str,input().split()) g1,s1,k1 A.split(.) g2,s2,k2 B.split(.) g int(g1)int(g2) s int(s1)int(s2) k int(k1)int(k2) if k>29:s1k%29 if s>17:g1s%17 print(str(g).str(s).str(k))...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...