Anred's Blog


  • 首页

  • 分类

  • 标签

  • 关于

  • 归档

  • 搜索

DDIA-01.可靠、可扩展、可维护的应用

发表于 2021-09-26 | 分类于 DDIA | | 阅读次数:
字数统计: 448

第一部分 数据系统的基础

1.可靠、可扩展、可维护的应用

本书主要讲述的内容是数据系统的原理与实践,以及如何构建数据密集型应用。目前的很多应用都是数据密集型,而不是计算密集型。计算性能基本不是大多数应用的限制因素,而是通常大量的数据信息。这些数据信息如何存储为了下次查找(database),加速读取(cache),根据索引查找(index),流处理?,大量增加数据(批处理)。由于不同场景对于性能,数据访问方式,具体实现的要求不同,数据系统有很多。对于数据系统,我们主要关注可靠性、可扩展性和可维护性3点。

可靠性

数据系统需要持续正常工作,即使面对多样的问题。

问题主要包括硬件问题、软件问题以及人的问题。

  • 硬件问题主要需要冗余备份、快速恢复等方法解决。

  • 软件问题可能会导致级联的问题。解决方法包括仔细考虑系统的假设与交互、全面测试、进程孤立、允许进程崩溃与重启、评测监控以及分析系统的行为。

  • 人的问题的解决方法包括最小化错误产生的可能(交互应当简单),环境解耦(方便沙箱测试),全局测试,快速恢复,设置详细清晰的监控(包括性能、错误率),好的训练。

可靠性的重要性在于我们对用户是有责任的。如果用户存储家庭照片的应用的数据库突然崩溃,他们会怎么想。

可扩展性

安全类错题集

发表于 2020-08-07 | 分类于 基础知识 | | 阅读次数:
字数统计: 1.1k

安全类错题集

  1. 常用android代码混淆工具:proguard。

  2. android app常见的调试手段有:重打包apk并设置AndroidManifest.xml的debuggable属性为true;ida或smalidea动态调试;frida hook框架;xposed hook框架。

  3. int i = s.size() //错误

    String 类取长度的方法为: length() 。

  4. 在Java多线程中,请用下面哪种方式不会使线程进入阻塞状态:yield()。 yield:让步,运行态->就绪态 。

  5. redis未授权的利用方法 :写入ssh秘钥;向web目录中写入webshell;向crontab中写入计划任务。

  6. HTTP返回码301代表永久性转移,对于301请求,搜索引擎或者浏览器都可以把跳转后的地址缓存下来,下一次不必发送这个请求。

  7. PIE全称是位置无关的可执行文件,中文解释为地址无关重定向文件,该技术是一个针对的代码段(.text),数据段(.data),未初始化变量变量(.bss)等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都转换加载地址,从而不能通过ROPgadget等一些工具来帮助解题。

  8. 端口服务可能导致命令执行:redis;mysql;rsync。

  9. Android应用Receiver注册的两种形式是:静态注册和动态注册。

  10. 爬虫和反爬虫定义:爬虫:使用任何技术手段,批量获取网站信息的一种方式。反爬虫:使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。

  11. notify()方法只唤醒一个等待线程并使该线程执行,如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。notifyall()会唤醒所有等待的线程,哪个线程将会第一个处理取决于操作系统的实现。

  12. 当线程执行wait()方法时,会释放当前的锁,然后让出CPU,进入等待状态,属于Object的成员方法。

  13. sleep()是一个静态方法,一个线程调用sleep方法后并不会释放他所持有的所有对象锁,但是sleep的运行过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果程序捕获了这个异常,那么就会继续执行catch语句块以及以后的代码。

  14. 数字签名 elgamal算法的原理是扩展欧几里得定理。

  15. 重放攻击(Replay Attacks)又称重播攻击、回放攻击,是指攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。

  16. Smurf攻击通过使用将回复地址设置成受害网络的广播地址的ICMP应答请求(ping)数据包,来淹没受害主机,最终导致该网络的所有主机都对此ICMP应答请求做出答复,导致网络阻塞。是一种拒绝服务攻击。

  17. ARP欺骗通过欺骗局域网内访问者PC的网关MAC地址,使访问者PC错以为攻击者更改后的MAC地址是网关的MAC,导致网络不通。此种攻击可让攻击者获取局域网上的数据包甚至可篡改数据包,且可让网络上特定计算机或所有计算机无法正常连线。

  18. shell脚本的特殊变量:$0(当前脚本文件名)、$n(传递给脚本或函数的参数)、$#(传递给脚本或函数的参数个数)、$*(传递给脚本或函数的所有参数,“”包含时会表现为一个整体)、$@(传递给脚本或函数的所有参数)、$?(上个命令的退出状态或函数的返回值)和$$(当前shell的进程ID;对于shell脚本,就是脚本所在进程ID)

  19. 安卓代码混淆原因: 优化java的字节码 ; 减小apk文件的大小,在混淆过程中会删除未使用过的类和成员 ; 代码安全,使类、函数、变量名随机变成无意义的代号形如:a,b,c…之类。防止app被反编译之后能够很容易的看懂代码。

