2024年【秋招面试题】C++ 网络编程 面试题库(一,Jetpack-MVVM高频提问和解答

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2.引用不可以改变指向,对一个对象"至死不渝";但是指针可以改变指向,而指向其它对象,虽然引用不可以改变指向,但是可以改变初始化对象的内容

3.引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节

4.引用比指针更安全。由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。

5.引用仅在声明时带有引用运算符“&”,以后像普通变量一样使用,不能再带“&”,其它场合使用的“&”都是地址操作符。

六、构造函数和析构函数

**构造函数的作用:**用于新建对象的初始化工作。(一个类可以有多个构造函数,构造函数可以重载,不可以加虚函数)
**析构函数的作用:**用于在撤销对象前,完成一些清理工作,比如:释放内存等。(一个类只能有一个析构函数,不可以重载)

**拷贝构造函数:**拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它的唯一的一个参数是本类型的一个引用变量,该参数是const类型,不可变的。

七、深拷贝和浅拷贝

**浅拷贝:**浅拷贝是对指针进行拷贝,拷贝后两个指针指向同一块内存空间。C++中如果不定义类的赋值构造函数,就会调用类的默认赋值构造函数,而类的赋值构造函数是浅拷贝。

**深拷贝:**深拷贝是对指针进行拷贝而且还对内容进行拷贝,拷贝完成后,指针指向的地址不一样,但是值是一样的。

**浅拷贝和深拷贝的区别:**前者就是使用编译器提供的默认拷贝构造函数或者默认赋值构造函数。后者是自己显示实现的拷贝/赋值构造函数。

八、对多态的理解

C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类类,别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。

多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定;动态多态是用虚函数机制实现的,在运行期间动态绑定。

多态的条件:

1.必须有继承

2.要有虚函数重写

3.用父类指针(引用)指向子类对象

多态的基础理论:

**联编:**一个程序模块,代码之间互相关联的过程

**动态联编:**把程序联编的过程,推迟到运行时进行

静态联编

多态的实现效果:

同样的调用语句,不同的表现形态

**多态的意义:**设计模式的基础、编写框架的基础、函数指针做函数参数

九、数据结构有哪些

什么是数据结构:

数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 
**常用的数据结构有:**数组,栈,链表,队列,树,图,堆,散列表等。

**数组:**数组是可以在内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问

**栈:**栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出。

**队列:**队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出。

**链表:**链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等。

**树:**树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。

十、socket包安全

TCP是一个基于字节流的传输服务,"流"意味着TCP所传输的数据是没有边界的。这不同于UDP提供基于消息的传输服务,其传输的数据是有边界的。TCP的发送方无法保证对等方每次接收到的是一个完整的数据包。就会出现分包或粘包的问题.
**分包:**传输数据不完整,一条信息被分成多次发送。 
比如我们发送了一条信息:“你好”,我们可能只收到了“你”,却没有收到“好”,这样就会导致数据的不完整。 
粘包:传输的多条数据粘在一起,比如我发了“你好”和“我是小胖”,我们可能会收到“你好我是小胖”,也可能收到“你好我是”“你好我”“你好我是小”,后几种情况是分包粘包同时发生,我们肯定不期望这种现象发生,所以我们就有必要对我们发送的数据进行编辑。

Socket只是一种通信手段它本身没有任何额外的安全措施,所以要用到加密技术 ,不然通信的数据非常容易初攻击者获取到,一般情况下,我们会使用CRC进行冗余验证,看数据包是否传输完整,然后自定义自己的加密方式,将数据包加密以后再发出,有的项目还会对数据包进行压缩,所以我们这里给出一种通用的结构:数据头(长度)+冗余验证(CRC)+是否压缩+包体(加密后)。

十一、new和malloc的区别

区别New 和deletemalloc和free
属性C++编译器支持库函数、头文件支持C
参数申请内存无需指定内存大小显式指定大小
返回值对象类型的指针泛型,void*类型,再转换为需要的类型
内存区域自由存储区堆上动态分配内存

十二、epoll的 LT 和 ET 模式的理解

epoll 对文件描述符的操作有两种模式:LT(level trigger)和 ET(edge trigger)。LT 模式是默认模式,LT 模式与 ET 模式的区别如下:

LT 模式:支持block和no-block socket。当 epoll_wait 检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用 epoll_wait 时,会再次响应应用程序并通知此事件。效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。

ET 模式:只支持no-block socket。当 epoll_wait 检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用 epoll_wait 时,不会再次响应应用程序并通知此事件。该模式效率非常高,尤其在高并发,大流量的情况下,会比LT少很多epoll的系统调用。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。

十三、TCP/UPD的区别

  • TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,是专门为了在不可靠的网络中提供一个可靠的端对端字节流而设计的,面向字节流。
  • UDP(用户数据报协议)是iso参考模型中一种无连接的传输层协议,提供简单不可靠的非连接传输层服务,面向报文

区别:

1) TCP是面向连接的,可靠性高;UDP是基于非连接的,可靠性低 
2) 由于TCP是连接的通信,需要有三次握手、重新确认等连接过程,会有延时,实时性差,同时过程复杂,也使其易于攻击;UDP没有建立连接的过程,因而实时性较强,也稍安全 
3) 在传输相同大小的数据时,TCP首部开销20字节;UDP首部开销8字节,TCP报头比UDP复杂,故实际包含的用户数据较少。TCP在IP协议的基础上添加了序号机制、确认机制、超时重传机制等,保证了传输的可靠性,不会出现丢包或乱序,而UDP有丢包,故TCP开销大,UDP开销较小 
4) 每条TCP连接只能是点到点的;UDP支持一对一、一对多、多对一、多对多的交互通信

