指针与引用(c++)
1. 变量、内存、比特位(bit)与字节(byte)在 C++ 中:
1 字节(byte) = 8 比特(bit)
变量必须占有实际的内存空间
64 位系统下指针大小通常是 8 字节(64 bit)
常见基础类型大小(不同平台可能略有差异,但通常如下):
类型
大小(字节)
大小(比特)
说明
bool
1
8
只占 1 字节
char
1
8
字符类型
short
2
16
int
4
32
最常用整数类型
long
4 或 8
32/64
Windows 是 4,Linux 是 8
long long
8
64
float
4
32
double
8
64
T*(指针)
8
64
64 位系统固定占 8 字节
123int x = 10; // 占 4 字节double d = 3.14; // 占 8 字节int* p = &x; // p 本身占 8 字节
2. 地址(Address)是什么?每个变量存储在内存中的某个位置,该位置有一个唯一编 ...
Untitled
Android滑的动点不动问题排查(Choreographer详解)排查过程:问题回顾:在实习的时候,看到过一个问题,在APP内部,用户点击”展开更多回复”按钮无响应,内容无法展开,但在此过程中能够滑动页面,loading动画正常渲染,就只是分页加载不出来,等待10-20s之后会有时能加载出来。
初步排查:
首先排除主线程卡顿问题,因为能够滑动页面,动画也可以渲染。
是否是业务代码异步操作等逻辑造成?
通过打log来判断点击以后,是否通过RxJava异步卡顿造成,发现不是
动画一直流程,和日志也没有关系
是否是同步屏障导致?
同步屏障同步屏障其实是和handler,渲染等有关的一个概念,总的来说就是在消息机制下,建立一个屏障,优先让异步消息先处理。这样说有点抽象,我们可以通过代码来理解
1234567891011121314151617181920212223242526272829303132public int postSyncBarrier() { return postSyncBarrier(SystemClock.uptimeMillis());} ...
Android 中网络协议的使用
Android 中网络协议的使用在Android中,有很多网络协议,在这些协议的正确使用下产生了很多优化:直播推流优化,图片下载优化等。我们首先先从介绍计算机网络开始,到具体的Android中协议的使用。
计算机网络模型一般来说,我们网络模型分为七层,四层,五层。通用来说,我们其实使用最多的是五层互联网协议
如图所示:
这里面其实最重要的还是运输层,网络层。关于其他的我们只是简单的介绍一下:(以五层为标准)
应用层:为用户进程直接提供服务,有HTTP/HTTPS协议。也有支持文件传送的FTP协议,DNS,POP3,SNMP,Telnet,支持电子邮件的SMTP协议等。
运输层:主要是为两个主机的进程提供服务,但一个主机也可以有多个进程进行通信,用的也是传输层的协议,具体有:TCP或者UDP
网络层:主要是为两台主机提供通信服务,经过路由再转发。
数据链路层:负责将网络层交下来的 IP 数据报封装成帧,并在链路的两个相邻节点间传送帧,每一帧都包含数据和必要的控制信息(如同步信息、地址信息、差错控制等)。
物理层:确保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境 ...
Kotlin 空安全机制与常用作用域函数总结
Kotlin 空安全机制与常用作用域函数总结本文总结了 Kotlin 中用于处理空值(null)的关键工具与语法,包括 !!、?.、?:、let、run、also、apply、takeIf 等。
基础空安全运算符1. 安全调用(?.)用于在对象可能为 null 的情况下调用方法/属性,不会抛出异常。
1val length = name?.length
2. Elvis 运算符(?:,提供默认值)如果左边为 null,则使用右边的值。
1val displayName = name ?: "访客"
3. 非空断言(!!)如果变量为 null,则抛出 NullPointerException。
1val length = name!!.length
常用作用域函数对比(let / run / also / apply)
函数
接收者类型
返回值
用途
let
it
最后一行
处理非空逻辑或链式调用
run
this
最后一行
对同一个对象做多步操作
also
it
原对象本身
用于调试打印、日志、辅助操作 ...
定位功能调试记录(RouteTracker App)
定位功能调试记录(RouteTracker App)📅 日期2025年4月3日
🧪 目标实现 Android App 中基于 Google Maps 的实时定位功能,使用 FusedLocationProviderClient 获取设备位置并在地图上展示。
🧭 过程记录✅ 地图与定位功能初步实现
使用 GoogleMap 成功加载地图;
使用 FusedLocationProviderClient 调用 requestLocationUpdates;
模拟器设置权限和配置正确;
日志打印如下:12345MAP: 地图准备好了MAP: 权限检查通过MAP: 准备启动 requestLocationUpdatesMAP: 已经调用 requestLocationUpdatesMAP: lastLocation 为 null
🛑 问题一:无定位更新现象
地图加载正常,但始终没有位置回调;
日志中 lastLocation == null;
手动发送定位无效;
adb shell dumpsys location 显示所有 provider 都是 OFF 或无有效定位。
原因
...
Android 进程间通信与管理
Android 进程间通信与管理IPC(inter-process communication)进程间通信是在不同的进程之间进行相互传递数据。
提到了进程,就不得不提一下线程与协程。
进程进程是指正在运行中的程序抽象,是系统进行资源分配和调度的基本单元,执行进程任务的是CPU,对于Android系统来说,Android系统会在应用组件启动并且应用没有其他组件运行的时候,启动一个新的Linux进程。
主要是由三部分构成:
执行指令集(描述要完成的功能)
所需要的数据集合
程序控制块(进程的描述信息与控制信息,是存在的唯一标志)
通俗易懂:“进程”是程序被操作系统加载到内存中运行起来后的样子
进程之间是相互独立的,一个进程崩了不会影响另一个进程,除非共享资源(IPC)
在Android 系统中,一个进程≈一个APP,也就是大多数应用也就一个进程。
一般来说,服务(Service)、 WebView(用来在 App 里嵌入网页)就会单开一个进程,防止阻塞主进程
那在Android系统中谁管理进程呢? AMS
AMS”溥天之下, 莫非王土“AMS作为Android系统的核心组件之一,扮演 ...
Linux内核态与用户态
Linux内核态与用户态用户态与内核态大部分操作系统中都划分了内核态与用户态,。对于Linux中,一个进程(应用程序)有的地址寻址空间一般是由操作系统位数决定,例如,32位操作系统的寻址空间是2的32次方(4G),对于一个进程而言,这就是他的范围,但是这个范围要再次划分,分为内核空间与用户空间
当然对应的空间也代表了不同的权限:内核空间(Kernel Space),这个空间只有内核程序可以访问;用户空间(User Space),这部分内存专门给应用程序使用。
也就是普通的应用程序是暂时无法访问内核空间的,只有在用户空间执行一些非特权指令。特权指令只能在内核空间执行。如果一个应用程序(进程)只是在用户空间进行操作,我们就叫他为程序在用户态进行执行。反之则是内核态
在内核态下,用户的寻址空间范围其实高达很多,基本上所有的位地址都可以达到,因为一个进程(应用)的寻址范围分两部分,一个是内核空间,一个是用户空间,大概可能一个1G 一个3G,具体看划分策略。
在用户态下,用户的寻址范围只能在一部分,也就是3G左右(以实际情况为准)
那么进程如何切换到内核态呢?
其实主要是由系统调用(System ...
Leetcode每日一题
Leetcode每日一题基本知识关于二维数组的操作:
一个二维数组Matrix分为很多个一维子数组。
例如:int[][] matrix = { {0, -1, 2}, {-1, 5, 6}, {7, 8, -1} }; 分为三个子数组{0 -1 2} {-1 5 6} {7 8 -1}
如何确定二维数组的列和行? 列:matrix[0].length //意味着第0个子数组有几个元素 行:matrix.length //意味着有几个子数组。
如何遍历一个二维数组?for (int[] row: matrix) {} //它表示对于 matrix中的每一个 row(每一个子数组),执行循环体内的操作
题目:修改矩阵 3033给你一个下标从 0 开始、大小为 m x n 的整数矩阵 matrix ,新建一个下标从 0 开始、名为 answer 的矩阵。使 answer 与 matrix 相等,接着将其中每个值为 -1 的元素 ...
Handler机制
Handler机制背景我们都知道在Android开发中我们不能执行耗时操作在主线程,因为用户能感知到这个操作,并且UI的操作必须要在主线程中进行更新,那么我们如何传递子线程的信息通知给主线程进行UI更新呢?这时我们就需要用到Handler,进程间通信的方式。
Handler机制
Handler从子线程经过SendMessage()方法发送消息给Message Queue队列 Message队列给Looper传递,最后主线程通过检查Looper来得到Message。
为什么不能直接用子线程发给主线程?因为主线程不可能无时无刻的去直接查看我们的子线程是否发送了数据,我们可以通过Looper中转站来检测
具体过程:主线程初始化时已经有了Handler系统了。1. 子线程拿到主线程的Handler 2. 子线程调用SendMessage()方法向主线程发送消息 3. 主线程从消息队列中拿到消息,调用HandleMessage拿到消息。
12345678910111213141516171819202122232425262728293031private void updateBluetoot ...
Leetcode面试150题
Leetcode 面试150题NO.88 :合并两个有序数组给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。
请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
示例 1:
1234输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3输出:[1,2,2,3,5,6]解释:需要合并 [1,2,3] 和 [2,5,6] 。合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。
示例 2:
1234输入:nums1 = [1], m = 1, nums2 = [], n = 0输出:[1]解释:需要合并 [1] 和 [] 。合并结果是 [1] 。
...