操作系统基础知识

发表于 2020-08-06 | 分类于 基础知识 | | 阅读次数:
字数统计: 2.3k

操作系统基础知识

进程

进程是正在执行的程序,是操作系统资源分配的基本单位。一般包含指令、数据和PCB。

孤儿进程是指父进程退出,还在运行的子进程。孤儿进程会被init进程(id为1)收养,不会对系统造成危害。

僵尸进程是指子进程的进程描述符在退出时不会释放,父进程同时也没有进行wait()或waitpid()操作获取子进程信息,因此子进程的进程描述符还会保存在系统中。由于进程号是有限的,如果产生大量的僵尸进程,将会没有可用的进程号而导致系统不能产生新的进程。解决办法是杀死父进程。使之成为孤儿进程。

守护进程(daemon)是运行在后台的一种特殊进程,它是独立于控制终端的,并在周期性地执行某些任务。

线程

线程是进程内部的不同执行路径,是操作系统独立调度的基本单位。一个进程可以有多个线程,线程共享进程资源。浏览器进程有多个线程,如http请求线程、事件响应线程和渲染线程等等,可并发执行。

进程与线程的区别

拥有资源:进程是资源分配的基本单位,但线程不拥有资源,线程可以访问隶属于进程的资源。

调度:线程是独立调度的基本单位。

系统开销:创建、撤销和切换进程时的开销大于创建、撤销和切换线程时的开销。由于执行进程的操作时,系统需要分配或回收资源,如内存空间、I/O设备。进程切换时,需要保存当前cpu环境,进行新进程cpu环境的设置;而线程切换时只需要保存和设置少量寄存器内容,开销小。

通信方面:线程间可以通过直接读写同一进程的数据进行通信,而进程之间需要进行IPC进程间通信。

线程有哪两种?

用户级线程:有关线程管理的工作都应用程序完成。用户级线程的好处时非常高效,不需要进入内核空间,但并发效率不高。

内核级线程:有关线程管理的工作都有内核完成。应用程序调用内核线程的接口来进行线程管理。优点是内核可以将不同线程更好地分配到不同CPU,以实现真正地并行计算。

现代操作系统往往组合方式实现多线程,线程创建完全在用户空间中完成,并且一个应用程序中的多个用户级线程被映射到一些内核级线程中。

并发和并行

并发是一段时间内,多个任务都会被处理;但某一时刻,只有一个任务在执行。单核处理器可以做到并发。

并行是在同一时刻,有多个任务在执行。需要多核处理器。

分时系统和实时系统

分时系统就是系统把CPU时间分成很短的时间片,轮流地分配给多个作业。对多个用户的多个作业都可以保证足够快的响应时间,并且有效提高了资源利用率。

实时系统是系统对外部输入的信息,能够在规定的时间内处理完毕并做出反应。优点时集中地及时地处理并作出反应,高可靠,安全性。

进程状态

创建、就绪、运行、终止和阻塞。

就绪状态是进程获得除了CPU之外的一切所需资源,一旦得到CPU即可运行。

阻塞状态为等待某资源或I/O。

运行态->阻塞态往往是由于等待外设,等待主存等资源分配或等待人工干预。

运行态->就绪态往往是时间片用完或更高优先级的进程抢占处理器。

进程调度算法

先来先服务:有利于长作业,不利于短作业。短作业等待时间过长。对I/O密集型进程也不利。

短作业优先:按估计运行时间最短的顺序进行调度。长作业可能会饿死,一直有短作业到来,长作业就永远得不到调度。

最短剩余时间优先:短作业优先的抢占版。

时间片轮转:将所有就绪进程按先来先服务排成队列,每次调度,把CPU时间分配给队首进程,执行一个时间片。时间片用完时,将进程送往就绪队列的末尾,同时继续把CPU时间进行分配。

时间片太小进程切换的时间花费多。

时间片过长则实时性就不能保证。

优先级调度:每个进程分配优先级,抢占式。为防止低优先级得不到调度,可以随着时间的增加,增加等待进程的优先级。

