Java中double/float四舍五入取整(ceil/floor/round)

执行测试:

参考链接


JAVA中double转int类型按四舍五入取整(实用)

Android 控件 RecyclerView

概述

RecyclerView是什么

从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加强大和灵活。RecyclerView的官方定义如下:

A flexible view for providing a limited window into a large data set.

从定义可以看出,flexible(可扩展性)是RecyclerView的特点。

RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。

RecyclerView的优点

RecyclerView并不会完全替代ListView(这点从ListView没有被标记为@Deprecated可以看出),两者的使用场景不一样。但是RecyclerView的出现会让很多开源项目被废弃,例如横向滚动的ListView, 横向滚动的GridView, 瀑布流控件,因为RecyclerView能够实现所有这些功能。

比如:有一个需求是屏幕竖着的时候的显示形式是ListView,屏幕横着的时候的显示形式是2列的GridView,此时如果用RecyclerView,则通过设置LayoutManager一行代码实现替换

RecylerView相对于ListView的优点罗列如下:

  • RecyclerView封装了viewholder的回收复用,也就是说RecyclerView标准化了ViewHolder编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
    直接省去了listview中convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。
  • 提供了一种插拔式的体验高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。
  • 设置布局管理器以控制Item布局方式横向竖向以及瀑布流方式
    例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还StaggeredGridLayoutManager等)。也就是说RecyclerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。
  • 可设置Item的间隔样式(可绘制)
    通过继承RecyclerView的ItemDecoration这个类,然后针对自己的业务需求去书写代码。
  • 可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecyclerView有其自己默认的实现。

但是关于Item的点击和长按事件,需要用户自己去实现。

继续阅读Android 控件 RecyclerView

todo-mvvm-databinding源码分析

MVVM框架 todo-mvvm-databinding 项目例子。

MVP框架 todo-mvp 项目例子。

目的

分析和学习官方mvvm框架的设计模式和数据绑定在其中的具体用法,制作一套符合当前公司业务场景的mvvm框架。其中也分析一下数据源在项目中的设计以及框架中单元测试的实施。

设计模式

MVVM框架中的ViewModel相比MVP框架中的Presenter起着类似的作用。两种框架结构的不同之处在于View分别与ViewModelPresenter进行通信:

  • 当MVVM框架中数据发生变化时会影响ViewModel的改变,View会自动更新库或框架。你不能直接通过ViewModel来修改View
  • 在这个项目中,你可以使用布局文件将ViewModel中的变量绑定到特定的UI元素上(如TextViewImageView)。数据绑定可以确保View和ViewModel保持双向同步,如下图所示。

继续阅读todo-mvvm-databinding源码分析

SQL中MAX函数与Group By获取同一字段重复的数据最大的一条

SQLMAX函数与Group By一起使用,获取同一字段重复的数据只取记录最大的一条,如下:

如果想找到每个clz里面的最大的age,则需要使用Group By和Max

如下的SQL语句,则输出结果有错误:

虽然找到的age是最大的age,但是与之匹配的用户信息却不是真实的信息,而是Group By分组后的第一条记录的基本信息。

如果我使用以下的语句进行查找,则可以返回真实的结果。

参考链接


resize2fs:Memory alloction failed while trying to resize

最近入手一块 12T 的西数红盘,打算安装到 WD MyCloud Gen1 上,从 4TB 版本升级到 12TB 版本,作为 TimeMachine 来用。

使用 拯救死翘翘了的WD MyCloud 方式恢复镜像之后,最后一步执行

结果报告如下错误:

这个原因网上查询了很久,基本上断定是 e2fsprogs 1.42.5 的 BUG,这个问题在  e2fsprogs 1.42.9 版本修复。修复内容参考代码下的 debian/changelog

关键日志如下:

编译过程参考 How to successfully build packages for WD My Cloud from source 中对于 e2fsprogs 1.42.13 的编译。

参考链接


error: cannot find symbol import android.support.v7.widget.ListViewCompat;

项目中,当com.android.support:appcompat-v7升级到28之后,出现如下错误

这个原因是由于com.android.support:appcompat-v7升级到28之后

已经不包含 android.support.v7.widget.ListViewCompat;这个类了。

我们要么使用android.support.v4.widget.ListViewCompat;替代,要么直接使用android.widget.ListView

目前的解决方法是直接使用android.widget.ListView

参考链接


向量与矩阵相乘

