目录
PETool
介绍
软件架构
安装教程
使用说明
打开后上半部分显示进程列表,下半部分的列表是当前选中进程的模块列表
PE查看,点击PE查看按钮弹出一个文件选择对话框,选择一个PE文件,点去确定,弹出此文件的PE信息
程序加壳,把要加壳的程序字节流加密后放到一个提前准备好的ShellCore.exe的新增节中,ShellCore.exe实现将新节点中的字节解密后把Imagebase位置指向新地址
DLL注入:选中一个进程,点击dll注入,弹出文件选择对话框,选中要注入的dll
源码地址:
PETool 介绍 Pe查看工具、进程和进程中模块查看基地址和镜像大小、Dll注入
软件架构 VC++、WindowsXP
安装教程 直接打开exe,不需要安装
使用说明 打开后上半部分显示进程列表,下半部分的列表是当前选中进程的模块列表 PE查看,点击PE查看按钮弹出一个文件选择对话框,选择一个PE文件,点去确定,弹出此文件的PE信息 程序加壳,把要加壳的程序字节流加密后放到一个提前准备好的ShellCore.exe的新增节中,ShellCore.exe实现将新节点中的字节解密后把Imagebase位置指向新地址 DLL注入:选中一个进程,点击dll注入,弹出文件选择对话框,选中要注入的dll 源码地址: https://gitee.com/zhangruyi/petool
由于是外部项目,不是自己写的,出现了这个问题;试了各种办法都没用,自己搭建demo都正常,肯定是项目代码哪边配置或者代码逻辑出了问题,进入mq后台管理发现
没有消费者注册。最后在对比排除各种情况后发现是spring.rabbitmq.listener.simple.auto-startup的值设置为了false,容器启动时不注册listener,改为true后接收到消息并消费。
开机自启动有两个方法:
一 、把程序的快捷方式放在”开始---启动“目录下。
二、把程序的安装目录放在注册表”“。
实现方法一:
1、编写bat脚本。执行bat启动exe。
a)核心:cmd命令 :start /b /d
//startFrs.bat
1 @set exeName=Frs.exe
@set FrsPath=..\dispatcher\
@set currPath=%~dp0
@set exePath=%currPath%%FrsPath%
@set exeAllPath="%exePath%%exeName%"
start /b /d "%exePath%" %exeName%
2、bat在执行cmd命令时,会有黑框。如果不想黑框出现,编写vbs脚本调用bat脚本。
//startFrs.vbs
public const vbQuote=""""
temp="C:\Program Files (x86)\simpleTrbo\centerAutoRestart\startFrs.bat"
batPath=vbQuote & temp & vbQuote
Set wshell=CreateObject("WScript.Shell")
wshell.Run batPath,,false
Set wshell=Nothing
3、InstallShield---》Project Assistant----》Application Files。
a)如下图方式,添加 StartUp Folder。
b)InstallShield---》Project Designer----》Organization---》Component----》StartUp--》Files----》右边右键添加上面创建的vbs脚本。
备注:bat、vbs文件,如果安装目录是自定义的,那么InstallScript里面还需要运行时修改vbs里面调用bat的路径
实现方法二:
1、InstallShield--》Project Assistant ----》Application Registry。
a)按照此路径依次创建(HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows / CurentVersion / Run)
MapReduce最初进入我们的实现,是作为Hadoop的核心计算引擎,负责分布式计算,也作为编程模型使用。在整个Hadoop生态当中,MapReduce的影响意义是深远的,也是第一代计算框架代表产品。今天的大数据开发学习分享,我们就来讲讲MapReduce应用场景相关的知识。
首先,MapReduce的设计初衷就是为了大规模数据集的批量处理,提升整体的数据处理效率,而MapReduce诞生之初,典型的应用就是使用MapReduce进行长句切割,然后进行词频统计,这也为MapReduce的应用场景埋下了伏笔。
MapReduce的计算流程
简单来说,Mapreduce的运算过程就是进行拆解-排序-汇总,解决的就是统计的问题,使用的思想就是分治的思想。
整个过程就是先读取文件,接着进行split切割,变成一个一个的词,然后进行map task任务,排列出所有词的统计量,接着sorting排序,按照字典序来排,接着就是进行reduce task,进行了词频的汇总,最后一步就是输出为文件。
其中对应着的是Hadoop Mapreduce对外提供的五个可编程组件,分别是InputFormat、Mapper、Partitioner、Reduce和OutputFormat。
MapReduce的应用场景
MapReduce的产生是为了把某些大的问题分解成小的问题,然后解决小问题后,大问题也就解决了。那么一般有什么样的场景会运用到呢?这里据几个非常典型的例子——
计算URL的访问频率
搜索引擎的使用中,会遇到大量的URL的访问,可以使用MapReduce来进行统计,得出(URL,次数)结果,在后续的分析中可以使用。
倒排索引
Map函数去分析文件格式是(词,文档号)的列表,Reduce函数就分析这个(词,文档号),排序所有的文档号,输出(词,list(文档号)),这个就可以形成一个简单的倒排索引,是一种简单的算法跟踪词在文档中的位置。
Top K问题
在各种的文档分析,或者是不同的场景中,经常会遇到关于Top K的问题,例如输出这篇文章的出现前5个最多的词汇。这个时候也可以使用MapReduce来进行统计。
关于大数据开发学习,MapReduce应用场景,以上就为大家做了简单的介绍了。MapReduce虽然在现在的大数据技术生态当中,需要实际编程的任务很少,但是该学还是得学。
notion api 前几天notion开放了api,notion开发者文档可以了解。
python操作notion 创建一个 Notion 机器人,输入名字,即可快速创建。
获取Token,点击 show,然后复制备用。
在需要使用API的页面中,点击 Share 并选择 Invite ,将机器人邀请进去,让其用于编辑的权限。
获取数据表的 database_id,点击数据表右上方的 ... 选择 Copylink ,
连接如下方:https://www.notion.so/xinhuoip/9bcf00dce55c42799f3b177dc325aa18?v=217bbe82893e4e4aa228a19f3f2dc888 ,其中 9bcf00dc-e55c-4279-9f3b-177dc325aa18 即为database_id。
使用python的requests库get方法来读取notion页面数据,示例代码如下:
import requests token = '这个是你创建机器人时获取到的见第二步' r = requests.request( "GET", "https://api.notion.com/v1/pages/5b35b115ddc442e080f1b1b27e5b0ae0",#字符串为页面id headers={"Authorization": "Bearer " + token, "Notion-Version": "2021-05-13"}, ) print(r.txet) 以上代码输出结果如下:
通过python的requests库中的post方法来操作notion添加数据,示例代码如下:
import requests token = '第二步中获取到的token值' def post(url,title,content): requests.request("POST", "https://api.notion.com/v1/pages", json={ "parent": {"type": "database_id", "database_id": "9bcf00dc-e55c-4279-9f3b-177dc325aa18"}, "properties": { "来源": {"url": url}, "标题": {"title": [{"type": "
之前每次想要获取Spring上下文【ApplicationContext】的时候,都去现查方案。本文针对获取Spring ApplicationContext的方式做了梳理,总结。
1. 概念 ApplicationContext是什么?
简单来说就是Spring中的容器,可以用来获取容器中的各种bean组件,注册监听事件,加载资源文件等功能
2. 获取ApplicationContext的方式 2.1. 创建工具类 通过此工具类,可以方便的获取bean组件, 获取配置信息等
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.math.NumberUtils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; public class SpringUtil { private static ApplicationContext applicationContext = null; private static Environment environment = null; public static void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringUtil.applicationContext == null) { SpringUtil.applicationContext = applicationContext; environment = applicationContext.getEnvironment(); //TODO 设置后,可以做一些操作 } } //获取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } public static Environment getEnvironment() { return environment; } //通过name获取 Bean.
51单片机具有两条查表指令,用于从 ROM 中读出预存的数据:
MOVC A, @A + PC
MOVC A, @A + DPTR
其中前一条指令的用法,比较难,使用的时候,需要计算一个“偏移量”。不了解“指令的字节数”的人,都不清楚应该如何计算。
最佳答案:
51单片机汇编语言有一条查表指令是:
MOVC A, @A + DPTR
它不是单独使用的,要和 DB 伪指令配套使用。
例如:若累加器A中有一个0~9的数,请用查表法求出该数的平方值,设平方表表头地址为1000H。
程序如下:
;-------------------------------------
MOV DPTR, #1000H
MOVC A, @A + DPTR
……
ORG 1000H
DB 0, 1, 4, 9, 16, 25......
;-------------------------------------
DB 伪指令从 ROM 1000H 开始,顺序存放了一系列的“平方”数据。
MOVC A, @A+DPTR 指令中的A,如果等于0,就会在“平方”数据中取出第0个,就是0;
MOVC A, @A+DPTR 指令中的A,如果等于1,就会在“平方”数据中取出第1个,就是1;
MOVC A, @A+DPTR 指令中的A,如果等于2,就会在“平方”数据中取出第2个,就是4;
MOVC A, @A+DPTR 指令中的A,如果等于3,就会在“平方”数据中取出第3个,就是9;
……
MOVC A, @A+DPTR 指令中的A,如果等于9,就会在“平方”数据中取出第9个,就是81。
硬件型号:UNSIGNED-1
系统版本:编程系统
C/C++编程语言中,int表示整型变量,是一种数据类型,用于定义一个整型变量,在不同编译环境有不同的大小,不同编译运行环境大小不同。在32/64位系统中都是32位,范围为-2147483648~+2147483647,无符号情况下表示为0~4294967295。
具有整数类型的项的值是它对应的数学整数。积分类型可以是无符号的(只能表示非负整数)或有符号(也能表示负整数)。
整数值通常在程序的源代码中指定为可选的前缀为+或 - 的数字序列。一些编程语言允许其他符号,例如十六进制或八进制。一些编程语言也允许数字组分隔符。
此数据的内部表示形式是值存储在计算机内存中的方式。与数学整数不同,计算机中的典型数据具有一些最小和最大可能值。
正整数的最常见表示是使用二进制数字系统的一串位。存储位的存储器字节的顺序是变化的;看到字节序。整数类型的宽度或精度是其表示中的位数。具有n位的整数类型可以编码2数字;例如,无符号类型通常表示非负值0到2-1。有时使用对位模式的整数值的其他编码,例如二进制编码的十进制或格雷码,或者诸如ASCII的打印字符码。
在二进制计算系统中有四种众所周知的方式来表示有符号数。最常见的是二进制补码,它允许带有n位的有符号整数类型表示从-2到2-1的数字。二进制补码算法很方便,因为表示和值之间存在完美的一对一对应关系(特别是没有单独的+0和-0),并且因为加法,减法和乘法不需要区分有符号和无符号类型。其他可能性包括偏移二进制,符号幅度和1'补码。
一些计算机语言以与机器无关的方式定义整数大小;其他人根据底层处理器字大小有不同的定义。并非所有语言实现都定义所有整数大小的变量,并且在特定实现中定义的大小甚至可能不是不同的。一种编程语言中的整数可以是不同语言或不同处理器上的不同大小。
其中整型变量包括下面几种类型:
1、有符号基本整型,关键字:[signed] int,数值范围:-2 147 483 648 ~ 2 147 483 647,字节:4
2、无符号基本整型,关键字:unsigned [int],数值范围:0 ~ 4 294 967 295,字节:4
3、有符号短整型,关键字:[signed] short [int],数值范围:-32768 ~ 32767,字节:2
4、无符号短整型,关键字:unsigned long [int],数值范围:0 ~ 65535,字节:2
5、有符号长整型,关键字:[signed] long [int],数值范围:-2 147 483 648 ~ 2 147 483 647,字节:4
6、无符号长整型,关键字:unsigned long [int],数值范围:0 ~ 4 294 967 295,字节:4
scanf_s( ) --> 安全的scanf函数,第三个参数要加上最大获取多少个数据。
char s[20];
scanf("%s",s,20);
例如:
#include int main()
{
double percent;
scanf_s("%lf%%", &percent);
printf("%lf",percent);
return 0;
}
输入:du4.5%
输出:4.500000
在输入流中把%剔除了。
扩展资料:
ANSI C中没有scanf_s(),只有scanf(),scanf()在读取时不检查边界,所以可能会造成内存访问越界,例如分配了5字节的空间但是读入了10字节
char buf[5]={'\0'};
scanf("%s", buf);
如果输入1234567890,后面的部分会被写到别的空间上去。
以上代码如果用scanf_s,第二行应改为scanf_s("%s",buf,5),表示最多读取5-1个字符,因为buf[4]要放'\0'
参考资料来源:百度百科-scanf_s
原标题:第26节:乘法运算的溢出
从业十年,教你 入门 第26讲:
乘法的规律跟加法的溢出规律是一样的。举一个例子如下:
unsigned char k=30;
unsigned char n=10;
unsigned char a;
a=k*n;
分析:
k和n相乘,相当于30乘以10,运算结果是300(十六进制是0x012c)保存在一个隐藏中间变量,根据前面加法运算的规律,我猜测这个隐藏中间变量可能是unsigned int类型,然后再把这个中间变量赋值给单字节变量a,a只能接收十六进制的低8位字节0x2c,所以运算后a的数值由于溢出变成了十六进制的0x2c(十进制是44)。
由于乘法的溢出规律跟加法的溢出规律是一样的,所以不再多举例子。在实际项目中,为了避免一不小心就溢出的问题,我强烈建议,不管加减乘除,凡是参与运算的变量全部都要转化成unsigned long变量,转化的方法也跟加减运算的转换方法一致,不再详细解决这方面的内容。
现在编写一个程序来练习刚才讲到的内容,最后把程序编译后下载到坚鸿51学习板观察结果。请直接复制第十节模板程序,修改的main程序代码如下:
void main() //主程序
{
/*---C语言学习区域的开始-----------------------------------------------------------------
----------*/
unsigned char k=30;
unsigned char n=10;
unsigned char a;
a=k*n;
GuiWdData0=a; //把变量a这个数值放到窗口变量0里面显示
/*---C语言学习区域的结束-----------------------------------------------------------------
----------*/
while(1)
{
initial();
key_service();
display_service();
}
}
查看运算结果的方法。如何在坚鸿51学习板上观察变量?按下S1或者S5按键即可切换显示不同的窗口,从而显示不同的变量。按下S9按键不松手就可以切换到十六进制的显示界面,松开手后会自动切换到十进制的界面。上坚鸿51学习板观察程序执行的结果如下:
变量a为0x2c(十进制是44)。
下节预告:除法运算的常见格式。
责任编辑:
复制代码 代码如下:
//1. 写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
//功能:
//在字符串中找出连续最长的数字串,并把这个串的长度返回,
//并把这个最长数字串付给其中一个函数参数outputstr所指内存。
//例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,outputstr所指的值为123456789
#include
#include
int continumax(char *outputstr,char *inputstr)
{
assert(outputstr);
assert(inputstr);
int length = 0;
int maxlength = 0;
int i = 0;
int j = 0;
while(inputstr[i] != '\0')
{
while( inputstr[i] >='0'&& inputstr[i] <= '9')
{
length++;
i++;
}
if(length > maxlength)
{
maxlength = length;
int k = i-maxlength;
for(j = 0; j < maxlength; j++ )
从汇编的角度解析函数调用过程
看看下面这个简单函数的调用过程:
int Add(int x,int y)
{
int sum = 0;
sum = x + y;
return sum;
}
int main ()
{
int a = 10;
int b = 12;
int ret = 0;
ret = Add(a,b);
return 0;
}
今天主要用汇编代码去讲述这个过程,首先介绍几个寄存器和简单的汇编指令的意思。
先看几个函数调用过程涉及到的寄存器:
(1)esp:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
(2)ebp:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。
(3)eax 是”累加器”(accumulator), 它是很多加法乘法指令的缺省寄存器。
(4)ebx 是”基地址”(base)寄存器, 在内存寻址时存放基地址。
(5)ecx 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。
(6)edx 则总是被用来放整数除法产生的余数。
(7)esi/edi分别叫做”源/目标索引寄存器”(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.
在32位平台上,ESP每次减少4字节。
再看几条简单的汇编指令:
mov :数据传送指令,也是最基本的编程指令,用于将一个数据从源地址传送到目标地址(寄存器间的数据传送本质上也是一样的)
sub:减法指令
lea:取偏移地址
假设我们有字符串a和b,那么a.find(b)是指在a这个字符串中查找b并返回b开头字母的位置,没查到就是-1
例题: 链接
这个题有两种解法,一种是暴力嘛,因为字符串的数量也不多,还有一种呢则是利用到find函数
①首先将该串复制一遍
②遍历查找原本母串能不能找到
③找到了的话需要移动的值就是find返回的值
④没找到就是-1
结束over~
下面是针对样例2的过程
2
molzv
lzvmo
每个位操作都可操作缓冲区中的数据,缓冲区由无符号字符作为指针来指定。该指针指向足够多的字节来表示缓冲区中的位数。如果缓冲区中的位数不是8的倍数,那么说明最后一个字节的某些位没有使用。
bit_get
bit_get 操作获取缓冲区中一个位的状态。要做到这一点,首先要确定位所在的字节,然后通过一个掩码从字节中获取相应的位。掩码中设置为1的位是将要从字节中读出的位。接着用一个循环操作将位移动到适当的位置。通过索引bits中相应的字节,并应用掩码,可以获取所需的位。
bit_get的时间复杂度为O(1)。这是因为获取缓冲区中位的状态所进行的所有操作都能够在固定时间内完成。
bit_set
bit_set 操作设置缓冲区中一个位的状态。此操作与bit_get的工作方式相 似,只是它是利用掩码设置指定位的状态,而获取指定位的状态。
bit_set 的时间复杂度为O(1)。这是因为获取缓冲区中位的状态所进行的所有操作都能够 在固定时间内完成。
bit_xor
对两个缓冲区bits1和bits2进行按位异或运算,并将计算的结果放到缓冲区bitsx中。要做到这一点,将bits1中第i个位置的位与bits2中第i个位置的位进行比较,如果位值相同,将第i个位置的位置0;否则,将第i个位置的位置1。这个过程会持续下去直到size指定的每个缓冲区中的位都计算完成。
bit_xor 的时间复杂度为O(β),其中β是每个缓冲区中的位数。这是因为此操作要在毎个位上循环迭代一次。
bit_rot_left
bit_rot_left 将缓冲区指定数量的位向左轮转。首先保存最左端字节的最左端位值,然后向左一位一位地移动每个字节的位值。在移动字节的过程中,将前一个字节最右边的位移到当前字节的最左边。当处理到最后一个字节时,将其最右边的位移动到首字节的最高位上。这个过程一直持续下去直到所有的位都轮转到位。
bit_rot_left 的时间复杂度为O(nβ),其中n为要向左轮转的位的个数,β是缓冲区中位的个数。这是因为,对于每次轮转,要进行(β/8)+1次移动。
位操作的实现代码:
/* bit.c */
#include #include “bit.h”
/* bit_get */
int bit_get(const unsigned char *bits, int pos)
{
unsigned char mask;
int i;
/* Set a mask for the bit to get. */
mask = 0x80;
for (i = 0; i < (pos % 8); i++)
mask = mask >> 1;
在Windows上搭建TensorFlow
在本文中,我将详细介绍如何在Windows 10上搭建TensorFlow环境,话不多说,直接开始。
首先,需要Python环境和pip工具。
1、获取Python和pip
在Windows环境安装Python 3.x版本,通常安装包中集成了pip工具,安装会非常简单方便。具体见:https://www.python.org/downloads/windows/
完成安装后,可以打开命令提示符并键入python,以查看你正在使用的版本。这里可以看到,我下载了3.7.3版:
然后可以退出Python解释器环境:
然后在CMD中使用如下代码测试pip工具安装的情况:
pip –V
接下来,在安装TensorFlow之前,需要先检查主机的GPU是否支持,在命令提示符下,执行命令:
control /name Microsoft.DeviceManager
然后查看“显示适配器”设置,将其打开,然后阅读显示适配器的名称,看看是否支持TensorFlow的运行(一般都会支持)。
注意:下载python时一定要下载64bit的,否则会在安装TensorFlow时出现不兼容的问题。
2、安装CUDA驱动程序(若没有使用GPU,可先跳过)
要说明一点,目前TensorFlow的最高版本已经提供了对CUDA 10.1的支持,若你下载的TensorFlow版本 >=1.13.0,则需要下载CUDA >=10.0的版本,否则会出现版本不兼容的问题。访问CUDA的下载网站,传送门:https://developer.nvidia.com/cuda-toolkit ,请确保通过选择下面的“Legacy Releases”链接来下载正确版本的驱动程序,如下图所示:
选择legacy Releases后,选择你需要的版本,如图:
并记住要选择安装local版本(因为network版本运行时比较依赖网络,网络不好容易崩掉):
然后下载并安装就OK啦(我使用的TensorFlow版本为1.14.0,故选择了10.0版本的CUDA进行下载安装)。
安装时可以直接选择精简版进行安装,等待一会儿就安装完成了。
附:如果在安装CUDA时出现问题或错误,这篇博客可以给你很大的帮助哦,传传传送门:https://blog.csdn.net/zzpong/article/details/80282814 。
但是,在运行TensorFlow之前,还需要一个与主机的CUDA版本相匹配的cuDNN版本(后面会介绍哦)。
3、安装TensorFlow
总有人说TensorFlow安装过程十分困难,但是其实细细想来这是其中比较简单的一个步骤了,具体操作如下。
直接在CMD命令行中输入:
pip install tensorflow
然后就会看到开始下载并安装一个版本的TensorFlow了,等待安装完成,在命令提示符窗口中输入:
python
打开Python编辑器,在其中输入:
import tensorflow as tf
若未提示错误,则说明TensorFlow下载安装成功啦,然后再输入:
print(tf.version)
就会输出当前安装的TensorFlow的版本号了。
注意:若提示错误缺少CUDA或NVIDIA,则说明你未完成安装CUDA和cuDNN,按照2、4步骤进行下载安装后即可。
若出现“OSError: [WinError 193] %1 不是有效的 Win32 应用程序”错误,则执行脚本:cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET W3SVC/AppPools/Enable32bitAppOnWin64 1 。其中,%SYSTEMDRIVE%表示系统盘(一般为c:)。这个命令的意思是设置在IIS服务器上的32位应用程序可以在Windows64位的机器上运行。
4、安装cuDNN库(与CUDA呼应)
cuDNN库是CUDA针对深度神经网络的更新包,TensorFlow会使用它用于加速NVidia GPU上的深度学习。传送门:https://developer.nvidia.com/cudnn。
但比较麻烦的是这个网站需要登录才能下载,所以你必须首先要注册一个NVidia开发者账号,它是免费的。登录后,你便会看到各种CuDNN的下载。然后就是选择匹配的版本,由于之前使用了CUDA 10.0,所以确定为CUDA 10.0选择了cuDNN v7.6.2。
转:https://blog.csdn.net/lugandong/article/details/72468831
一、
拿512fs说话:
看图知道采样的位深是32bit(位),左右声道各占了8*32BCLK,那一个完整的LRCLK一共8*32*2=512BCLK。
其实xxxfs就是这么算出来的,也是固定的,当你定了几个channel,多少位深,就几乎可以确认是多少fs了。从主观的角度来看,fs的数值越大,那么一个完整的LRCLK越多,那承载的数据量就越大,随之的就是音质就会更加好。
上图是32位的采样,2channel,xxxfs的选择有:
128fs、256fs、512fs
如果是16bit的采样,2channel呢?
16*2(channel)*2(每个LR有几个16BCLK组成) = 64fs
按照倍数的增加,会有如下的选择:
64fs、128fs、256fs、512fs
如果是24bit的采样,2channel呢?
24*2(channel)*2(每个LR有几个16BCLK组成) = 96fs
按照倍数的增加,会有如下的选择:
96fs、192fs、384fs、768fs(这个级别的估计一般的ADC很难)
二、
那BCLK是怎么算的?
例在Android系统中,播放的音频文件格式:
sample_rate=44.1Khz,sample_length=16,channel=2时,
那么BCLK应该为2×44.1Khz×16=32xsample_rate=1.4112Mhz
MCLK存在着关系,这个一般要看芯片。如果存在这4倍的关系,那么:
MCLK = 4*BCLK=5.6448Mhz
至于MCLK的选择还要看外部的晶振。
鉴于如上的,那它是xxxfs?
正常是fs=MCLK/ sample_rate=5.6448*1000/44.1=128fs
fs=16*2*(LRCLK各几个16 BCLK组)=128fs,一共是4个。
如果现在你要对外部晶振进行选型了,现在是sample_rate=48Khz,sample_length=16,channel=2,我们选择512fs,那外部晶振MCLK要选择多大? MCLK=fs*sample_rate=512*48=24.576Mhz--------------------- 作者:慢几步-深几度-前行 来源:CSDN 原文:https://blog.csdn.net/lugandong/article/details/72468831 版权声明:本文为博主原创文章,转载请附上博文链接!
Java-ThreadLocal ThreadLocal是JDK包提供的,它提供了线程本地变量,也就是如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题。
每一个线程都有自己的ThreadLocal变量副本 创建如下的测试类,其中有两个静态内部类,Account用于展示ThreadLocal和普通属性在多线程下的值的区别;MyThread用来验证ThreadLocal是线程独享的,普通变量非线程独有。
测试类 public class ThreadLocalTest { public static void main(String[] args) { // Account类中有ThreadLocal类型的属性 Account account = new Account("初始名", "123456"); // 启动两个共享同一个account对象的线程 new MyThread(account, "甲").start(); new MyThread(account, "乙").start(); } static class Account { /** * 定义一个ThreadLocal类型的变量,每一个线程都会保留该变量的一个副本 */ private ThreadLocal<String> threadLocalField = new ThreadLocal<>(); private String num; /** * 将str字符串更新为属性ThreadLocal的值 * * @param str 用于替换ThreadLocal属性 * @param num 用于替换普通属性 */ public Account(String str, String num) { //对ThreadLocal的静态内部类进行设置 this.
1.基本用法 arr.forEach(value, index, array)
2.forEach()中的continue 借用return 或者 some+return实现
3.forEach()中的break 借用try+catch 或者 some 或者every实现
ps1: forEach()与map()的区别: 前者常用来改变原数组内容,后者原数组内容不改变。
ps2:类数组不可以使用forEach(), splice(), push() 等原型链上的方法,需要添加到类数组对象的属性上面才可以
如果一个手机彻底坏了,开不了机,比如摔坏的,完全无法正常维修了,那么如果手机里有重要的数据要怎么恢复呢?下面就给大家一个思路,但需要有专业的焊接的设备才可以,但一般是可以恢复完整的数据的。
首先手机可以变成碎片,但主板上的内存必须是完好的,注意不是运行内存,是机身内存完好即可,因为数据都存放在机身内存里。
恢复数据思路是:先查看内存芯片上的字母,然后查询芯片型号,比如下面这个例子是海力士eMCP(如下图),FBGA221封装。找到支持脚位的U盘主控板及免驱主控型号(已知安国AU6438支持),如找不到主控板也可以找个读卡器然后查询对应硬盘型号的官方datasheet数据点位,飞线连接。
硬件连接好后打开Diskgenius分析硬盘分区结构,可见有非常多的逻辑分区。确定用户数据所在逻辑分区后打开R-Studio扫描分析数据目录结构,即可完整恢复出所有数据。
照片可直接恢复出来。联系人、短信…等是以SQlite数据库格式存储,恢复解密需安装linux系统转换出来。
本方法适用于所有安卓手机 eMMC、eMCP,FBGA153、FBGA162等主流手机内存硬盘。
具体步骤是:
1、先把手机内存芯片拆出来
2、然后准备好焊接风枪,温度适中,把内存芯片从手机主板上拆下来。
3、准备好焊接eMCP芯片到U盘主控板上的工具如下图。
4、准备好免驱的安国主控的主控板,不含内存,但包含其他主控部分,焊接上闪存就是一个完整的U盘了,主控板可以网上买到。
5、用热风枪和锡焊工具把之前取下的内存芯片焊接到U盘主控板上。
6、焊接emmc或者amcp都可以,这两种手机内存的区别如下。
7、下图是海力士内存各种芯片的引脚功能示意图
8、然后把焊接好内存的U盘插到电脑上,用diskgenius分析硬盘分区结构可以看到下图内存里之前在手机里的所有分区,找到你存放照片等重要数据的分区,然后用diskgenius专业版的数据恢复功能,导出数据即可。
总结:这是恢复损坏手机数据的一个比较靠谱的方法了,当然你得根据你的手机内存型号找对主控板,否则无法识别也没用。
Remix OS for PC安装教程
先到官方网站上下载安装包:http://www.jide.com/en/remixos-for-pc
官方提供了直接下载和BT种子下载两种方式,Legacy、EFI两种版本,分别适合传统BIOS、新的UEFI。这里下的是Legacy。
下载来的是个大约700MB的压缩包,解压。
预备一个容量不低于8GB的USB 3.0 U盘。
格式化为FAT32。
刚才解压的文件夹内有启动盘制作工具Remix OS USB Tool,启动后载入同样在文件夹内的ISO镜像。
完成后重启,此时不要拔掉U盘。
开机进入BIOS环境,一般是按Del。
在启动顺序中选择刚才的U盘。
两种安装方式:Resident Mode会保留所安装Remix OS系统的各种资料,适合家用电脑;Guest Mode则是重启就会丢失,适合在公共电脑上体验。
然后就是各种载入,第一次大约3分钟,之后每次约1分钟。
这就安装得差不多了。选择语言。
用户协议必须同意啦。
登陆Wi-Fi网络。
安装完成。