应用场景选择:

  • 对实时性要求高和高速传输的场合下使用UDP;在可靠性要求低,追求效率的情况下使用UDP;
  • 需要传输大量数据且对可靠性要求高的情况下使用TCP

十四、三次握手和四次挥手

三次握手:客户端和服务端建立连接需要三次握手 
第一次:客户端向服务端发送报文,向服务器发送连接请求; 
第二次:服务端向客户端返回ACK报文,通知客户端可以连接; 
第三次:客户端收到服务端报文,正式连接服务端。 
三次握手完成。

四次挥手:客户端要与服务器断开连接,需要四次挥手 
第一次:客户端向服务端发送FIN报文,向服务器发送中断连接请求; 
第二次:服务器收到客户端中断请求,向客户端发送已得知中断请求,但服务器还有资源未处理,需要等待; 
第三次:服务器处理完数据后,再次向客户端发送报文,告诉客户端可以断开连接了; 
第四次:客户端收到服务端断开连接的确认信息后,最后发送信息看是否真的断开连接了,如果服务器一段时间没有回应,则说明已经断开,中断过程完成; 
四次挥手完成。

十五、socket的概念和特点

socket概念:

这是为了实现以上的通信过程而建立成来的通信管道,其真实的代表是客户端和服务器端的一个通信进程,双方进程通过socket进行通信,而通信的规则采用指定的协议。

socket只是一种连接模式,不是协议,socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。tcp、udp,简单的说(虽然不准确)是两个最基本的协议,很多其它协议都是基于这两个协议如,http就是基于tcp的,.用socket可以创建tcp连接,也可以创建udp连接。

Socket 传输的特点:

优点:

1)  传输数据为字节级,传输数据可自定义,数据量小(对于手机应用讲:费用低)

2)传输数据时间短,性能高

3)适合于客户端和服务器端之间信息实时交互

4)可以加密,数据安全性强

缺点:

1)需对传输的数据进行解析,转化成应用级的数据

2)对开发人员的开发水平要求高

3)相对于Http协议传输,增加了开发量

十六、gdb调试

GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。

进入gdb后可直接在(gdb)后输入相应命令进行调试操作。

  1. 启动gdb
  2. 查看源码 list
  3. 运行程序 run
  4. 设置断点 break
  5. 单步执行 continue、step、next
  6. 查看变量 printf
  7. 退出调试 quit

十七、面向对象的理解

  1. 面向对象

特点:被动的去实现,分解成一个个的对象

由现实的世界建立的软件模型

优点:效率高、易维护、易复用、易扩展

**缺点:**类调用时需要实例化,开销比较大

**面向对象:**面向对象编程就是把问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事物在整个解决问题的步骤中的行为。

面向对象就是高度实物抽象化(功能划分)、面向过程就是自顶向下的编程(步骤划分)

十八、虚函数的作用

**虚函数的作用:**用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。

**虚函数的实现:**在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。

十九、类和对象的关系

类是对象的概括,对象是类的具体体现

1)**对象:**对象是运行期的基本实体,它是一个封装了数据和操作这些数据的代码的逻辑实体。

2):类是具有相同类型的对象的抽象。一个对象所包含的所有数据和代码可以通过类来构造。

二十、IO复用,epoll和select的区别,opoll和selete的特点

I/O 多路复用是为了解决进程或线程阻塞到某个 I/O 系统调用而出现的技术,使进程或线程不阻塞于某个特定的 I/O 系统调用。

select(),poll(),epoll()都是I/O多路复用的机制。I/O多路复用通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪,就是这个文件描述符进行读写操作之前),能够通知程序进行相应的读写操作

epoll:

epoll支持水平触发和边缘触发,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知

epoll的优点:

**1、没有最大并发连接的限制,**能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口);
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。

3、 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。

Selete:

