自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(83)
  • 收藏
  • 关注

原创 《Fallacies of Distributed Systems》原文手译

微服务,也以微服务架构为人们所知,是一种架构模式,它将应用构建成一些列的服务,这些服务具有:*易维护和测试*低耦合*可独立部署*围绕业务*维护规模小微服务架构让规模大而复杂的应用分发变得更迅速、频繁和可靠。它也让开发组织能够迭代它们的技术栈。内容交付网络和边缘计算本质上是尝试让冰箱和货车之间的距离尽可能近。通过将数据复制到更接近需要的位置,来让我们大幅减少延迟。基础设施即代码(IaC)是通过代码而非手工流程来管理和提供基础设施。

2024-03-12 23:20:37 766

原创 Raft算法详解(二):领导者选举

下一篇会讲解Raft的日志复制机制对Raft算法感兴趣的朋友还可以阅读一下我翻译的Raft论文。

2024-01-25 20:02:09 563

原创 Raft论文手译(下)

继续,本篇文章将对Raft论文的后半部分进行翻译。

2024-01-24 15:24:48 840

原创 Raft论文手译(上)

Raft是一种管理日志一致性的算法。它可以产生和Paxos一样的结果,和Paxos一样高效,但其结构与Paxos有所不同。相对于Paxos,Raft更通俗易懂也更容易实现其系统功能。为了更利于理解,Raft将领导者选举、日志复制、安全性等重要要素进行分离,并大幅提升它们的相关性以减少原来需考虑的状态类型。根据用户的使用反馈,相对于Paxos,Raft更易于学生学习使用。Raft还包含一种改变簇成员的全新机制,它通过冗余技术来保证安全性。一致性算法能使多台机器即使在部分成员宕机的情况下依然像一个整体一样工作。

2024-01-24 11:05:02 961

原创 Raft算法详解(一):介绍

Raft是一种一致性算法,它包含了几个部分分别是领导者选举、日志复制、日志压缩和安全性。

2024-01-21 10:59:01 395

原创 FFmpeg Visual Studio开发(四):音频解码

上一篇文章我们学习了如何通过FFmpeg解码视频帧,本篇文章我们来学习如何解码音频帧。文章分段讲解视频解码的各个步骤,接着会贴上完整代码,最后进行测试。准备工作在开始学习前,我们先准备一个文件夹(Res),在里面放置一个视频文件(video.mp4)和一个音频文件(audio.mp3),时长为1分钟左右即可。当然,对于没有学过 FFprobe 和 FFplay 的朋友,强烈建议先学习一下它们的常用命令。这两个工具可以用来测试我们的音视频文件。音频解码的步骤如下。1.打开文件获取多媒体文件上下文

2022-02-13 20:16:03 1707

原创 FFprobe常用命令

介绍FFprobe是一个强大的音视频信息查看工具。具体使用查看基本信息命令如下。-i 表示输入文件,可以是mp4、mp3等封装格式的文件,但不能是原始数据文件,如yuv、pcm等。ffprobe -i audio.mp3当然,也可以查看网络多媒体文件信息。ffprobe -i http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4查看流的格式信息命令如下。视频文件会有视频流和音频流。ffprobe -show_format -i video.m

2022-02-13 17:18:42 2616

原创 FFplay常用命令

介绍与准备

2022-02-11 21:59:29 2402 1

原创 FFmpeg Visual Studio开发(三):视频解码

上一篇文章我们学习了如何把视频文件解封装,本篇文章我们来学习如何解码视频数据。文章分段讲解视频解码的各个步骤,接着会贴上完整代码,最后进行测试。准备工作首先创建一个新的控制台工程,把FFmpeg4的库配置好,不熟悉的朋友可以看看第一篇文章。接着跑一下测试程序看看配置是否成功。#include "stdafx.h"#include <iostream>extern "C"{#include "libavformat/avformat.h"};using namespace s

2022-02-11 15:17:03 1460

原创 FFMPEG常用命令(四):图片相关命令

上一篇文章我们学习了FFmpeg音频相关的命令,本篇文章我们来学习FFmpeg图片相关的命令。准备工作和上一篇文章一样,我们准备一个Res文件夹,在里面放一个视频文件(video.mp4,一分钟左右)和一张图片文件(image.jpg)。然后在这个文件夹打开命令行。接着我们了解一下YUV,YUV是图片的一种编码方式,Y指明亮度,U和V指色度,用于表示像素的颜色。常见的YUV采样有三种,分别是YUV444、YUV422 及 YUV420。YUV444是指每个像素点都有自己的Y值、U值和V值,如下图。