抢占式:操作系统可以强行将运行的进程暂停,调度器将CPU分配给其他就绪进程。

非抢占式:调度器一旦把处理机分配给某进程,便可以一直让他运行下去,知道阻塞或完成。

上下文切换

是一种将CPU资源从一个进程分配到另一个进程的机制。

死锁

在两个或多个并发进程中,如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么该进程集合就产生了死锁。

死锁条件:(1)互斥:每个资源要么已经分配给了一个进程,要么就是可用的。(2)占有和等待:已经得到了某个资源的进程可以再请求新的资源。(3)不可抢占:已经分配给一个进程的资源不能强制性地被抢占,只能被占有进程显式地释放。(4)环路等待:有2个或2个以上的进程组成一条环路,每个进程等待下一个进程所占有的资源。

解决办法:

鸵鸟策略:直接忽略死锁。解决死锁代价很高,但死锁影响没那么大,发生概率不高。

死锁预防:破坏4个必要条件,避免发生死锁。

死锁避免:允许3个必要条件,但通过算法判断资源请求是否可能导致循环等待的形成并相应决策,来避免死锁点的产生。线程启动拒绝:如果一个线程的请求会引发死锁,则不允许其启动。资源分配拒绝:如果一个线程增加的资源请求会导致死锁,则不允许此申请。

死锁检测和恢复:维护一个系统的资源分配图,定期进行死锁检测,如果有则解决死锁。

进程同步

临界区、互斥量、信号量、管程。

进程间通信:

管道:实质为内核缓冲区,可看成循环队列。半双工。

命名管道:FIFO,提供了一个路径名与之关联,不具有亲缘关系的进程也可以彼此通信。

消息队列:消息的链表,存放在内存中。存在唯一标识。

共享内存:多个进程可以直接读写同一块内存空间。

信号量:控制多个进程对共享资源的访问。

socket:套接字,不在同一主机的两个进程网络通信。

磁盘调度算法

先来先服务:按照磁盘请求顺序调度。优点是公平和简单。但平均寻道时间可能会较长。

最短寻道时间优先:优先调度与当前磁头最近的磁道。可能会发生饥饿。

电梯算法scan扫描算法:总是保持一个方向运行,直到该方向没有请求为止。解决了饥饿问题。

虚拟内存

物理内存扩充成更大的逻辑内存,从而让程序获得更多的可用内存。使用部分加载的技术,从而能加载更多的进程,看起来内存变大了,磁盘或者硬盘。

页面替换算法

最佳算法:选择被换出的页面最长时间内不再被访问,通常可以保证获得最低的缺页率。理论算法。

先进先出:但也可能会把经常访问的页面换出。

LRU:根据过去判断。将最近最久未使用的页面换出。维护一个链表。页面访问则将之移动到表头。由于需要更新链表,因此LRU代价很高。

时钟算法:时钟算法使用环形链表,0则不替换,1则替换。

leetcode总结

发表于 2020-07-22 | 分类于 leetcode | | 阅读次数:
字数统计: 287

LeetCode

1. 数组

(1)一定要弄清输入值的数据范围。优先考虑极端情况,如输入数组长度为0的情况以及边界的处理情况。

(2)LeetCode错误:control reaches end of non-void function[werror=return-type];

有时我们在一块程序里已经有return,但不是在这块代码的结尾,leetCode也会编译不通过,所以我们也要在函数的代码块结尾也return一下。

(3)处理大小比较部分的时候,一定记得考虑等于的情形是否满足要求。

(4)C++中,使用i++还是++i?使用++i更好。原因:因为前置版本的递增运算符避免了不必要的工作,它把值加1后直接返回改变了的运算对象。与之相比,后置版本需要将原始值存储下来以便于返回这个未修改的内容。如果我们不需要修改前的值,那么后置版本的操作就是一种浪费。

(5)float数据的正确表示

1
2
3
float f = 1.1;   //错误 1.1是double类型 java中
float f = 1.1f; //正确
double d = 34.4; //正确

Android安全之组件安全

发表于 2020-07-21 | 分类于 android security | | 阅读次数:
字数统计: 1.7k

Android 安全之组件安全

1. 暴露Activity组件

漏洞利用的目的:

通过当前已经暴露的组件跳转访问到私有组件界面。

漏洞利用过程:

根据反编译可以看出,触发通过的条件是传入值为1的int变量key和值为“hello”的String变量value。

1
2
3
4
5
6
7
8
9
10
11
12
private void a() {
Intent intent = getIntent();
if (intent != null) {
int i = intent.getIntExtra("key", 0);
String str = intent.getStringExtra("value");
if (i == 1 && "hello".equals(str))
dosomething();
}
}
private void dosomething() {
startActivity(new Intent((Context)this, NoExportActivity.class));
}