select 的核心功能是调用tcp文件系统的poll函数,不停的查询,如果没有想要的数据,主动执行一次调度(防止一直占用cpu),直到有一个连接有想要的消息为止。从这里可以看出select的执行方式基本就是不同的调用poll,直到有需要的消息为止。

缺点:

1、每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;

2、同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大;

3、select支持的文件描述符数量太小了,默认是1024。

优点:

1、select的可移植性更好,在某些Unix系统上不支持poll()。

2、select对于超时值提供了更好的精度:微秒,而poll是毫秒。

二十一、客户端与服务器如何通信

1.服务器先用socket()函数来建立一个套接字,用这个套接字完成通信的监听和数据的收发
2.服务器用bind()函数来绑定一个端口号和IP地址,使套接字与指定的端口号和IP地址相关联
3.用服务器调用listen()函数,使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的请求发送
4.客户机用socket()函数建立一个套接字,设定远程IP和端口
5.客户机调用connect()函数连接远程计算机指定的端口。
6.服务器调用accept()函数来接受远程计算机的请求,建立与客户机之间的通信连接
7.建立连接以后,客户机用write()函数或者close()函数向socket中写入数据,也可以用read()函数读区服务器发来的数据
8.服务器用read()函数读区客户机发来的数据,也可以用write()函数或者send()函数来发送数据
9.通信完成以后,使用close()函数关闭socket连接

二十二、堆和栈的区别

栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。

堆由开发人员分配和释放, 若开发人员不释放,程序结束时由 OS 回收,分配方式类似于链表

堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;

(2)空间大小不同。每个进程拥有的栈的大小要远远小于堆的大小。理论上,程序员可申请的堆大小为虚拟内存的大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;

