- 博客(120)
- 收藏
- 关注
原创 LiveDate 在 NetworkBoundResource 中的巧妙应用
由于View的刷新依赖于网络请求的返回的结果,而网络请求又需要一定的时间,整个过程是一个同步操作,代码中往往也需要传递callback,来完成View的更新。NetworkBoundResource 通过引入LiveDate,把数据的请求变成了一个异步的操作,View的更新通过LiveDate 的 observe 来完成。在上面的示例中,我们定义了一个getUser方法,该方法通过调用UserRepository的getUser方法来获取用户数据,并使用LiveData将数据呈现给UI。
2023-03-31 10:57:55
223
原创 ViewModel 跟 Activity 之间到底是什么关系?
ViewModelStore中存储 ViewModel 的 hashtagMap 是activity 成员变量的成员变量,就这样 activity 和 ViewModel就绑定到了一起。Factory 负责创建 ViewModel,ViewModelStore 负责存储 ViewModel。我们日常都是如此获得ViewModel的,那你知道ViewModelProvider到底是怎么获得ViewModel的吗?ViewModel又是如何跟activity/fragment之间绑定的?
2023-03-26 16:40:32
442
原创 Android Recycler Tips 之 smoothScrollToPosition 和 scrollToPosition 触发 ScrollListener
1.在recyclerView中,scrollToPosition 不会触发 scrollListener,而 smoothScrollToPosition 会触发 scrollListener 。源码分析可参考2.监听 smoothScrollToPosition 滑动动画停止时,的例子:private void scrollToPosition(int position){ recyclerView.removeOnScrollListener(onScrollListener);
2022-04-04 11:47:45
3044
原创 《编程珠玑》学习记录第八章算法设计技术
算法的设计这个问题太过庞大,对于一个程序员来说,最好的办法就是多接触不同的算法,并且时刻总结。问题:一个一维的整数数组,有N个元素,元素有正数也有负数。找到数组中任意连续个元素最大和。分析:其实这是一个典型的动态规划问题,但是书中给了好几种方法,虽然有些方法不是最优的,但是分析问题的过程是很值得借鉴的。方法一:使用暴力法找到所有的子序列,并计算出所有子序列的和,结果自然就得到了。这种方法的事件复杂度是O(n*n)vector<int> testArray = {31, -41,
2020-09-21 21:18:57
290
原创 《编程珠玑》学习记录第三章数据决定程序的结构
这章讲的是数据结构对程序的影响:使得程序代码简洁、已读。毕竟程序是给人看的,所以能被人看懂,才是代码的首要任务。 提高效率。不仅是代码的运行效率,还有代码的维护效率。习题1:税收问题。题目中使用if-else的分支语句的缺点有两点:代码太长,需要大概500行代码左右才能完成功能,也不利于之后的代码更新。 代码从上到下执行,是一个顺序查找的过程,效率太低。问题分析:分段的税收问题。这个问题可以有两种方法进行处理:递推公式法。很容易就可以得到分段税收的递推公式,但是对于一次税收结果的计算时间
2020-09-12 16:19:26
216
1
原创 《编程珠玑》学习记录第二章算法
本章通过三个小问题来引出算法这个概念。文中提出,有时候埋头苦干之前,如果能够静下心来找到一个合适的算法,将会事半功倍。但是埋头苦干和冷静思考的时机是一门大学问。问题A:文件中包含最多40亿个随机排列的32位正整数,找出一个不在文件中的32位正整数。分析:对于32位的正整数最大在42亿多,所以在只包含40亿的文件中一定会有一些正整数不包含在文件中。由于文件太大,很难将所有的数都吃进内存。答案:二分查找的思想。第一步:遍历整个文件,对于每一个数进行判断,如果这个数的二进制第一位为1,将这个数存入文件
2020-09-09 09:58:46
210
原创 《编程珠玑》学习记录第一章开篇
开篇提出了一个排序问题问题描述:在一个磁盘文件中存在10000000左右个正整数,不存在重复元素,每个数在区间[1, 10000000]中。输出:将这些整数升序排列,并存到一个磁盘文件里。约束:大约有1M的内存空间可用,运行时间在10秒左右。分析:对于1千万左右的数字,我们至少要用4个字节来存储。如果同时将1千万个这样的数字读入内存,大约需要38M左右的内存,这远远超过题目要求。这种情况下,需要对磁盘文件进行多趟的排序,这样的话代码会很复杂,而且很难满足时间要求。解决方法:文中提出.
2020-09-03 20:14:29
149
原创 学习muduo库(15)之socket类
UML:解释:从逻辑上讲这个类封装的很简单,只有一个私有变量,就是文件描述符,剩下的所有的方法,都是围绕文件描述符来展开的,而且上一篇博客中提到的sochetops.h中的所有函数都是全局函数,而这些全局函数也是在socket类中调用的。...
2020-01-09 10:49:00
221
原创 学习muduo库(14)之网络编程相关的系统函数SocketsOps.h
SocketsOps.h在这个头文件中将网络相关的系统函数进行了进一步的封装,这里的函数也都是全局函数。int socket(int domain, int type, int protocol);•domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET(IPv4)、AF_INET6(IPv6)、AF_LOCAL(或称AF_UNIX,Unix域soc...
2020-01-04 15:00:53
323
原创 学习muduo库(14)之eventloopthread类
UML:解释;这个类体现了muduo库的思想:每一个线程有且有一个eventloop对象。此类的功能也是,创建一个线程,并在线程的回调函数中创造一个eventloop对象。值得学习的细节:EventLoop* EventLoopThread::startLoop(){ assert(!thread_.started()); thread_.start(); ...
2020-01-02 21:16:51
457
原创 学习muduo库(13)之evenloop类中wakeup()的概念
预备知识:eventfdeventfd是Linux 2.6提供的一种系统调用,它可以用来实现事件通知。eventfd包含一个由内核维护的64位无符号整型计数器,创建eventfd时会返回一个文件描述符,进程可以通过对这个文件描述符进行read/write来读取/改变计数器的值,从而实现进程间通信。#include <sys/eventfd.h>int eventfd...
2020-01-02 10:19:18
913
原创 学习muduo库(12)之定时器相关的类TimerQueue
准备知识:int timer_create(int clockid,int flags);//成功返回0参数:clockid:第一个参数一般为CLOCK_REALTIME或者CLOCK_MONOTONIC,其参数意义为参数意义CLOCK_REALTIME:相对时间,从1970.1.1到目前时间,之所以说其为相对时间,是因为我们只要改变当前系统的时间,从1970.1.1...
2019-12-31 09:44:56
328
1
原创 学习muduo库(11)之eventpoll类
预备知识:poll:int poll(struct pollfd fds[], nfds_t nfds, int timeout);参数:fds:这是一个结构体数组指针。nfds:是这个数组的大小。timeout:表示poll的阻塞时间。typedef struct pollfd { int fd; /* 需要被检测或选择的文件描述符...
2019-12-27 15:58:23
383
原创 学习muduo库(10)之与日志相关的类
准备知识:标准C语言预处理要求定义某些对象宏,每个预定义宏的名称一两个下划线字符开头和结尾,这些预定义宏不能被取消定义(#undef)或由编程人员重新定义。__LINE__ 当前程序行的行号,表示为十进制整型常量__FILE__ 当前源文件名,表示字符串型常量另外gcc还支持__func__,和__FUNCTION__,它指示所在的函数,但是这个关键字不被windows下的v...
2019-12-26 11:24:05
212
原创 学习muduo库(9)之线程单例类ThreadLocalSingleton
准备知识:__thread是GCC内置的线程局部存储设施,存取效率可以和全局变量相比。__thread变量每一个线程有一份独立实体,各个线程的值互不干扰。可以用来修饰那些带有全局性且值可能变,但是又不值得用全局变量保护的变量。__thread使用规则: 只能修饰POD类型(类似整型指针的标量,不带自定义的构造、拷贝、赋值、析构的类型,二进制内容可以任意复制memset,memcpy...
2019-12-20 19:06:08
483
原创 学习muduo库(8)之线程本地存储类ThreadLocal
预备知识:int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));第一个参数为指向一个键值的指针,第二个参数指明了一个destructor函数,如果绑定的函数不为空,那么当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块。key一旦被创建,所有线程都可以访问它,但各线程可根据自己的需要往...
2019-12-20 14:42:19
197
原创 学习muduo库(7)之单例类Singleton
UML:pthread_once(&ponce_, &Singleton::init);pthread_once(&ponce_, &Singleton::init);是一个线程安全的,且保证Singleton::init仅仅被执行一次。解释:Singleton是一个模板类,而且所有的成员都是静态的,所有不用生成对象。使用时这样写:mud...
2019-12-20 09:27:00
377
原创 学习muduo库(6)之线程池类ThreadPool
UML:这是一个十分重要的类,这个类中维护了两个队列,一个是任务队列,一个是线程队列。我们将任务放到任务队列中,线程队列从任务队列中不断地读取任务。线程队列的尺寸是自己定义的,所以线程队列是一个大小固定的队列。任务队列是一个std::deque,我们可以设置它的最大尺寸。两个条件变量是用来优化任务队列的读写的,类似于BoundedBlockingQueue...
2019-12-19 21:13:46
265
原创 学习muduo库(5)之有界缓冲区类无界缓冲区类BlockingQueue和BoundedBlockingQueue
UML:BlockingQueue这是一个用std::deque设计的线程安全的队列,其实要想简单的保证队列的线程安全,只需要在读写的时候加上锁就行啦。为了提高效率,这里引入了条件变量。产生的效果就是,当读出数据时,发现这个队列是空的,就把这个线程挂起到条件变量上,当写入数据的时候就唤起所有正在等待条件变量的线程。写法如下:void put(const T& x) ...
2019-12-19 11:46:58
349
原创 学习muduo库(4)之门闩类CountDownLatch
UML:解释:CountDownLatch类是一个通过条件变量类condition,来实现让多个子线程同时起跑的。其实count_是表示需要建立的线程数,当count_大于零时,线程会被条件变量挂起。每建立一个线程count_都会减一,当最后一个线程建立成功后,count_减为零。这个时候就唤起所有被条件变量挂起的线程。这些线程同时起跑。关键的代码如下:void CountD...
2019-12-19 10:52:43
279
1
原创 学习muduo库(3)之条件变量condition类
预备知识:pthread_cond_t这是Linux库中的一个变量类型,表示多线程的条件变量,用于控制线程等待和就绪的条件。pthread_cond_init()muduo库用次函数来初始化条件变量。它的原型为:extern int pthread_cond_init __P ((pthread_cond_t *__cond,__const pthread_condat...
2019-12-17 17:54:33
316
原创 学习muduo库(2)之互斥锁MutexLock类
UML类图:解释:供我们使用的是lock()和unlock()这两个函数,与Linux自带的互斥量使用方法类似。需要解释的是holder_,这个变量使用来记录当时锁住锁的线程的tid,如果没有任何线程锁住锁它的值为0。就是通过这种方式来体现MutexLock的上锁和解锁的。在源码中是这样体现的: void lock() ACQUIRE() { MCHECK...
2019-12-17 15:54:56
246
原创 学习muduo库(1)之CmakeLists.txt的编写
CMakeLists.txt有很多复杂的写法,尤其是设置一些变量的时候,我这里只写出来最简单的写法,没有变量全部用绝对路径来写,这对新手来说,最友善。cmake_minimum_required(VERSION 2.6) //限制最低版本project(pas CXX) //cmake的工程名叫做pas,限定语言为c++ADD_DEFINITIONS(-std=c++11) //采用...
2019-12-16 14:15:33
396
原创 初识c++(37)基于对象的编程思想
基于对象的编程思想在c++中面向对象的编程思想是基于c++中的各种虚机制来完成的,这里就不详细展开啦。而基于对象的编程思想则是基于std::function和std::bind两个函数来实现的。std::function和std::bindhttp://www.cplusplus.com/reference/functional/bind/?kw=bindhttp://www.cp...
2019-12-11 10:23:50
275
原创 TCP/IP详解(4)之IP协议之抓包测试
1.版本号:占四位,就是IP协议的版本,通信双方的IP协议必须要达到一致,IPv4的版本就是4.2.首部长度:占四位,因为长度为四比特,所以首部长度的最大值为1111,15,又因为首部长度代表的单位长度为32个字(也就是4个字节),所以首部长度的最小值就是0101,当然,也确实如此,大部分的ip头部中首部字节都是0101.也就是5*4=20个字节,如果是最大值15的话,ip首部的最大值就是...
2019-11-07 15:45:35
1818
原创 初识c++(36)之模板函数与分离编译模式
分离编译模式一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件连接起来形成单一的可执行文件的过程称为分离编译模式。举个例子://main.cpp#include <iostream>#include "hello.h"int main(int argc, char** argv) { my_function(1); r...
2019-11-07 10:33:00
207
原创 TCP/IP详解(3)之ARP协议
链路层的数据帧在同一网段中传送时,需要知道下一跳的MAC地址。那么怎么知道IP地址对应的MAC地址呢?这就需要ARP协议啦。原地址的电脑以广播的形式向本网段中发送ARP协议的数据帧,目标电脑接收到后,会返回APR协议的数据帧,告诉原地址电脑,目标电脑的MAC地址。硬件类型:16位字段,用来定义运行ARP的网络类型。每个局域网基于其类型被指派一个整数。例如:以太网的类型为1。ARP可用在...
2019-11-04 21:43:13
305
原创 TCP/IP详解(2)之数据链路层数据帧的格式以及抓包测试
数据链路层的数据帧的传递是依赖于物理地址来传递的,所以这里的目的地址、原地址都指的是物理地址。帧类型指的是数据帧传递遵循的类型。数据指的是网络层传递下来的数据包,帧校验是用来校验数据帧在传递工程中,是否发生问题!抓包测试的结果如下:...
2019-10-30 20:02:47
1666
原创 TCP/IP详解(1)之计算机网络体系结构
这是自己对这一段时间学习计算机网络的总结,主要内容会集中在tcp/ip协议上面。每一层的数据叫不同的名字,并遵循不同的协议。第5层应用层(Application 此层数据单位【消息message】)协议和应用:http,ftp,tftp,telnet,dns,smtp 第4层传输层(Transport 此层数据单位【段segment】)协议和应用:tcp,udp,spx 第3层网络...
2019-10-25 14:51:31
638
原创 用pytorch搭建最简单的BP网络训练mnist手写数字图片数据集实例
最简单的例子:import torchimport torch.nn as nnimport torch.nn.functional as Fimport mnist_loaderimport numpy as npclass Net(nn.Module): def __init__(self, n_feature, n_hidden, n_output): ...
2019-10-24 14:59:39
1293
原创 剑指offer(6)面试题4:二维数组中的查找(第二版44页)
代码:#include<iostream>using namespace std;bool Find(int* test_array, int rows, int columns, int number){ int min_rows = 0;//从右上角开始查找。 int max_columns = columns - 1; while(mi...
2019-10-21 16:02:00
170
原创 初识c++(35)之传递二维数组
在传递一维数组的时候,可以简单粗暴的传递指针。但是对于二维数组来说,必须知道数组的第二维的信息,才可以正确的进行索引。以下几种做法可以正确的传递二维数组。#include <iostream>using namespace std;/*传二维数组*///第1种方式:传数组,第二维必须标明/*void display(int arr[][4])*/void displ...
2019-10-21 10:32:23
762
原创 C++多线程(6)之条件变量(std::condition_variable)
条件变量(std::condition_variable)这是c++11提供的一个类,用于多线程之间的通信。条件变量顾名思义就是根据不同条件而变化的量。应用场景这里举一个例子:有一个线程要求必须达到某种状态才能继续执行,否则将卡死在这里。在这种情况下我们有两种方案,第一种方案就是,在这个线程中不断去检测这个状态,直至符合条件。第二种方案就是,这个线程卡在这里不工作,当条件成立时,去通知...
2019-10-21 09:22:22
688
原创 数据结构与算法C++实现(10)之哈希表
一、概念散列技术是在记录的存储位置和他的关键字之间建立一个确定的对应关系f,是的每个关键字key对应一个存储位置f(key)。查找时,根据这个对应的关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。我们把这种对应关系f成为散列函数,又称为哈希(Hash)函数。采用散列技术将记录存储在一块连续的存储空间中,这块连续空间称为散列表或哈希表(Hash-...
2019-10-16 14:22:17
1074
2
原创 剑指offer(5)不修改数组找出重复的数字(第二版41页)
代码:#include<iostream>int countRange(const int* P_array, int len, int start, int end) { int count = 0; for(int i = 0; i < len-1; ++i) { if(P_array[i] <= end && P_ar...
2019-10-14 21:18:25
107
原创 剑指offer笔记(4)面试题3:数组中重复的数字(第二版39页)
代码:#include<iostream>bool Duplicate(int array_teat[], int len, int& result){ if(array_teat == nullptr || len <= 0) //判断参数是否符合条件 { return false; } for(int i = 0; i <...
2019-10-12 20:38:27
125
原创 23种设计方法c++实现(5)单例模式
单例模式:这是最简单的模式,就是在程序中,对于某个类只允许实例化一个对象。单例类负责自己的实例化,并提供调用它的接口。UML结构图设计要点构造函数Singleton()设计为private,这样就只能自己负责实例化自己。 定义一个private staticSingleton(饿汉模式),或者定义一个private staticSingleton * (懒汉模式)。这...
2019-10-11 20:49:36
150
原创 剑指offer笔记(3)c++中重载类的赋值符号
这是剑指offer第二版25页的题目:按照上面的要求写出来的代码是这样的:#include<iostream>#include<cstring>class CMyString{ public: CMyString(char* pData = nullptr) { m_pData = pData; } CMyString(c...
2019-10-10 21:34:26
177
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人