2022-02-10 23:57:54 7395

原创 FFmpeg Visual Studio开发(二):视频解封装

上一篇我们在Visual Studio上搭建好了FFmpeg4的环境,本篇文章我们来学习FFmpeg的视频解封装。文章会把程序分成几段来讲解,最后会贴出完整代码。准备工作首先创建一个新的控制台工程,把FFmpeg的库配置好,不熟悉的朋友可以看看上一篇文章。接着跑一下测试程序看看配置是否成功。#include "stdafx.h"#include <iostream>extern "C"{#include "libavformat/avformat.h"};using nam

2022-02-10 16:57:17 824

原创 FFmpeg Visual Studio开发(一):环境搭建

介绍FFmpeg是一个强大的音视频编解码开源库。目前(2022/2/9)FFmpeg版本已经到了4+,支持多种平台。本篇文章将讲解如何在Visual Studio上搭建FFmpeg环境并编写FFmpeg的HelloWorld程序。准备工作在此之前,大家先做好心理准备吧。在环境搭建过程中会遇到相当多的坑,FFmpeg的学习光是这一步就劝退很多人了。坚持下来吧。这里使用的是Visual Studio 2013,FFmpeg使用的是4.3版本。FFmpeg分为static(静态库)、shared(动态库)

2022-02-10 00:34:34 1396 1

原创 FFMPEG源码编译安装

介绍与准备FFmpeg是一个强大的音视频编解码开源库。目前(2022/2/9)FFmpeg版本已经到了4+,支持多种平台。本文将讲解如何在Linux环境下编译安装FFmpeg。在开始前首先做一些准备。1.在FFmpeg官网下载FFmpeg的最新源码(4+)2.准备Linux编译环境(Ubuntu16或其他Linux系统)解压解压下载好的FFmpeg压缩文件。tar -xvf ffmpeg-snapshot.tar.bz2解压完成后会得到一个ffmpeg文件夹。编译与安装先进入ffmp

2022-02-09 18:05:52 4503

原创 FFMPEG常用命令(三):音频相关命令

上一篇文章我们学习了FFmpeg视频相关的命令,本篇文章我们来学习FFmpeg音频相关的命令。准备工作和上一篇文章一样,我们准备一个Res文件夹,在里面放一个视频文件(video.mp4)和音频文件(audio.mp3)。然后在这个文件夹打开命令行。改变格式音频格式转换命令如下。-f ogg表示编码格式是ogg,ogg是非常先进的音频格式,可以用于游戏音效。常见的音频格式还有mp3、mpeg-4、wma等。ffmpeg -i audio.mp3 -f ogg out.ogg改变采样率音频采

2022-02-09 17:04:22 3388 1

原创 FFMPEG常用命令(二):视频相关命令

上一篇文章我们学会了FFmpeg最基本的命令。本篇文章我们来学习FFmpeg视频相关的命令。准备工作和上一篇文章一样,我们准备一个Res文件夹,在里面放一个视频文件(video.mp4)和音频文件(audio.mp3)。然后在这个文件夹打开命令行。改变格式FFmpeg可以转换视频格式,命令如下。3gp是一种移动设备的视频格式。常见的视频格式还有mp4、AVI、RMVB、FLV等。ffmpeg -i video.mp4 -f 3gp out.3gp当然还有更多的格式可以转换,查询命令如下。其中

2022-02-09 15:05:28 2809

原创 FFMPEG常用命令(一):音视频信息与抽取

介绍与准备FFmpeg是一个强大的音视频编解码开源库。目前(2022/2/9)FFmpeg版本已经到了4+,支持多种平台。下面我们来学习一下FFmpeg的常用命令。在学习之前要做一些准备工作,首先是安装FFmpeg,这里的运行环境是Windows。其次是准备好一个视频文件(mp4)和一个音频文件(mp3),用于音视频的编解码测试。测试用的MP4可以在这个页面下载。创建一个文件夹叫Res,把测试文件放在这里,分别命名video.mp4、audio.mp3。最后在这个文件夹下打开命令行,准备工作就完

2022-02-09 12:09:04 3030

原创 SQLite 基本语法(二)

上一篇文章讲述了SQLite数据库创建删除、表的增删查。本篇文章来重点讲解WHERE的使用。准备工作在真正开始前,我们先做一点准备工作。创建一个SampleDB.db的数据库,在这个数据库创建一个表,表包括ID、Name和Age三个字段。记录有四条。四条记录如下。WHERE语句当我们在使用SELECT、DELETE和UPDATE时,通过WHERE来限制操作的范围。例如下面的查询操作。AND表示“而且”。OR表示“或者”IN 表示枚举,例如只要年龄是8或11的记录。BETWEEN