最近在看"程序员的数学"系列的"线性代数"部分,当阅读向量矩阵乘法的时候,感觉各种别扭。以前学习的时候,简单的把向量乘以矩阵简化理解成矩阵乘以一维矩阵,然后交换位置进行矩阵乘法。也就是 n 维向量乘以 m*n 矩阵,变成m*n 矩阵乘以 n*1 维矩阵。以后一直是这么计算的。

这么理解计算结果是正确的,但是却不利于理解矩阵的映射特性,矩阵就是映射 这句话怎么都理解不对了!!

书本中一直说向量是竖排的,类似这样 $\begin{bmatrix} v1\\\ v2\\\ v3\\\ v4 \end{bmatrix}$。

并且说 n 维向量乘以 m*n 矩阵,得到 m 维向量。这个各种不理解,把列向量理解成了列矩阵,因此这个乘法各种不理解,不符合矩阵的运算规则。这么多年过去了,基础知识都理解的不正确,呵呵!! 

其实,书上 1.16部分已经解释过,列向量计算的时候,要放倒,变成 $\begin{bmatrix} v1& v2& v3& v4 \end{bmatrix}$ 的样子,再参与计算。计算结果再切换成$\begin{bmatrix} v1\\\ v2\\\ v3\\\ v4 \end{bmatrix}$的列向量的样子,这样就可以完整的理解整个映射过程了。

继续阅读向量与矩阵相乘

加快Android Studio 3.6.3的编译速度

1. 加大给Android Studio 3.6.3分配的内存

打开Android Studio的安装目录,找到虚拟机的配置文件,进行修改,如下:

Windows
编辑安装目录下的bin\studio64.exe.vmoptions

macOS Catalina(10.15.4)

继续阅读加快Android Studio 3.6.3的编译速度

macOS Catalina(10.15.4)安装应用提示 '无法打开"XXXX",因为无法验证开发者' 的解决方法

macOS Catalina(10.15.4) 使用HomeBrew安装SageMath

启动的时候提示如下:

继续阅读macOS Catalina(10.15.4)安装应用提示 '无法打开"XXXX",因为无法验证开发者' 的解决方法

macOS Catalina(10.15.4)下RsaCtfTool的安装及使用

在CTF比赛中,往往会涉及到RSA解密类的题目,有了这个工具(基于python3.x)做起来就得心应手了。

这个也可以作为安全工具来使用,检查密钥的安全性。

RSA简介

为了方便理解,先对RSA密钥体制做个简略的介绍。

  1. 选择两个大的参数,计算出模数 N = p * q
  2. 计算欧拉函数 φ = (p-1) * (q-1),然后选择一个e(1<e<φ),并且e和φ互质(互质:公约数只有1的两个整数)
  3. 取e的模反数d,计算方法为:e * d ≡ 1 (mod φ) (模反元素:如果两个正整数e和n互质,那么一定可以找到整数d,使得 e * d - 1 被n整除,或者说e * d被n除的余数是1。这时,d就叫做e的“模反元素”。欧拉定理可以用来证明模反元素必然存在。两个整数a,b,它们除以整数M所得的余数相等:a ≡ b(mod m),比如说5除3余数为2,11除3余数也为2,于是可写成11 ≡ 5(mod 3)。)
  4. 对明文m进行加密:c = pow(m, e, N),可以得到密文c。
  5. 对密文c进行解密:m = pow(c, d, N),可以得到明文m。
整理:

pq:两个大的质数,是另一个参数N的的两个因子。
N:大整数,可以称之为模数
ed:互为无反数的两个指数
cm:密文和明文
(N, e):公钥
(N, d):私钥
pow(x, y, z):效果等效pow(x, y)% z, 先计算xy次方,如果存在另一个参数z,需要再对结果进行取模。
密钥长度:n以二进制表示的的位数,例如密钥长度为512代表n用二进制表示的长度为512bit

RSA安全性分析

对于RSA加密算法,公钥(N, e)为公钥,可以任意公开,破解RSA最直接(亦或是暴力)的方法就是分解整数N,然后计算欧拉函数φ(n)=(p-1) * (q-1),再通过d * e ≡ 1 mod φ(N),即可计算出 d,然后就可以使用私钥(N, d)通过m = pow(c,d,N)解密明文。

保障RSA的安全性

1. 定期更换密钥
2. 不同的用户不可以使用相同的模数N
3. p与q的差值要大,最好是差几个比特
4. p-1与q-1都应该有大的素因子,一般建议选择的两个大素数p、q使得p=2p+1和q=2q+1也是素数
5. e的选择不要太小
6. d的选择也是不可以太小,最好满足d>=n的4分之1

参考链接