(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。

(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由操作系统进行释放,无需我们手工实现。

(5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率比栈要低得多。

二十三、结构体和类的区别

最本质的一个区别就是默认的访问控制: 
默认的继承访问权限 
struct是public的,class是private的。

二十四、STL中的vector如何实现

STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库。它被容纳于C++标准程序库中,包括容器、算法、迭代器组件。 
vector内部使用动态数组的方式实现的。如果动态数组的内存不够用,就要动态的重新分配,一般是当前大小的两倍,然后把原数组的内容拷贝过去。所以,在一般情况下,其访问速度同一般数组,只有在重新分配发生时,其性能才会下降。注意vector的size()和capacity()是不同的,前者表示数组中元素的多少,后者表示数组有多大的容量。由上面的分析可以看出,使用vector的时候需要注意内存的使用,如果频繁地进行内存的重新分配,会导致效率低下。它的内部使用allocator类进行内存管理,程序员不需要自己操作内存。

vector其中一个特点:内存空间只会增长,不会减小,援引C++ Primer:为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。设想一下,当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。因此STL实现者在对vector进行内存分配时,其实际分配的容量要比当前所需的空间多一些。就是说,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。

二十五、如何保证线程的安全

在大多数软件应用中,线程的数量都不止一个,多线程程序处在一个多变的环境中,可访问的全局变量和堆数据随时都可能被其他的线程改变,这就将“线程安全”的问题提上了议程。那么,如何确保线程的安全呢?

线程安全
一般说来,确保线程安全的方法有这几个:竞争与原子操作、同步与锁、可重入、过度优化

竞争与原子操作
多个线程同时访问和修改一个数据,可能造成很严重的后果。出现严重后果的原因是很多操作被操作系统编译为汇编代码之后不止一条指令,因此在执行的时候可能执行了一半就被调度系统打断了而去执行别的代码了。一般将单指令的操作称为原子的(Atomic),因为不管怎样,单条指令的执行是不会被打断的。

因此,为了避免出现多线程操作数据的出现异常,Linux系统提供了一些常用操作的原子指令,确保了线程的安全。但是,它们只适用于比较简单的场合,在复杂的情况下就要选用其他的方法了。

同步与锁
为了避免多个线程同时读写一个数据而产生不可预料的后果,开发人员要将各个线程对同一个数据的访问同步,也就是说,在一个线程访问数据未结束的时候,其他线程不得对同一个数据进行访问。

同步的最常用的方法是使用锁(Lock),它是一种非强制机制,每个线程在访问数据或资源之前首先试图获取锁,并在访问结束之后释放锁;在锁已经被占用的时候试图获取锁时,线程会等待,直到锁重新可用。

二元信号量是最简单的一种锁,它只有两种状态:占用与非占用,它适合只能被唯一一个线程独占访问的资源。对于允许多个线程并发访问的资源,要使用多元信号量(简称信号量)。

可重入
一个函数被重入,表示这个函数没有执行完成,但由于外部因素或内部因素,又一次进入该函数执行。一个函数称为可重入的,表明该函数被重入之后不会产生任何不良后果。可重入是并发安全的强力保障,一个可重入的函数可以在多线程环境下放心使用。

过度优化
在很多情况下,即使我们合理地使用了锁,也不一定能够保证线程安全,因此,我们可能对代码进行过度的优化以确保线程安全。

二十六、数组和链表的区别

数组

数组的特点:

1.在内存中,数组是一块连续的区域 
2.数组需要预留空间

在使用前需要提前申请所占内存的大小,这样不知道需要多大的空间,就预先申请可能会浪费内存空间,即数组空间利用率低 
**ps:**数组的空间在编译阶段就需要进行确定,所以需要提前给出数组空间的大小(在运行阶段是不允许改变的)

3.在数组起始位置处,插入数据和删除数据效率低。

插入数据时,待插入位置的的元素和它后面的所有元素都需要向后搬移 
删除数据时,待删除位置后面的所有元素都需要向前搬移

4.随机访问效率很高,时间复杂度可以达到O(1)

因为数组的内存是连续的,想要访问那个元素,直接从数组的首地址处向后偏移就可以访问到了

5.数组开辟的空间,在不够使用的时候需要扩容,扩容的话,就会涉及到需要把旧数组中的所有元素向新数组中搬移 
6.数组的空间是从栈分配的

数组的优点:

随机访问性强,查找速度快,时间复杂度为O(1)

数组的缺点:

1.头插和头删的效率低,时间复杂度为O(N) 
2.空间利用率不高 
3.内存空间要求高,必须有足够的连续的内存空间 
4.数组空间的大小固定,不能动态拓展

链表

链表的特点:

1.在内存中,元素的空间可以在任意地方,空间是分散的,不需要连续 
2.链表中的元素都会两个属性,一个是元素的值,另一个是指针,此指针标记了下一个元素的地址

每一个数据都会保存下一个数据的内存的地址,通过此地址可以找到下一个数据

3.查找数据时效率低,时间复杂度为O(N)

因为链表的空间是分散的,所以不具有随机访问性,如要需要访问某个位置的数据,需要从第一个数据开始找起,依次往后遍历,直到找到待查询的位置,故可能在查找某个元素时,时间复杂度达到O(N)

4.空间不需要提前指定大小,是动态申请的,根据需求动态的申请和删除内存空间,扩展方便,故空间的利用率较高 
5.任意位置插入元素和删除元素效率较高,时间复杂度为O(1) 
6.链表的空间是从堆中分配的

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

时效率低,时间复杂度为O(N)

因为链表的空间是分散的,所以不具有随机访问性,如要需要访问某个位置的数据,需要从第一个数据开始找起,依次往后遍历,直到找到待查询的位置,故可能在查找某个元素时,时间复杂度达到O(N)

4.空间不需要提前指定大小,是动态申请的,根据需求动态的申请和删除内存空间,扩展方便,故空间的利用率较高 
5.任意位置插入元素和删除元素效率较高,时间复杂度为O(1) 
6.链表的空间是从堆中分配的

[外链图片转存中…(img-v0ZzbCJV-1715591732612)]
[外链图片转存中…(img-Am0MNSI3-1715591732613)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Jetpack是一个结合MVVM的快速开发框架,它基于MVVM模式并集成了谷歌官方推荐的Jetpack组件,包括LiveData、ViewModel、Lifecycle和Navigation组件。这个框架使用Kotlin语言,并添加了大量的拓展函数,以简化代码。它还集成了Retrofit网络请求和协程,可以帮助开发者快速开发项目。\[1\] MVVM是一种软件架构模式,它将应用程序分为三个主要部分:模型(Model)、视图(View)和视图模型(ViewModel)。在MVVM中,视图负责显示数据和用户交互,模型负责处理数据和业务逻辑,而视图模型则充当视图和模型之间的中间层,负责管理视图的状态和数据。JetpackMVVM模式可以帮助开发者更好地组织和管理代码,提高开发效率和舒适度。\[1\] 使用JetpackMVVM可以带来许多好处,例如简化代码、提高开发效率、提供更好的代码结构和可维护性。通过使用Jetpack的组件,开发者可以更轻松地处理生命周期管理、数据共享和导航等常见任务。而MVVM模式则可以帮助开发者更好地分离关注点,使代码更易于测试和维护。\[2\] 总之,JetpackMVVM是一种强大的组合,可以帮助开发者快速开发Android应用程序,并提供更好的代码结构和可维护性。如果你想了解更多关于JetpackMVVM的信息,可以参考引用\[1\]中提供的Jetpack框架的介绍。 #### 引用[.reference_title] - *1* *2* [JetpackMvvm](https://blog.csdn.net/u014608640/article/details/124711159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid...](https://blog.csdn.net/m0_37796683/article/details/130277908)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值