2022-02-07 16:53:25 555

原创 SQLite 基本语法(一)

介绍SQLite是一种轻量级的数据库,主要用于嵌入式设备,Android App使用的也是SQLite。在学习SQLite之前。首先需要安装SQLite3,这里选用的环境是Windows。下面我们通过一个例子来学习SQLite常用的语法。数据库创建和导出打开命令行,输入SQLite3,回车,进入SQLite3。我们来创建一个数据库,名字就叫SampleDB,.db是文件类型。导出数据库也很简单,首先退出SQLite3。.quit是退出命令。回到命令行后输入sqlite3 SampleDB

2022-02-07 15:09:07 1377

原创 Android Jetpack:Lifecycle使用教程

介绍Lifecycle是Android Jetpack中用于管理生命周期的库。无论是MVP模式还是MVVM模式,Activity充当的都是View(视图)的角色。然而随着程序功能越来越复杂,很多模块都需要在相应的生命周期上停止或释放内存,这就使得Activity的代码不得不写大量与视图无关的代码,就如下面这个例子。通过Lifecycle就能够很好的解决这个问题。public class MainActivity extends AppCompatActivity implements ...{ .

2022-02-06 14:44:01 1914

原创 Android Jetpack:Room与Database Inspector使用教程

本文章涉及到SQLite语法,对SQLite语法不了解的朋友可以先学习一下它的基本使用再来阅读本文章。介绍Room是Android Jetpack中用于操作数据库的库,本篇文章将讲解Room的使用方法,并简单介绍如何使用Database Inspector调试(Android Studio 4.1+)。基本使用方法使用Room,我们要完成三个工作,定义实体类,定义DAO,定义数据库。首先把Room的相关库导进来,前面两项是必要的,后面的optional是可选项,它们是Room对其他三方库的拓展。

2022-02-03 17:24:27 2346

原创 Android跨进程通信(五):Messenger源码解析

前面的文章我们学会了如何使用Messenger进行跨进程通信。本篇文章我们来探究一下Messenger源码。Messenger创建Messenger有两种构造方法,第一个是传入Handler,它是服务端的创建方式。第二个是传入IBinder,它是客户端的创建方式。首先来看第一种创建方式。Messenger内部有一个IMessenger成员变量,它是由Handler获取的。//Messenger.javapublic final class Messenger implements Parcelab

2022-02-02 00:27:20 1809

原创 Android跨进程通信(四):AIDL源码解析

本篇文章是AIDL的源码解析,不了解AIDL的朋友可以看看使用教程,熟悉了基本的使用后再来阅读本文章。阅读本文章的时候,把服务端和客户端的工程都打开结合着它们来一同分析。接口代码总览在我们编写AIDL并成功编译后,工程里便会自动生成一个Java接口文件。首先来总览这个文件,红色框的方法就是AIDL文件里声明的方法。文件里还有一个Stub静态内部抽象类,它implements了此Java接口(蓝色框),也就是说它或它的子类要把AIDL声明的方法给实现了。来看看Stub类。红色框说明Stub类继承自B

2022-02-01 18:38:05 1397

原创 Android跨进程通信(三):Messenger使用教程

前面的文章讲述了如何通过AIDL来实现Android的跨进程通信,本篇文章来讲解如何使用Messenger来实现同样的功能。介绍Messenger是AIDL的封装,进程可以通过Messenger来实现通信。直接编写AIDL相当复杂,而Messenger大大简化了编写流程。下面先介绍Messenger的基本使用方法。准备工作创建Messenger对象需要传入一个Handler,在这个Handler里对接收到的数据进行处理。Handler handler = new Handler(){ @Ove

2022-02-01 14:48:00 2841 1

原创 Android Jetpack:LiveData与ViewModel的使用教程

介绍LiveData是Android Jetpack的一个组件,它具有监听生命周期的功能,保证在生命周期的活跃状态时及时通知观察者数据更新。使用LiveData并不需要太担心内存泄漏问题,因为它在创建时会绑定LifeCycle(例如Activity),当LifeCycle销毁时,LiveData便会自动与其解除绑定。ViewModel则是MVVM模式里的概念,从名字也可以看出它是View(视图)和Model(模型)通信的桥梁。ViewModel的作用和MVP模式里的Presenter非常相似,但View

2022-01-30 19:48:06 1389

原创 Android Jetpack:WorkManager使用教程

介绍WorkManager是Android Jetpack的一个强大的组件,用于处理后台耗时任务。后台任务可以是一次性的,也可以是重复的。快速入门在使用前先把库导进来,其中前两个是必选项。dependencies { def work_version = "2.7.1" // (Java only) implementation "androidx.work:work-runtime:$work_version" // Kotlin + coroutines

2022-01-30 14:03:55 1651

原创 Android跨进程通信(二):AIDL使用教程2

上一篇文章讲述如何编写服务端的代码,本篇文章讲解客户端代码的编写,并测试两程序的进程间通信。编写客户端的AIDL代码上篇文章也说过AIDL对包名要求很苛刻,因此在编写的时候要格外注意。首先,切换为Project模式。在main文件夹上创建一个新文件夹,一定要叫aidl。按照下面这种方式创建一个aidl文件,然后不管它(这是为了解决Android Studio的一个"小"bug),这个步骤不能漏。接着把服务端的aidl包一整个复制到客户端的aidl下。复制后,客户端的aidl文件夹如下,

2022-01-29 23:38:08 1846

原创 Android跨进程通信(一):AIDL使用教程1

介绍本篇文章将讲述Android AIDL的基本使用。AIDL叫Android接口定义语言,是用于辅助开发者完成Android跨进程编程的工具。下面将通过两个Android应用来讲解如何使用AIDL来完成跨进程编程。先来介绍一下这两个应用的场景。第一个应用是传感器应用,能够侦测收集温度数据(模拟场景),并提供温度检测的Service,也就是说这个应用是服务提供方。第二个应用则是客户端,它能够绑定第一个应用的温度侦测服务,显示当前手机温度。编写服务端AIDL代码先创建一个空白工程,名字就叫Sensor

2022-01-29 23:36:34 2974

原创 A*算法(五):在三维地图的可行性

上一篇文章在原有的A*算法上增加了权值,解决了混合型地图的最短时间循迹问题。本篇文章我们来讨论一下A*算法,在三维地图上可行性。可行性讨论在二维空间上,我们把地图分割成许许多多大小一致的正方格。而在三维空间,我们就得考虑高度了。于是一个三维地图就可以通过许许多多大小一致的正方体来表示。A*算法用在三维空间无非就是把高度也考虑进去。但是在二维空间里,方格最多只要考虑8个方向,而三维空间的方块最多得考虑26个方向(3*3*3 - 1),这对于一般的遍历算法来说,工作量是巨大的。为了减少遍历,我们可以尝

2022-01-26 15:38:33 3669

原创 A*算法(四):权值与混合型地图

上一篇文章讨论了双向策略以及类似的算法,本篇文章在原有A*算法上进行更深入的思考,看看如何通过权值来解决混合型地图的循迹问题。思想与思路我们先来思考一个问题。100米的水泥地、100米的沙地和100米的泥潭,很显然在水泥地上跑是最快的。那么在方格地图上应该怎么表示呢?用不同颜色表示就可以了,如下图,灰色是水泥地,黄色是沙地,棕色是泥潭。此时又有一个问题,“最小代价”指的是什么?看看下面的图片。如果“最小代价”是指距离长度,那么蓝色就是“最小代价”的路线,而不是红色。我们给不同地质的方块设定一个

2022-01-26 14:04:55 1177 1

原创 A*算法(三):双向策略与类似算法

上一篇讲解了8方向A*算法的执行过程,本篇文章讲解双向A*算法。思想与思路“双向”策略其实在很多算法里都有使用过,主要是起到优化的作用。例如冒泡排序,单向冒泡排序每一趟都能确定一个元素的最终位置。如下图,冒泡排序会依次把8、7、6…放在最终位置。使用双向策略,那么每一趟就能确定两个元素的最终位置。如下图,依次确定8和1、7和2、6和3…,当两个指针相遇时,排序就完成了。类似地,A*算法也可以尝试双向策略。起点和终点同时探索,如下图,相遇时结束。但是,所有A*算法的执行都有一个重要的条件,那就

2022-01-26 12:05:05 1927

原创 A*算法(二):8方向

上一篇文章讲解了A*算法的最简版本,本篇文章在4方向A*算法的基础上讲解8方向的情况。准备工作在讲解8方向A*算法前,我们需要想想这个“最小代价”是指什么。第一种情况,如下图,如果离开A到周围的8个方格的代价均是1,那么从起点到终点的“最小代价”就是指最少需要走几步。第二种情况,如下图,如果斜着走的代价是√2,那么从起点到终点的“最小代价”就是指最小距离长度。和上一篇一样,我们给方格定义变量A、B、C...

2022-01-26 11:11:32 2149 2

原创 A*算法(一):4方向

介绍与准备A算法是一种用于方格地图寻找最短路径的算法,这种算法适用于静态地图。本篇文章讲述A算法的最简版本,也就是只考虑四个方向的A*算法。所谓的四个方向就是指可以上下左右移动,但不允许斜着移动。方格内有A,B,C三个变量。A指初始位置到当前方格的最小代价B指当前方格到终点的估计代价C指A + B的值例如下图,橙色方块A = 1,B = 5,C = 1 + 5 = 6。B所谓的估计代价就是当前方块与终点的横向差值(绝对值)和纵向差值(绝对值)的和。对于橙色方块而言横向差值为3,纵向差值为2,所

2022-01-26 00:41:34 1724

原创 Android NDK入门教程(一):环境搭建及HelloWorld

创建项目和普通的App不同,在创建项目时我们要选择C++工程,这样就会自动完成相关的C++配置及文件创建。工程创建后,如果Android Studio没有安装NDK,则会报错提示安装它,点击安装即可。接下来在MainActivity.java上会发现一个native方法,这就是JNI的Demo方法,之后依葫芦画瓢秀可以了。再看看工程目录,会发现多了一个cpp文件夹,c++的工程文件就是放在这里的。native-lib.cpp就是工程创建c++的Demo源文件,打开它。刚刚MainActivi

2022-01-03 14:22:58 1865

原创 Makefile基础教程

前期准备在真正使用Makefile之前,我们首先先写四个c文件和相应的h文件,分别是fun0.c,fun1.c,fun2.c,fun0.h,fun1.h,fun2.h以及main.c//fun0.c#include "fun0.h"void print0(){ printf("hello world 0");}//fun0.h#include <stdio.h>void print0(void);//fun1.c#include "fun1.h"void print1

2022-01-02 20:04:16 13204 4

原创 Android音视频开发之ExoPlayer(三):自定义布局

隐藏自带按钮第一篇中讲述了如何快速上手ExoPlayer,所用到的显示控件是StyledPlayerView。在默认情况下,StyledPlayerView是会显示自带的控制按钮和进度条的。隐藏它们很简单,只需把use_controller设置成false即可。<com.google.android.exoplayer2.ui.StyledPlayerView android:id="@+id/videoView" android:layout_width="m

2021-12-30 19:07:45 5636

原创 Android音视频开发之ExoPlayer(二):播放列表常用的功能

播放列表ExoPlayer内置了一个播放列表,可以通过ExoPlayer实例来对播放列表进行增删改查。在上篇文章中,我们使用setMediaItem方法来添加播放的视频,这个方法调用的时候会先把列表清空,再添加该视频,也就是说,这个方法只支持播放单个视频。mPlayer.setMediaItem(mediaItem);如果需要添加多个视频,调用addMediaItem方法即可。MediaItem mediaItem = MediaItem.fromUri("http://clips.vorwae

2021-12-30 12:50:41 5190

原创 Android音视频开发之ExoPlayer(一):快速入门ExoPlayer

初识ExoPlayerExoPlayer是Google推出的一种多媒体播放器框架,支持本地音视频的播放,同时网络视频也是支持的。快速上手首先,把ExoPlayer的库导进来。注意,这里使用的ExoPlayer版本是2.16.1,其他版本在初始化ExoPlayer上会略有区别,大家可以参看说明文档。android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targ

2021-12-30 10:12:00 4673

原创 Android Logger日志框架源码解析

前言本篇文章将解析Android开源日志框架Logger的源码,Logger的版本是2.2.0,对这个框架还不了解的朋友可以先快速学习基本使用再来阅读本文。初始化先看一下Logger初始化的基本操作FormatStrategy logcatFormatStrategy = PrettyFormatStrategy.newBuilder() .tag("MyTag") .showThreadInfo(true)

2021-03-19 15:07:35 376

原创 Android 树形存储器(二):xml解析原理及优化

上一篇讲解了如何使用树形存储器,本篇来讲解它是如何从xml文件中解析出一棵树的。源码解析下面是 parseFromXml 方法,我们就是通过这个静态方法来解析xml文件的。public static <D> Tree<D> parseFromXml(InputStream inputStream, AbsTreeXmlHandler<D> treeXmlHandler){ try { //1 SAXParse

2020-07-11 15:52:04 334

原创 Android 树形存储器(一):使用方法

基本使用首先导入库。allprojects { repositories { ... maven { url 'https://jitpack.io' } } }dependencies { implementation 'com.github.PYJTLK:MindMapViewTest:1.2'}为了快速上手树形存储器,我们以下面这张图片为例创造一棵树。Tree<Integer> root = new Tree<>();//设

2020-07-10 21:43:13 284

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除