由此,利用adb命令访问activity组件:

1
adb shell am start -n com.example.bughunter/com.example.bughunter.ComponentSecurity.ExportActivity --ei key 1 -e value "hello"

利用start访问activity组件,其中“-n”后面是“包名/类名”,“–ei”表示传入int类型值,“-e”表示传入String值。由此,即可进入私有隐藏界面。

1
阅读全文 »

android_security

发表于 2020-07-15 | 分类于 android security | | 阅读次数:
字数统计: 990

Android Security

1.Android基础知识


Android系统架构主要分为:应用层(java)、框架层(java)、库文件(C)&Android运行时(运行java代码的虚拟机)和Linux kernel。

Android四大组件:

Activity:窗口界面。Activity之间通过Intent进行通信。android应用的每一个Activity都必须在AndroidManifest.xml配置文件中声明。

Service:运行于后台,一般不需要与用户交互。一般为其他组件提供后台服务或监控其他组件的运行。有两种工作状态,一种是启动状态,主要用于执行后台计算;另一种是绑定状态,主要用于其他组件和service的交互。配置文件中需要声明全部service。

Content Provider:存放和获取数据并使这些数据可以被所有应用程序访问。应用程序间共享数据的唯一方法。

Broadcast Receiver:为了便于进行系统级别的消息推送。本质是一种全局的监听器,可以实现系统中不同组件之间的通信。发送广播用Intent,接收广播用广播接收器BroadcastReceiver。静态注册&动态注册。

阅读全文 »

常用python代码

发表于 2020-07-13 | 分类于 python | | 阅读次数:
字数统计: 502

常用python代码


1. numpy array、torch tensor和Image之间相互转换

(1)numpy array与Image之间互相转换

1
2
3
4
5
6
from PIL import Image  
import numpy as np
im = Image.open("a.jpg")

img = np.array(im) # image to numpy array
im=Image.fromarray(img) # numpy array to image

(2)numpy array与torch tensor之间互相转换

1
2
3
4
5
6
import torch
import numpy as np
a = torch.ones(5)
b = a.numpy() # torch tensor to numpy array
a = torch.from_numpy(b) # numpy array to torch tensor
# 转换后的tensor与numpy array指向同一地址,对一方值的改变会改变另一方

(3)torch tensor与Image之间互相转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PIL import Image
import torch
import torchvision.transforms as transforms

path_img = "./1.bmp"
img_pil = Image.open(path_img).convert('RGB')
img_tensor = transforms.Compose([
# transforms.Resize((224, 224)),
transforms.ToTensor(), # Image to torch tensor
# transforms.Normalize(norm_mean, norm_std),
])(img_pil)

img = transforms.ToPILImage()(img_tensor)
# torch tensor to Image
阅读全文 »

汇编语言程序设计笔记_存储器寻址

发表于 2020-03-25 | 分类于 汇编语言 | | 阅读次数:
字数统计: 105

更灵活的定位内存地址的方法

and和or指令

and指令可将操作对象的相应位设为0,其他位不变。

or指令可将操作对象的相应位设为1,其他位不变。

ASCII 码

一种编码方案。字符存储在计算机中的是ASCII码转换的二进制。

大小写转换的问题

‘A’ ASCII 41H ‘a’ ASCII 61H 小写比大写ASCII码大20H。

嵌入式系统安全笔记_接口技术

发表于 2020-03-24 | 分类于 嵌入式系统安全 | | 阅读次数:
字数统计: 792

嵌入式接口技术——通信

找例程编译。学会修改例程,提高可靠性。

硬件:通信(相互通道)、输入(前向通道)、输出(后向通道)

部件:传感器、执行器、人机界面、相互通信、电源

阅读全文 »

网络安全笔记_缓冲区溢出

发表于 2020-03-23 | 分类于 网络安全 | | 阅读次数:
字数统计: 432

缓冲区溢出

缓冲区溢出攻击的原理

1、缓冲区溢出攻击模式:

  • 找到可利用的缓冲区溢出隐患
  • 注入恶意代码
  • 溢出缓冲区
  • 重定向到攻击程序
  • 执行攻击程序
  • 获得控制权
  • 任意地执行程序
阅读全文 »
123
Peng Zhang

Peng Zhang

21 日志
14 分类
31 标签
GitHub E-Mail
© 2021 Peng Zhang | Site words total count: 16.8k
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
  |  访问量   |  访客
0%