Quantcast
Channel: CSDN博客推荐文章
Viewing all 35570 articles
Browse latest View live

566. Reshape the Matrix。

$
0
0

In MATLAB, there is a very useful function called ‘reshape’, which can reshape a matrix into a new one with different size but keep its original data.

You’re given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number and column number of the wanted reshaped matrix, respectively.

The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were.

If the ‘reshape’ operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

Example 1:

Input:
nums =
[[1,2],
[3,4]]
r = 1, c = 4
Output:
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.

Example 2:

Input:
nums =
[[1,2],
[3,4]]
r = 2, c = 4
Output:
[[1,2],
[3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.

Note:
1.The height and width of the given matrix is in range [1, 100].
2.The given r and c are all positive.


题中的意思就是将一个二维数组重新改变形状,也就是说为的reshape函数(在Python中的pandas也存在,MATLAB也存在),可以对一个二维数组重新指定形状。题中的第一个例子就是将一个2*2的数组转换为1*4的形状,其中的元素就是按照原来的顺序依次排放。第二个例子说明了如果原先的数组不能转变成指定的形状,就返回原来的数组。

刚开始想的就是,将原来的二维数组中的内容全部取出来存放在队列中,然后创建一个指定形状(行数为r,列数为c)的二维数组,依次将队列中的内容取出来进行赋值即可。

class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
        if(nums.size() == 0 || nums.size() * nums[0].size() != r*c) {//如果等于0或者不能转换为指定的要求则返回原数组
            return nums;
        }

        queue<int> all_nums;
        vector<vector<int>> new_nums;
        int i,j;
        new_nums.resize(r);//设定为r行
        for(i=0;i<r;i++) {
            new_nums[i].resize(c);//设定每列多少个元素
        }
        for(i=0;i<nums.size();i++) {//将所有的数字放到一个队列中
            for(j=0;j<nums[i].size();j++) {
                //cout << nums[i][j] << endl;
                all_nums.push(nums[i][j]);
            }
        }

        for(i=0;i<r;i++) {//新的行数
            for(j=0;j<c;j++) {//新的列数
                new_nums[i][j] = all_nums.front();
                all_nums.pop();
            }
        }

        return new_nums;
    }
};

上面的方法需要使用额外的空间来存储原来的内容,其实在我们创建完制定的二维数组之后就可以进行存放了,我们可以使用两个变量:row和col,分别用来标记需要将元素存放在二维数组中的什么位置,row和col是从0开始的,然后col进行加一并且判断此时的col和要求的c是不是一样,如果一样的话说明这一行已经存满了,将row进行加一代表着开始存放第二行数据,并且col需要置0.

例如,将1*4(1,2,3,4)的转变为2*2的:

创建一个2*2的数组,然后row和col都为0,

所以第一次赋值:new_nums[0][0] = 1,然后col加一并且判断此刻col是不是等于2(也就是题中的2),此刻不等于。

第二次赋值:new_nums[0][1] = 2,col加一发现此刻col等于2,所以说明这一行存满了,需要下一行了。所以row加一,col置0.

第三次赋值:new_nums[1][0] = 3,col加一,此刻不等于2。

第四次赋值:new_nums[1][1] = 4,col加一,row加一,但是原数组中已经没有内容了,就结束了。产生的new_nums就是我们需要的形状。

class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {

        if(nums.size() == 0 || nums.size() * nums[0].size() != r*c) {//如果等于0或者不能转换为指定的要求则返回原数组
            return nums;
        }

        vector<vector<int>> new_nums(r,vector<int>(c));
        int i,j;
        int row=0,col=0;

        for(i=0;i<nums.size();i++) {//处理行
            for(j=0;j<nums[0].size();j++) {//处理列
                new_nums[row][col] = nums[i][j];//取出一个元素赋值给新的数组
                col++;//列加一,向后移动一个
                if(col == c) {//如果此刻的列数已经增加到了规定的列数,就让行数加一,列数清零
                    col = 0;
                    row++;
                }
            }
        }

        return new_nums;
    }
};
作者:Leafage_M 发表于2017/11/25 19:56:29 原文链接
阅读:42 评论:0 查看评论

十.ARM裸机学习之中断系统1(S5PV210的中断系统详解)

$
0
0
一.轮询方式处理按键
参考 E:\Linux\8.key_open
//按键的初始化
void key_init(void)
{
	// GPH0CON的bit8~15全部设置为0,即为输入模式
	rGPH0CON &=~(0xff<<8);
	// GPH2CON的bit0~15全部设置为0,即为输入模式
	rGPH2CON &= ~(0xFFFF<<0);
	
}
void key_polling(void)//轮询方式
{
	
	// 依次,挨个去读出每个GPIO的值,判断其值为1还是0.如果为1则按键按下,为0则弹起
	
	// 轮询的意思就是反复循环判断有无按键,隔很短时间
	// 对应开发板上标着LEFT的那个按键
	while(1)
	{
		if (rGPH0DAT & (1<<2))
		{
			// 为1,说明没有按键
			led_off();
			printf("key left.\n");
		}
		else
		{
			// 添加消抖
			// 第一步,延时
			delay20ms();
			// 第二步,再次检验按键状态
			if (!(rGPH0DAT & (1<<2)))
		{
			// 为0,说明有按键
			led1();
			printf("key down.\n");
		}
			
		}
	
	// 对应开发板上标着DOWN的那个按键
	if(rGPH0DAT &(1<<3)) // 为1,说明没有按键
	{
		led_off();
		printf("key down.\n");
	}
	else // 为0,说明有按键
	{
		// 添加消抖
			// 第一步,延时
			delay20ms();
			// 第二步,再次检验按键状态
			if (!(rGPH0DAT & (1<<3)))
		{
			// 为0,说明有按键
			led1();
			printf("key down.\n");
		}
	}
	
	// 对应开发板上标着UP的那个按键
	if (rGPH2DAT & (1<<0))
	{
			// 为1,说明没有按键
		led_off();
		printf("key down.\n");
	}
	else
	{
			// 添加消抖
			// 第一步,延时
			delay20ms();
			// 第二步,再次检验按键状态
			if (!(rGPH2DAT & (1<<0)))
		{
			// 为0,说明有按键
			led3();
			printf("key down.\n");
		}
	}
		
	}
    
	
}
二.中断系统 2017/11/21 23:30
1.异常向量表分析:

(1)、复位(RESET)
    a、当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,包括系统加电和系统复位。
    b、通过设置PC跳转到复位中断向量处执行称为软复位。
    (2)、未定义的指令
    当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断,可以通过改异常中断机制仿真浮点向量运算。
    (3)、软件中断
    这是一个由用户定义的中断指令(SWI)。该异常由执行SWI指令产生,可用于用户模式下的程序调用特权操作指令。在实时操作系统中可以通过该机制实现系统功能调用。
    (4)、指令与取终止(Prefech Abort)
    如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,当被预取的指令执行时,处理器产生指令预取终止异常中断。
    (5)、数据访问终止(DATAABORT)
    如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问终止异常中断。
    (6)、外部中断请求(IRQ)
    当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。系统中个外设通过该异常中断请求处理服务。
    (7)、快速中断请求(FIQ)
    当处理器的外部快速中断请求引脚有效,而且CPSR的F控制位被清除时,处理器产生外部中断请求异常中断。
一.CPU自动处理的过程包括如下:
1、  拷贝CPSRSPSR_
2、  设置适当的CPSR位: 改变处理器状态进入ARM状态;改变处理器模式进入相应的异常模式;设置中断禁止位禁止相应中断。
3、  更新LR_,这个寄存器中保存的是异常返回时的链接地址
4、  设置PC到相应的异常向量
异常中断处理返回
 二. 异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回:
    (1)、将所有修改过的用户寄存器从处理程序的保护栈中恢复。 
    (2)、将SPSR复制回CPSR中,将连接寄存器LR的值减去相应的偏移量后送到PC中。 
    (3)、若在进入异常处理时设置了中断禁止位,要在此清除。
    复位异常处理程序不需要返回。

当异常发生时,内核会跳转到向量表的相应位置,并执行当中的指令。对于每一种异常,保存的返回地址都是不一样的,一般都需要我们手动的跳转,当然调整的时机也需要我们选择,是在进入处理前跳转还是返回时调整都是需要我们程序员控制的。

三.中断处理的第一阶段(异常向量表阶段)处理。 2017/11/23 22:35
第一个阶段的主要任务是从异常发生到响应异常并且保存/恢复现场、跳转到真正的异常处理程序处
1.查210的iROM application ,iRAM中的异常向量表起始地址为0xD0037400

各个异常对应的入口就等于异常向量表的起始地址+上图中入口的偏移地址:如下图

2.中断处理保存现场,包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12,


1)中断处理要注意保护现场(中断从SVC模式来,则保存SVC模式下的必要寄存器的值)和恢复现场(中断处理完成后,准备返回SVC模式前,要将保存的SVC模式下的必要寄存器的值恢复回去,不然到了SVC模式后寄存器的值乱了,SVC模式下原来正在进行的常规任务就被你搞坏了)
(2)保存现场包括:第一:设置IRQ栈;第二,保存LR;第三,保存R0~R12
(3)为什么要保存LR寄存器?要考虑中断返回的问题。中断ISR执行完后如何返回SVC模式下去接着执行原来的代码。中断返回其实取决于我们进入中断时如何保存现场。中断返回时关键的2个寄存器就是PC和CPSR。所以我们在进入IRQ模式时,应该将SVC模式下的下一句指令的地址(中断返回地址)和CPSR保存起来,将来恢复时才可以将中断返回地址给PC,将保存的CPSR给CPSR。
(4)中断返回地址就保存在LR中,而CPSR(自动)保存在(IRQ模式下的)SPSR中

四、中断处理的第二阶段处理过程
第二个阶段就是进入了真正的异常处理程序irq_handler之后,目的是识别多个中断源中究竟哪一个发生了中断,然后调用相应的中断处理程序来处理这个中断。

1.第一阶段:找到具体是哪个中断:S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多支持128个中断,实际支持不足128个,有些位是空的);210没有子中断寄存器,每个中断源都是并列的。当中断发生时,在irq_handler中依次去查询4个中断源寄存器,看哪一个的哪一位被置1,则这个位对应的寄存器就发生了中断,即找到了中断编号
2.第二阶段找到对应的中断服务处理isr:2210开拓了一种全新的寻找isr的机制。210提供了很多寄存器来解决每个中断源对应isr的寻找问题,实现的效果是当发生相应中断时,硬件会自动的将相应isr推入一定的寄存器中,程序员在设置中断的时候,把这个中断的isr地址直接放入这个中断对应的VECTADDR寄存器即可。

S5PV210中断处理的主要寄存器:
VIC0INTENABLE:中断使能
VIC0INTENCLEAR:中断禁止
VIC0INTSELECT:中断选择,IRQ/FIQ
VIC0IRQSTATUS:IRQ中断状态寄存器,软件在处理中断第二阶段的第一阶段,就是靠查询这个寄存器来得到中断编号
VIC0FIQSTATUS:FIQ中断状态寄存器
VIC0VECTADDR:中断源对应的ISR地址,中断发生第二阶段如何获取isr地址由这个寄存器自动完成,只需要拿出ISR地址,调用即可
VICnVECTPRIORITY31:中断优先级设置寄存器
VIC0ADDRESS:向量地址寄存器,当有中断发生时,硬件上会将当前中断的中断服务例程ISR地址从寄存器VICVECTADDR自动拷贝到寄存器VICDDR中
总结S5PV210的中断体系采用如下的ISR确定策略
(1)、将128个中断源分为4组,每组的ISR组成一个数组,以中断号为数组索引。
(2)、4组ISR数组的首地址分别存放在VICVECTADDR0~VICVECTADDR3中。
绑定ISR时,只需将用户自己编写的ISR地址放入ISR数组中以中断号为索引的位置即可

五、中断处理流程(参考:http://blog.51cto.com/9291927/1787523) 2017/11/24 22:51
S5PV210中断处理流程:
1、中断处理前的准备工作
A、初始化中断控制器。
外部中断的中断控制器的初始化包括:绑定第一阶段异常向量表;外设相应GPIO引脚设置为外部中断模式、外部中断控制寄存器的初始化、中断向量控制寄存器的初始化。
内部中断的中断控制器的初始化包括:中断向量控制寄存器的初始化,
B、绑定中断源的ISR到向量中断控制器的VICnVECTADDR。
C、使能中断源中断。
问题1:如何绑定自己实现的isr到VICnVECTADDR
(1)搞清楚2个寄存器的区别:VICnVECTADDR和VICnADDR(寄存器在上面已经解释
(1)VICVECTADDR寄存器一共有4×32个,每个中断源都有一个VECTADDR寄存器,我们应该将自己为这个中断源写的isr地址丢到这个中断源对应的VECTADDR寄存器中即可。

问题二:真正的中断处理程序如何获取isr?
(1)当发生中断时,硬件会自动把相应中断源的isr地址从VICnVECTADDR寄存器中推入VICnADDR寄存器中,所以我们第二阶段的第二阶段isr_handler中,只需要到相应的VICnADDR中去拿出isr地址,调用执行即可。

思考问题:中断处理程序与中断服务ISR的区别:?(截取的网上的资料)
中断处理程序和中断服务例程ISR是两个非常容易混淆的概念,但两者是两个不同的概念。内核中的中断处理程序与中断服务例程的关系如下图:

    每一个触发中断的中断源对应一个中断处理程序,每一个中断处理程序对应多个中断服务例程。对中断服务例程进行注册后中断服务例程就会挂在中断请求队列中。中断处理程序是中断向量的处理程序,如果多个设备共享一个中断源,中断处理程序必须要调用每个设备的中断服务例程ISR。
    在裸机中,由于每个中断源(终端编号)只有一个对应的中断向量地址寄存器VICVECTADDR,所以每一个中断处理程序只有一个中断服务例程。
2、中断处理流程
A、异常向量表跳转到IRQ入口
CPU处理常规任务时收到中断的通知,于是S5PV210根据iROM固化代码跳转到iRAM的异常向量表的IRQ异常向量地址。一般将负责保护现场、处理中断、恢复现场的汇编代码段的起始地址赋值给IRQ异常向量地址,作为处理中断的入口。
B、保护中断现场(在start.S中),然后跳入isr_handler
处理中断之前先要保护总线 现场,主要工作是:设置IRQ模式下的栈,将R0-R12,LR压栈保存(由于流水线的原因,LR一般为当前执行的指令地址加8,LR减去4就是下一条要运行指令的地址)。
C、执行中断处理程序
在isr_handler中先去搞清楚是哪个VIC中断了。查看VICnADDR寄存器是否有ISR函数地址,如果有,执行ISR。一般在中断发生之前已经绑定好ISR到VICnVECTADDR。
D、恢复现场
执行ISR后,将栈中的R0-R12,LR分别出栈R0-R12,PC,程序将根据PC的值自动跳转会到常规任务执行。
// 在这个汇编函数中,用来做中断模式下的现场保护和恢复,并且调用真正的中断处理程序

IRQ_handle:
	// 设置IRQ模式下的栈
	ldr sp, =IRQ_STACK
	// 保存LR
	// 因为ARM有流水线,所以PC的值会比真正执行的代码+8,
	sub lr, lr, #4
	// 保存r0-r12和lr到irq模式下的栈上面
	stmfd sp!, {r0-r12, lr}
	// 在此调用真正的isr来处理中断
	bl irq_handler
	// 处理完成开始恢复现场,其实就是做中断返回,关键是将r0-r12,pc,cpsr一起回复
	ldmfd sp!, {r0-r12, pc}^




作者:wangweijundeqq 发表于2017/11/25 20:58:55 原文链接
阅读:49 评论:0 查看评论

Android关于活动Activity的教程

$
0
0

相关引用:

《第一行代码 第2版》

https://developer.android.com/guide/topics/ui/notifiers/toasts.html

从上节我们可以知道,Android包含四大组件:

  • Activity
  • BroadCastReceiver
  • Service
  • ContentProvider

作为一个嵌入式设备的程序,对于用户来说,最直观的就是界面显示了,所以本篇课程学学Activity的知识

什么是活动(Activity)

JavaSE中,程序的入口是main()函数;而在Android中,若这个程序是被用户可见的,则需用用到Android的组件————Activity,它是一个可以包含用户界面的组件,被用户交互操作。

一个Android程序包含零到多个Activity。

基本用法

怎么创建

若你创建一个Android项目的时候,不更改默认配置,IDE会自动帮你生成带Activity组件的项目(至于如何创建,可自行google)。下面我们准备手动创建一个Activity,选择Add No Activity:
手动创建一个Activity
我学Android的时候,流行的IDE还是Eclipse,所以我习惯了它的窗口界面,在开发中,我一般都是将Android Studio改成Project模式:
Project模式
鼠标右击包名 → New → Activity → Empty Activity,会弹出下图的对话框,不要勾选Generate Layout File和Launcher Activity:
创建一个Activity
打开FirstActivity.java,由于继承了Actvity(AppCompatActivity是Activity的子类),所以Android Studio自动帮我们重写了onCreate()方法:

    public class FirstActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    }

在Android中,只要看到onXxx()的方法,其实就是理解为 在xxx时候执行,例如onCreate()几时在创建的时候执行,onClick()在组件被点击的时候执行,onDestory()在销毁的时候执行……

加载内容布局

前面说到,创建Activity时不够选Generate Layout File是为了我们自己手动创建布局文件,那什么是布局文件呢???其实布局文件就是用来显示界面内容的

如何创建

从上节我们知道,Android的布局文件是放在layout目录的,创建目录:
创建layout目录

接下来就可以在这个目录下创建我们的布局文件了,并命名为firstactivity_layout:
创建布局文件1

创建布局文件2

创建完成后,Android Studio会自动显示可视化布局编辑器窗口:
可视化编辑器窗口

图片左下角有两个切换卡,左边是Design,右边是Text。前者是可视化布局编辑器,在这里你不仅可以预览当前的布局,还可以通过拖放的方式编辑布局;而Text则是通过XML文件的方式来编辑布局的,一般情况下是用XML方式编辑布局,所以我们切换到Text:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

</LinearLayout>

在这里我们可以添加一个最简单的组件:Button(按钮):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮"/>

</LinearLayout>

xml中各元素属性的含义

这里对Button的几个属性进行讲解:

  1. android:id是Button这个组件的唯一标识,类似于现实生活中人们的身份证,如果要在java代码中操作某个组件,则组件需要设置id,这样才能在代码中通过id拿到这个组件。注意:定义一个id格式是@+id/xxxxx,不能写成@id/xxxxxx,后者表示引用一个资源
  2. android:layout_width和android:layout_height,顾名思义,表示组件的宽度和高度,match_parent表示和父元素一样宽,而Button的父元素是LinearLayout,LinearLayout的宽度也为match_parent,那是多少呢??这里你可以简单先理解成和屏幕一样宽,本系列只讲基础知识;wrap_content则表示高度刚好包含Button里面的内容
  3. android:text指定了Button显示的内容。

我们可以点击右侧工具栏的Preview预览一下效果:
Preview预览视图

显示布局

布局文件的创建工作已经完成了,现在让我们在Activity中加载它,显示出来吧:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);
    }
}

上述代码中,是使用setContentView()给当前Activity加载布局的,使用方法是往这个方法传入一个int型的布局文件id。上节中提过,项目中的资源文件都会在R文件中生成一个唯一标识的资源id。因此我们把创建的布局文件id传入即可。

在清单文件中注册(AS自动完成)

上一章说过,Android的四大组件必须在清单文件中注册才能生效,activity自然不例外,只是Android Studio贴心的帮我们完成了这个动作:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.snaptech.activitytest">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".FirstActivity"></activity>
</application>

</manifest>

清单文件元素属性的含义

  1. 标签中android:name是来指定具体注册哪个活动的,这里填入的.FirstAcitivity是什么意思呢?其实这不过就是com.snaptech.activitytest.FirstActivity的缩写而已。由于在最外层的标签中已经通过package属性指定了程序的包名是com.snaptech.activitytest,因此在注册活动时这一部分就可以省略了,直接使用.FirstActivity就足够了。

设置活动为主入口

上一章中说过,Activity要想作为主入口,只需要如下声明即可:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.snaptech.activitytest">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".FirstActivity"
    android:label="This is FirstActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

</manifest>

android:label是用来指定活动中标题栏内容的,标题栏是显示在活动最顶部的。label不仅会成为标题栏中的内容,还会成为Launcher中应用程序显示的名称。运行本程序,结果如下:
运行效果图

使用onClick()+Toast打印

对于什么是Toast,Android官网的定义是:

A toast provides simple feedback about an operation in a small popup. It only fills the amount of space required for the message and the current activity remains visible and interactive. Toasts automatically disappear after a timeout.

简单翻译就是,Toast框是一个小的弹出窗口,用于提供有关操作的简单反馈。它只填充消息所需的空间大小,并且当前的Activity仍然是保持可见并且可以和用户交互的(此处涉及到Activity的生命周期,下文会讲解)。Toast框会在设定的时间超时后,自动消失。

另外我们要知道,按钮是可点击的,我们可以通过给按钮Button设置点击监听事件来实现:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        //findViewById()通过在R文件的唯一标识id获取组件,返回的是View对象,而View对象是所有组件的父类,所以要向下转型为Button对象。
        Button button = (Button) findViewById(R.id.btn_button);
        //通过该方法为Button注册一个点击的监听器
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {//还记得上文所说的诀窍吗??onXxx()就是在Xxx的时候调用,此处Button为点击的时候调用
                //通过Toast的静态方法makeText()创建Toast对象,传入三个参数,第一个是上下文对象Context,直接传入Activity本身,第二个是要现实的内容,第三个是显示的时长,有两个常量选择Toast.LENGTH_SHORT和Toast.LENGTH_LONG。记得最后调用.show()方法,不然不会显示!!!
                Toast.makeText(FirstActivity.this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

点击Button,结果:

onClick()+Toast

点击事件的四种写法

下面介绍组件点击事件的四种方法:

第一种

自定义一个类,并实现onClickListener接口:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
        button.setOnClickListener(new ClickListener());
    }

    class ClickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            Toast.makeText(FirstActivity.this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
        }
    }
}

第二种

定义一个匿名内部类实现onClickListener接口

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(FirstActivity.this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
            }
        });
    }
}

第三种

让当前activity实现onClickListener接口

public class FirstActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(FirstActivity.this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
    }
}

第四种

在xml文件中给Button节点设置onClick属性,然后在activity中定义跟该属性值同名的方法:

public class FirstActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
    }

    public void onButtonClick(View v){
        Toast.makeText(this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
    }
}

在Android官网中,对于此种方法是这样介绍的:

For instance, if you specify android:onClick=”sayHello”, you must declare a public void sayHello(View v) method of your context (typically, your Activity).

如果你在xml中设置了这个属性,那么你必须在你的上下文中声明一个public类型的方法,并且形参类型为View。

销毁一个活动

上面学习了如何创建一个活动,那么如果想要销毁一个活动呢?其实只要按一下Back键就可以了。如果你想在代码中实现,可以调用Activity类的finish()方法:

public class FirstActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Toast.makeText(FirstActivity.this,"button is clicked !!! ",Toast.LENGTH_SHORT).show();
                FirstActivity.this.finish();
            }
        });
    }
}

运行效果和按下Back键是一样的

Intent

如果想要在两个Activity之间跳转的话,就要用到Intent,通过设置Intent对象的参数指定要跳转的Activity。

概念

Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。Intent一般可被用于启动活动、启动服务以及发送广播等场景。

显式Intent

通过设置Acitivity的包名和类名实现的跳转,称为显示意图

隐式Intent

通过指定一系列的action和category,交由系统去分析这个Intent然后做出响应,称为隐式意图

实践

我们可以利用Intent从FirstActivity跳转到SecondActivity。

创建第二个Activity

利用前面介绍的创建Activity的方法创建SecondActivity:

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.secondactivity_layout);
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/btn_button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button2"/>

</LinearLayout>

还是在SecondActivity的界面上简单的定义了一个Button,内容为Button2。
别忘了在清单文件中检查是否注册了这个Activity:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".FirstActivity"
        android:label="This is FirstActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".SecondActivity"></activity>
</application>

由于不是入口Activity,所以不需要配置FirstActivity里的内容。

显式意图跳转

要从FirstActivity显示跳转到SecondActivity:

public class FirstActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
    }

    public void onButtonClick(View view){
        Intent intent = new Intent(this,SecondActivity.class);
        startActivity(intent);
    }
}

点击FirstActivity中的“按钮”,程序会经过动画跳转到SecondActvity,并显示后者的布局内容:
显示Intent跳转

隐式意图跳转

还记得我们在清单文件中注册FirstActivity时候,所设置的属性吗?其实这些属性就是被用于其他Activity隐式启动的。

打开清单文件,为SecondActivity设置action和category:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

action的android:name其实可以随便写,但是最好写规范。要想让一个Activity被隐式启动,必须设置action与category!
隐式意图启动Activity成功的条件:Intent参数的值必须与该Activity在清单文件中属性的定义的值同时匹配

public class FirstActivity extends AppCompatActivity{
    private final String INTENT_ACTION = "com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
    }

    public void onButtonClick(View view){
        Intent intent = new Intent(INTENT_ACTION);
        //实际上有调用以下代码,只不过是自动帮你添加了
        //intent.addCategory(Intent.CATEGORY_DEFAULT);
        startActivity(intent);
    }
}

等等,前面不是说必须要和同时匹配才能响应吗?怎么没看到指定category?其实这是因为android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法时,会自动将这个category添加到Intent中。运行程序,效果和显示意图启动一致。

我们再修改清单文件中SecondActivity的属性:

<activity android:name=".SecondActivity">
    <intent-filter>
        <action android:name="com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY"/>
        <action android:name="com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY_TEMP"/>
        <category android:name="com.snaptech.activitytest.CATEGORY_SECOND_ACTIVITY"/>
    </intent-filter>
</activity>

这里设置了两个,在FirstActivity中将Intent的action指定为其中任何一个:

public class FirstActivity extends AppCompatActivity{
    private final String INTENT_ACTION = "com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY";
    private final String INTENT_ACTION_TEMP = "com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY_TEMP";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
    }

    public void onButtonClick(View view){
        Intent intent = new Intent(INTENT_ACTION_TEMP);
        startActivity(intent);
    }
}

重新运行程序,报错:

Tips:程序出现错误,将Tag过滤器切换到Error,出现错误的地方源头一般在log信息最下面

报错信息

错误提示没有一个Intent可以响应我们的操作,这是因为在Android中,每个Intent只能指定一个action,可以指定多个category

隐式意图的使用场景

一般用于启动不同应用中的Activity,常用的,我们可以启动系统自带的应用。比如你的程序中需要展示一个网页,这时候你不必自己实现这个功能,可以调用系统自带的浏览器来实现:

public class FirstActivity extends AppCompatActivity{
    private final String INTENT_ACTION = "com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY";
    private final String INTENT_ACTION_TEMP = "com.snaptech.activitytest.START_ACTION_SECOND_ACTIVITY_TEMP";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.firstactivity_layout);

        Button button = (Button) findViewById(R.id.btn_button);
    }

    public void onButtonClick(View view){
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://blog.csdn.net/wudongjiang333"));
        startActivity(intent);
    }
}

结果:
隐式意图

上述代码中,可能你会对setData()陌生,它接收一个Uri对象,主要用于指定当前Intetn正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。与此对应,我们可以在中在配置一个标签,用于更精确地指定当前活动能够响应什么类型的数据。可以配置一下内容:

  • android:scheme:用于指定数据的协议部分,如上例中的http部分。
  • android:hose:用于指定数据的主机名部分,如上例中的blog.csdn.net
  • android:port:用于指定数据的端口部分,一般紧随在主机名之后。
  • android:path:用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容
  • android:mimeType:用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

如果系统中存在多个Activity的intent-filter同时与你的intent匹配,那么系统会显示一个对话框,列出所有匹配的Activity,由用户选择启动哪一个

匹配的所有Activity列表

本节暂时介绍到这里,下一节主要介绍Activity之间的通信、Activity的生命周期、Activity的启动模式等内容

作者:wudongjiang333 发表于2017/11/25 21:03:39 原文链接
阅读:48 评论:0 查看评论

NOIP2017图书管理员(普及T2)

$
0
0

T2

题面传送门

模拟水题,按图书编号从小到大排序,然后直接查询判断,不会TLE的

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
using namespace std;
int n,q,len,ans,a[1000006],s;
int main()
{
    cin>>n>>q;
    rep(i,1,n)cin>>a[i];
    sort(a+1,a+1+n);
    while(q--){
        ans=-1;
        cin>>len>>s;
        int t=1;
        while(len--)t*=10;
        rep(i,1,n)
            if(a[i]%t==s){
                ans=a[i];
                break;
            }
        printf("%d\n",ans);
    }
    return 0;
}
作者:qwerty1125 发表于2017/11/25 22:17:12 原文链接
阅读:0 评论:0 查看评论

NOIP2017棋盘(普及T3)

$
0
0

T3

题面传送门

开始想去DP,但是写完之后发现不满足DP的无后效性,真是gg

然后开始着手dfs+记忆化。貌似bfs也能跑?(话说我是不是押到题了,之前给四十五中出过一道类似于bfs的题)但感觉复杂度太大,会TLE

正解是将已经有色的格子向四个不同的方向搜索,未染色的就进行染色,之后再搜索

一定要注意边界的判断啊!

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define inf 0x3f3f3f
using namespace std;
const int maxn=1006,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
int n,m,x,y,opt,Map[maxn][maxn],f[maxn][maxn];
void dfs(int x,int y,int p){
    rep(i,0,3){
        int nowx=x+dx[i],nowy=y+dy[i];
        if(nowx>n||nowx<1||nowy>n||nowy<1)continue;
        if(~Map[nowx][nowy]){
            if((~Map[x][y]?Map[x][y]:p)==Map[nowx][nowy])
            {
                if(f[nowx][nowy]>f[x][y])f[nowx][nowy]=f[x][y],dfs(nowx,nowy,Map[nowx][nowy]);
            }
            else{
                if(f[nowx][nowy]>f[x][y]+1)f[nowx][nowy]=f[x][y]+1,dfs(nowx,nowy,Map[nowx][nowy]);
            }
        }
        else{
            if(Map[x][y]==-1)continue;
            else if(f[nowx][nowy]>=f[x][y]+2)f[nowx][nowy]=f[x][y]+2,dfs(nowx,nowy,Map[x][y]);
        }
    }
}
int main()
{
    mem(Map,-1);
    mem(f,inf);
    cin>>n>>m;
    rep(i,1,m){
        cin>>x>>y>>opt;
        Map[x][y]=opt;
    }
    f[1][1]=0;
    dfs(1,1,0);
    if(f[n][n]==1061109567)cout<<"-1\n";
    else cout<<f[n][n]<<endl;
    return 0;
}
作者:qwerty1125 发表于2017/11/25 22:18:23 原文链接
阅读:0 评论:0 查看评论

NOIP2017跳房子(普及T4)

$
0
0

T4

题面传送门

感觉在pj组放这道题是不是有些难了,难度大于NOIP2015D2T1那道跳石子

老套路先二分答案+DP

f[i]表示跳前i个格子,且停在第i个格子最大分数;

sc[i]表示第i个格子的分数。

转移:f[i]=max(f[j])+sc[i] 前提是从j可以跳到i

显然,这种时间复杂度太大

需要再次使用单调队列优化

发现转移中j的位置是随着i的右移而右移的

对于格子j,如果dis[i]-dis[j]>=机器人能跳的最小距离,显然f[j]是可以进队的

但是要维护整个队列单调递减,每次直接去队头就好了

注意要把最小值置极小,否则会WA

#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define dep(i,a,b) for(register int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
using namespace std;
const ll maxn=5e5+6,inf=1844387848000;
ll dis[maxn],sc[maxn],f[maxn],n,d,k,x,y;
bool check(int x)
{
    deque<ll>que;
    ll from=0,stepl=max(d-x,(ll)1),stepr=d+x;
    rep(i,1,n){
        while(dis[from]+stepl<=dis[i]){
            while(!que.empty()&&f[que.back()]<=f[from])que.pop_back();
            que.push_back(from++);
        }
        while(!que.empty()&&dis[que.front()]+stepr<dis[i])que.pop_front();
        if(!que.empty())f[i]=f[que.front()]+sc[i];
        else f[i]=-inf;
        if(f[i]>=k) return 1;
    }
    return 0;
}
int main()
{
    cin>>n>>d>>k;
    ll sum=0;
    rep(i,1,n){
        cin>>x>>y;
        dis[i]=x;sc[i]=y;
        if(y>0)sum+=y;
    }
    if(sum<k){cout<<"-1\n";return 0;}
    int l=1,r=dis[n],mid;
    while(l<r){
        mem(f,0);
        mid=(l+r)/2;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    cout<<r<<endl;
    return 0;
}
作者:qwerty1125 发表于2017/11/25 22:19:25 原文链接
阅读:3 评论:0 查看评论

Redis 快速入门

$
0
0

Redis 快速入门

谈到Redis,大家应该都不陌生。它是用c语言开发的一个高性能键值数据库,主要用于缓存领域。本章通过Redis的安装,Redis的五大数据类型,Redis的Java客户端,Redis与Spring 的整合 。来让读者对它有一个初步的了解。下一章再通过介绍配置文件来搭建Redis的主从模式和集群模式(配置大于编程,先从简单的编程入手)。

效果图
Redis 缓存项目效果图

需求:对商品类目进行Redis缓存处理
技术:Redis,Spring,SpringMVC,Mybatis,EasyUI
说明:EasyUI的树菜单上一章节有介绍,这里是为了方便展示效果。项目结构图中箭头所指的文件是需要重点学习的。若对EasyUI 树菜单感兴趣的可以访问:(该章节源码中提供商品类名的sql文件)
http://blog.csdn.net/qq_19558705/article/details/78583888
源码:见文章底部
项目结构
项目结构图

Redis 安装

安装文档:
https://github.com/ITDragonBlog/daydayup/blob/master/Redis/Redis%E5%AE%89%E8%A3%85.md

Redis 五大数据类型

Redis 五大数据类型有String 类型,Hash 类型,List 类型,Set 类型,Zset(Sortedset)类型。其中常用的是前三个。
官方提供的操作手册:http://redisdoc.com/
在redis 自带的客户端中输入命令时,可以使用tab自动补齐,新手建议不要偷懒。

String 类型

String 是 redis 最基本的类型,一个key对应一个value。
赋值:set key value
取值:get key
批量赋值:mset key value … keyN valueN
批量取值:mget key … keyN
取值并赋值:getset key value
删除key:del key … keyN
数值加一:incr key
数值加N:incrby key n
数值减一:decr key
数值减N:decrby key n
字符串追加:append key value
字符串长度:strlen key
*注 形如”key … keyN” 表示可以批量操作

127.0.0.1:6379> set key value
OK
127.0.0.1:6379> get key
"value"
127.0.0.1:6379> mset key1 1 key2 2 key3 3
OK
127.0.0.1:6379> mget key1 key3
1) "1"
2) "3"
127.0.0.1:6379> del key
(integer) 1
127.0.0.1:6379> incr count
(integer) 1
127.0.0.1:6379> incrby count 10
(integer) 11
127.0.0.1:6379> decr count
(integer) 10
127.0.0.1:6379> decrby count 5
(integer) 5
127.0.0.1:6379> set str itdragon
OK
127.0.0.1:6379> append str " blog!"
(integer) 14
127.0.0.1:6379> get str
"itdragon blog!"
127.0.0.1:6379> strlen str
(integer) 14

Hash 散列类型

Redis hash 是一个键值对集合,和Java 的HashMap 类似。
Redis hash 是一个String 类型的 field 和 value 的映射表,hash特别适合用于存储对象(key 可以是对象+id,field 是对象属性,value则是属性值)。
给一个字段赋值:hset key field value
给多个字段赋值:hmset key field value … fieldN valueN
取一个字段的值:hget key field
取多个字段的值:gmset key field … fieldN
取所有的字段名和值:hgetall key
删除字段名和值:hdel key field … fieldN
判断字段是否存在:hexists key field
获取key的所有field:hkeys key
获取key的所有value:hvals key
获取field个数:hlen key
*注:这里的field 就是 字段名,value 就是字段值

127.0.0.1:6379> hset user name itdragon
(integer) 1
127.0.0.1:6379> hget user name
"itdragon"
127.0.0.1:6379> hmset user position java study redis
OK
127.0.0.1:6379> hmget user position study
1) "java"
2) "redis"
127.0.0.1:6379> hgetall user
1) "name"
2) "itdragon"
3) "position"
4) "java"
5) "study"
6) "redis"
127.0.0.1:6379> hdel user name 
(integer) 1
127.0.0.1:6379> hdel user position study
(integer) 2
127.0.0.1:6379> hexists user name
(integer) 1
127.0.0.1:6379> hexists user age
(integer) 0
127.0.0.1:6379> hkeys user
1) "name"
2) "position"
3) "study"
127.0.0.1:6379> hvals user
1) "itdragon"
2) "java"
3) "redis"
127.0.0.1:6379> hlen user
(integer) 3

List 类型

Redis 列表是采用来链表来存储的简单字符串列表,按照插入顺序排序。添加元素一般从链表两端开始。
向列表左侧加元素:lpush key value … valueN
向列表右侧加元素:rpush key value … valueN
遍历列表:lrange key startIndex endIndex
获取List长度:llen key
通过下标获取值:lindex key index
通过下标设置值:lset key index value
列表左侧移除第一个元素:lpop key
列表右侧移除第一个元素:rpop key
截取保留剩下的列表:ltrim key startIndex endIndex
在制定元素插入值:linsert key after/before index value
把集合第一个元素移到其他集合中:rpoplpush key otherListKey
* 注:若endIndex=-1 表示最后一位;otherListKey 表示其他集合

127.0.0.1:6379> lpush list 1 2
(integer) 2
127.0.0.1:6379> rpush list 3 4 
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "3"
4) "4"
127.0.0.1:6379> lpop list
"2"
127.0.0.1:6379> rpop list
"4"
127.0.0.1:6379> llen list
(integer) 2
127.0.0.1:6379> lindex list 1
"3"
127.0.0.1:6379> linsert list after 1 2
(integer) 3
127.0.0.1:6379> linsert list before 3 4
(integer) 4
127.0.0.1:6379> ltrim list 0 1
OK
127.0.0.1:6379> rpoplpush list newlist
"1"

Set 类型

Redis 的 Set 是String类型的无序集合。它是通过HashTable实现实现的,用法和 List 类型很相似。
新增集合元素:sadd key value … valueN
删除集合元素:srem key value … valueN
获取集合所有元素:smembers key
判断集合元素是否存在:sismember key value
集合差集:sdiff key1 key2
集合交集:sinter key1 key2
集合并集:sunion key1 key2
获取集合长度:scard key1

127.0.0.1:6379> sadd set a b c d
(integer) 4
127.0.0.1:6379> srem set a b c
(integer) 3
127.0.0.1:6379> smembers set
1) "d"
127.0.0.1:6379> sismember set a
(integer) 0
127.0.0.1:6379> sismember set d
(integer) 1
127.0.0.1:6379> sadd setA 1 2 3 
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) "1"
127.0.0.1:6379> sdiff setB setA
1) "4"
127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"
127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> scard setA
(integer) 3

Zset 类型

Redis 的 zset(sorted set)和 set 一样也是string类型元素的集合,且不允许有重复的成员。不同的是 zset 的每个元素都会关联一个double类型的分数。zset正是通过分数来为集合中的成员进行排序。zset的成员是唯一的,但分数(score)却可以重复。
新增集合元素:zadd key score value … scoreN valueN
获取元素分数:zscore key value
按照分数从小到大排序:zrange key startIndex endIndex
按照分数从大到小排序:zrevrange key startIndex endIndex
遍历时显示分数:withscores
统计分数比value少的个数:zrank key value
统计分数比value高的个数:zrevrank key value
输出分数在制定值内的元素:zrangebyscore key score1 score2
给元素加分:zincrby key score value
获取元素个数:zcard()
统计分数内的个数:zcount key score1 score2
删除制定排名内的元素:zremrangebyrank key no1 no2
删除指定分数内的元素:zremrangebyscore key score1 score2
删除指定元素:zrem key value
* 注: zcount 统计分数内的个数,score1 <= keyScore =< score2;zremrangebyrank 的 no1 和 no2 表示排名的第几位。

127.0.0.1:6379> zadd zset 65 A 67 C 66 B
(integer) 3
127.0.0.1:6379> zscore zset C
"67"
127.0.0.1:6379> zrange zset 0 -1
1) "A"
2) "B"
3) "C"
127.0.0.1:6379> zrevrange zset 0 -1
1) "C"
2) "B"
3) "A"
127.0.0.1:6379> zrevrange zset 0 -1 withscores
1) "C"
2) "67"
3) "B"
4) "66"
5) "A"
6) "65"
127.0.0.1:6379> zrank zset C
(integer) 2
127.0.0.1:6379> zrevrank zset C
(integer) 0
127.0.0.1:6379> zrangebyscore zset 65 66
1) "A"
2) "B"
127.0.0.1:6379> zrangebyscore zset 65 66 limit 1 2
1) "B"
127.0.0.1:6379> zincrby zset 10 A
"75"
127.0.0.1:6379> zcard zset
(integer) 3
127.0.0.1:6379> zcount zset 65 66
(integer) 1
127.0.0.1:6379> zremrangebyrank zset 0 1
(integer) 2
127.0.0.1:6379> zremrangebyscore zset 100 200
(integer) 0
127.0.0.1:6379> zrem zset A
(integer) 1

Jedis客户端

Jedis 是比较主流的 Redis Java 客户端。
第一步:导入Jedis需要的jar

<!-- Redis客户端 -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <jedis.version>2.7.2</jedis.version>
</dependency>

第二步:单元测试类
Jedis 的语法和 Redis 几乎一样,如果学好了Redis,Jedis也就没问题了,可谓是买一送一。建议使用连接池的方式。

package com.itdragon.redis;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class TestJedisOperate {

    private final static String HOST = "112.74.83.71";
    private final static int PORT = 6379;

    /**
     * jedis 的语法和 redis 的语法几乎一致,比较常用的有Hash,String,List
     */
    @Test
    public void jedisSignle() {
        Jedis jedis = new Jedis(HOST, PORT);
        jedis.set("account", "itdragon");
        System.out.println("set , get 操作 : " + jedis.get("account"));
        jedis.mset("account:01", "itdragon01", "account:02", "itdragon02");
        System.out.println("mset , mget 操作 : " + jedis.mget("account:01", "account:02"));
        jedis.hset("user", "name", "ITDragon");
        System.out.println("hset , hget 操作 : " + jedis.hget("user", "name"));
        Map<String, String> userMap = new HashMap<>();
        userMap.put("password", "123456");
        userMap.put("position", "Java");
        jedis.hmset("user", userMap);
        System.out.println("hmset , hmget 操作 : " + jedis.hmget("user", "name", "password", "position"));
        if (0 == jedis.llen("userList")) {
            jedis.lpush("userList", "1", "2", "3");
        }
        System.out.println("List 类型 lpush , lrange 操作 : " + jedis.lrange("userList", 0, -1));
        jedis.sadd("userSet", "1", "2", "2");
        System.out.println("Set 类型 sadd , smembers 操作 : " + jedis.smembers("userSet"));
        Map<String, Double> scoreMembers = new HashMap<>();
        scoreMembers.put("A", 65.0);
        scoreMembers.put("C", 67.0);
        scoreMembers.put("B", 66.0);
        jedis.zadd("userScore", scoreMembers);
        System.out.println("Set 类型 zadd , zrange 操作 : " + jedis.zrange("userScore", 0, -1));
        jedis.close();
    }

    @Test
    public void testJedisPool() {
        JedisPool pool = new JedisPool(HOST, PORT);
        Jedis jedis = pool.getResource();
        System.out.println("通过连接池获取 key 为 account 的值 : " + jedis.get("account"));
        jedis.close();
        pool.close();
    }

}

Spring 整合 Redis

创建用于整合redis的文件 applicationContext-jedis.xml
建议使用redis 默认配置(默认,让生活更美好)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
    <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:resource/*.properties" />
    <!-- 连接池配置 (可以用 redis 默认配置,效果可能会更好)-->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="30" />
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="10" />
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="1024" />
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="1800000" />
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="10000" />
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="1500" />
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="true" />
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="true" />
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="false" />
    </bean> 
    <!-- jedis客户端单机版 -->
    <bean id="redisClient" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="host" value="${redis.host}" />
        <constructor-arg name="port" value="${redis.ip}" />
        <!-- <constructor-arg name="poolConfig" ref="jedisPoolConfig" /> -->
    </bean>
    <bean id="jedisClient" class="com.itdragon.common.utils.JedisClientSingle"/>
</beans>

简单封装了Jedis 常用方法 JedisClientSingle.java

package com.itdragon.common.utils;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

// 单例的Redis 工具类
public class JedisClientSingle {

    /**
     * connect timed out 问题: 
     * 1. 检查redis服务是否开启
     * 2. 检查是否是因为防火墙的问题
     * 3. 检查网络问题(如果在同一个局域网内几乎不会出现这个问题)
     * Jedis jedis =new Jedis(HOST,PORT,100000);
     * JedisPool pool = new JedisPool(poolConfig, HOST, PORT, 100000);
     */

    @Autowired
    private JedisPool jedisPool; 

    public String get(String key) {
        Jedis jedis = jedisPool.getResource();
        String string = jedis.get(key);
        jedis.close();
        return string;
    }

    public String set(String key, String value) {
        Jedis jedis = jedisPool.getResource();
        String string = jedis.set(key, value);
        jedis.close();
        return string;
    }

    public String hget(String hkey, String key) {
        Jedis jedis = jedisPool.getResource();
        String string = jedis.hget(hkey, key);
        jedis.close();
        return string;
    }

    public long hset(String hkey, String key, String value) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hset(hkey, key, value);
        jedis.close();
        return result;
    }

    public long del(String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.del(key);
        jedis.close();
        return result;
    }

    public long hdel(String hkey, String key) {
        Jedis jedis = jedisPool.getResource();
        Long result = jedis.hdel(hkey, key);
        jedis.close();
        return result;
    }

}

获取商品类名接口实现类 ProductCategoryServiceImpl.java

package com.itdragon.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itdragon.common.pojo.EUTreeNode;
import com.itdragon.common.pojo.ResponseResult;
import com.itdragon.common.utils.JedisClientSingle;
import com.itdragon.common.utils.JsonUtils;
import com.itdragon.mapper.ProductCategoryMapper;
import com.itdragon.pojo.ProductCategory;
import com.itdragon.pojo.ProductCategoryExample;
import com.itdragon.pojo.ProductCategoryExample.Criteria;
import com.itdragon.service.ProductCategoryService;

@Service
public class ProductCategoryServiceImpl implements ProductCategoryService {

    @Autowired
    private ProductCategoryMapper categoryMapper;

    @Autowired
    private JedisClientSingle jedisClientSingle;

    @Value("${CATEGROY_ID_CACHE_REDIS_KEY}")
    private String CATEGROY_ID_CACHE_REDIS_KEY;

    @Override
    public List<EUTreeNode> getCategoryList(Long parentId) {
        long startTime = System.currentTimeMillis();
        List<EUTreeNode> resultList = new ArrayList<>();
        // 从redis缓存中取内容
        try {
            String cacheDatas = jedisClientSingle.hget(CATEGROY_ID_CACHE_REDIS_KEY, parentId.toString());
            if (StringUtils.isNotBlank(cacheDatas)) {
                List<ProductCategory> categories = JsonUtils.jsonToList(cacheDatas, ProductCategory.class);
                for (ProductCategory category : categories) {
                    EUTreeNode node = new EUTreeNode();
                    node.setId(category.getId());
                    node.setText(category.getName());
                    node.setState(category.getIsParent()?"closed":"open");
                    resultList.add(node);
                }
                System.out.println("redis cache Time : " + (System.currentTimeMillis() - startTime));
                return resultList;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        ProductCategoryExample example = new ProductCategoryExample();
        Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(1);
        criteria.andParentIdEqualTo(parentId); // 查询父节点下的所有子节点
        List<ProductCategory> productCategories = categoryMapper.selectByExample(example);

        for (ProductCategory category : productCategories) {
            EUTreeNode node = new EUTreeNode();
            node.setId(category.getId());
            node.setText(category.getName());
            node.setState(category.getIsParent()?"closed":"open");
            resultList.add(node);
        }
        System.out.println("No redis cache Time : " + (System.currentTimeMillis() - startTime));
        // 向redis缓存中添加内容
        try {
            jedisClientSingle.hset(CATEGROY_ID_CACHE_REDIS_KEY, parentId.toString(), JsonUtils.objectToJson(productCategories));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }

    // 后面的内容看源码...
}

源码:https://github.com/ITDragonBlog/daydayup/tree/master/Redis

到这里,Redis 的快速入门就结束了。下一章节介绍Redis 的主从和集群。

作者:qq_19558705 发表于2017/11/25 23:41:07 原文链接
阅读:2 评论:0 查看评论

Unity Shader 学习笔记(27)渲染轮廓线(描边)方法、卡通风格渲染、素描风格渲染

$
0
0

Unity Shader 学习笔记(27)渲染轮廓线(描边)方法、卡通风格渲染、素描风格渲染

参考书籍:《Unity Shader 入门精要》


渲染轮廓线(描边)

五种方法:
- 基于观察角度和表面法线。即视角方向和表面法线点乘结果判断(接近0,表示面接近垂直与视角)。
- 过程式几何。两个Pass:第一个Pass渲染背面并且让轮廓可见(顶点外扩);第二个Pass正常渲染正面。适应于大多数表面平滑的模型,不适合立方体等平整模型。
- 基于图像处理。前面两种边缘检测就是了:直接用算子判断使用深度和法线纹理。但如果一些深度和法线变化很小的无法检测出来,如桌子上一张纸。
- 基于轮廓边。检测方法:相邻两个三角是否一个面向视角,另一个背向视角,就是边。即 (n0·v > 0) ≠ (n1·v > 0)。 缺点是轮廓是逐帧单独提取的,帧与帧之间会出现跳跃性。
- 混合上述方法。首先找到轮廓线(方法4),把模型和轮廓边渲染到纹理中,再使用图像处理识别轮廓线(方法3),在图像空间进行风格化渲染。


卡通风格渲染

使用描边方法2,以及卡通风格的高光反射光照模型实现。
描边注意:在背面顶点扩展时,可能有正面的面,这时会出错。可想象一个半实心球,内部有个面向视角的面,顶点外扩时,内部的面会超出外表面,遮挡了外表面。解决办法是先让背面法线z值减0.5再归一化(背面压扁)。
高光实现:镜面反射使用Blinn模型,计算(n·h)时,做阈值比较,小于的就是高光部分。

Shader "Custom/Chapter 14/Toon Shading" {
    Properties {
        _Color ("Color Tint", Color) = (1, 1, 1, 1)
        _MainTex ("Main Tex", 2D) = "white" {}
        _Ramp ("Ramp Texture", 2D) = "white" {}                     // 漫反射渐变纹理
        _Outline ("Outline", Range(0, 1)) = 0.1                     // 轮廓线宽度
        _OutlineColor ("Outline Color", Color) = (0, 0, 0, 1)       // 轮廓线颜色
        _Specular ("Specular", Color) = (1, 1, 1, 1)
        _SpecularScale ("Specular Scale", Range(0, 0.1)) = 0.01     // 高光反射的阈值
    }
    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}

        // 第一个Pass,延展背面顶点,实现描边。
        Pass {
            NAME "OUTLINE"
            Cull Front      // 剔除正面,只渲染正面
            ...

            v2f vert (a2v v) {
                v2f o;

                // 顶点和法线变换到视角空间下,让描边可以在观察空间达到最好的效果
                float4 pos = mul(UNITY_MATRIX_MV, v.vertex); 
                float3 normal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);  
                normal.z = -0.5;    // 让法线向视角方向外扩,避免物体有背面遮挡正面
                pos = pos + float4(normalize(normal), 0) * _Outline;        //对外扩展,出现轮廓
                o.pos = mul(UNITY_MATRIX_P, pos);

                return o;
            }
            ...
        }

        // 第二个Pass,基于Blinn光照模型,使用自定义高光光照模型,实现高光。
        Pass {
            Tags { "LightMode"="ForwardBase" }
            Cull Back
            ...

            float4 frag(v2f i) : SV_Target { 
                ...

                fixed spec = dot(worldNormal, worldHalfDir);

                // 高光区域抗锯齿操作,fwidth:邻域像素的近似导数。
                fixed w = fwidth(spec) * 2.0;       

                // _SpecularScale为0会完全消除高光反射,smoothstep:小于-w为0,大于w为1,否则在01之间插值。
                fixed3 specular = _Specular.rgb * lerp(0, 1, smoothstep(-w, w, spec + _SpecularScale - 1)) * step(0.0001, _SpecularScale);    

                return fixed4(ambient + diffuse + specular, 1.0);
            }

            ENDCG
        }
    }
    FallBack "Diffuse"
}

素描风格渲染

通过判断不同光照下漫反射值,使用不同的渲染纹理。纹理组成一个色调艺术映射(Tonal Art Map, TAM)。


// 素描风格
Shader "Custom/Chapter 14/Hatching" {
    Properties {
        _Color ("Color Tint", Color) = (1, 1, 1, 1)
        _TileFactor ("Tile Factor", Float) = 1  // 平铺系数
        _Outline ("Outline", Range(0, 1)) = 0.1
        _Hatch0 ("Hatch 0", 2D) = "white" {}    // 6张素描纹理,模拟不同阴影使用的纹理
        _Hatch1 ("Hatch 1", 2D) = "white" {}
        _Hatch2 ("Hatch 2", 2D) = "white" {}
        _Hatch3 ("Hatch 3", 2D) = "white" {}
        _Hatch4 ("Hatch 4", 2D) = "white" {}
        _Hatch5 ("Hatch 5", 2D) = "white" {}
    }

    SubShader {
        Tags { "RenderType"="Opaque" "Queue"="Geometry"}

        UsePass "Custom/Chapter 14/Toon Shading/OUTLINE"    // 使用前面的描边渲染Pass

        Pass {
            ...

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
                fixed3 hatchWeights0 : TEXCOORD1;   // 6张纹理存在两个fixed3中
                fixed3 hatchWeights1 : TEXCOORD2;
                float3 worldPos : TEXCOORD3;
                SHADOW_COORDS(4)
            };

            v2f vert(a2v v) {
                ...

                o.hatchWeights0 = fixed3(0, 0, 0);
                o.hatchWeights1 = fixed3(0, 0, 0);

                float hatchFactor = diff * 7.0; // 放大7倍,便于分成7块,混合权重。

                if (hatchFactor > 6.0) {
                    // 纯白
                } else if (hatchFactor > 5.0) {
                    o.hatchWeights0.x = hatchFactor - 5.0;
                } else if (hatchFactor > 4.0) {
                    o.hatchWeights0.x = hatchFactor - 4.0;
                    o.hatchWeights0.y = 1.0 - o.hatchWeights0.x;
                } else if (hatchFactor > 3.0) {
                    o.hatchWeights0.y = hatchFactor - 3.0;
                    o.hatchWeights0.z = 1.0 - o.hatchWeights0.y;
                } else if (hatchFactor > 2.0) {
                    o.hatchWeights0.z = hatchFactor - 2.0;
                    o.hatchWeights1.x = 1.0 - o.hatchWeights0.z;
                } else if (hatchFactor > 1.0) {
                    o.hatchWeights1.x = hatchFactor - 1.0;
                    o.hatchWeights1.y = 1.0 - o.hatchWeights1.x;
                } else {
                    o.hatchWeights1.y = hatchFactor;
                    o.hatchWeights1.z = 1.0 - o.hatchWeights1.y;
                }

                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                TRANSFER_SHADOW(o);

                return o; 
            }

            fixed4 frag(v2f i) : SV_Target {            
                fixed4 hatchTex0 = tex2D(_Hatch0, i.uv) * i.hatchWeights0.x;
                fixed4 hatchTex1 = tex2D(_Hatch1, i.uv) * i.hatchWeights0.y;
                fixed4 hatchTex2 = tex2D(_Hatch2, i.uv) * i.hatchWeights0.z;
                fixed4 hatchTex3 = tex2D(_Hatch3, i.uv) * i.hatchWeights1.x;
                fixed4 hatchTex4 = tex2D(_Hatch4, i.uv) * i.hatchWeights1.y;
                fixed4 hatchTex5 = tex2D(_Hatch5, i.uv) * i.hatchWeights1.z;
                // 全白和最浅的纹理混合。
                fixed4 whiteColor = fixed4(1, 1, 1, 1) * (1 - i.hatchWeights0.x - i.hatchWeights0.y - i.hatchWeights0.z - 
                            i.hatchWeights1.x - i.hatchWeights1.y - i.hatchWeights1.z);

                fixed4 hatchColor = hatchTex0 + hatchTex1 + hatchTex2 + hatchTex3 + hatchTex4 + hatchTex5 + whiteColor;

                UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

                return fixed4(hatchColor.rgb * _Color.rgb * atten, 1.0);
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}
作者:l773575310 发表于2017/11/26 0:31:21 原文链接
阅读:23 评论:0 查看评论

jQuery学习之三---工具

$
0
0

本博文会挑选一些比较重要的内容进行分析解释,恭迎大家观看哦,加油,一起学习!!

数组和对象操作

1、.each(object,[callback])退each使falsejQuery().each() 方法,此方法可用于例遍任何对象。

//遍历数组
$.each([2017,11,25],function(i,n)){
    console.log(i,n);//0,2017 1,11 2,25
}
//遍历对象
$.each({name:"pingzi",sex:"girl"},function(i,n)){
    console.log(i,n);//0,pingzi 1,girl
}

2、$.grep(array,callback,[invert])
使用过滤函数过滤数组元素。
此函数的前两个参数是必选的:待过滤数组和过滤函数callback,此函数将处理数组每个元素。第一个参数为当前元素,第二个参数为元素索引值。此函数应返回一个布尔值,返回true以保留元素,false以删除元素。
invert,是决定grep函数返回值的。默认为false,这个时候grep函数返回符合过滤函数return条件的新数组,就是删除了不符合条件的元素的新数组

$.grep([0,1,2],function(n,i){
    return n>0;
})
//[1,2]

当invert设置为true时,grep函数返回被过滤掉的元素数组,内容是被删除的元素

$.grep([2017,11,25],function(n,i){
    return n>1;
},true)
//[0,1]

3、$.map(arr|obj,callback)
将一个数组中的元素转换到另一个数组中。
通俗的说,就是把一个数组里面的元素,通过callback进行操作之后,返回一个新数组的过程。

//将原数组中每个元素+4转换成一个新数组
$.map([0,1,2],function(n){
    return n+4;
});
//[4,5,6]

//原数组中每个元素扩展为一个包含本身和其值+1的数组,并转换为一个新的数组
    //哎呦好气哦,这个题目为啥子一定要说的这么洋气,其实不就是返回数组本身和其本来的元素+1的数组嘛,有毛病哦
$.map([0,1,2],function(n){
    return [n,n+1];
});
//[0,1,1,2,2,3]

4、$.inArray(val,arr)
参一:查找的内容
参二:待处理的数组
确定第一个参数在数组中的位置,从0开始计数,如没找到返回-1

var arr = ["pingzi",7,8,"child"];
$.inArray("pingzi",arr);0
$.inArray(9,arr);//-1

5、$.toArray()
把jq集合中所有的DOM元素转化为一个数组

<li>1</li>
<li>2</li>
<li>3</li>
$("li").toArray();//[<li>1</li>,<li>2</li>,<li>3</li>]

6、$.merge(fir,sec)
合并两个数组,返回结果会修改第一个数组的内容,第二个数组的元素加在第一个数组元素后面。

$.merge( [0,1,2], [2,3,4] );//[0,1,2,2,3,4]

测试操作

7、$.contains(container,contained)
一个DOM节点是否包含另一个DOM节点
container:DOM元素作为容器,可以包含其他元素
contained:DOM节点,可能被其他元素所包含

//检测一个元素是否包含另一个元素
$.contains(document.documentElement,document.body);//true
$.contains(document.body,document.documentElement);//false

8、$.type(obj)
检测obj的数组类型

jQuery.type(true) === "boolean"   
jQuery.type(3) === "number"
jQuery.type("test") === "string"
jQuery.type(function(){}) === "function"
jQuery.type([]) === "array"
jQuery.type(new Date()) === "date"
jQuery.type(/test/) === "regexp"

9、.isFunction(obj)obj10.isEmptyObject(obj)
jQuery 1.4 新增。测试对象是否是空对象(不包含任何属性)。
jQuery 1.4 中,这个方法既检测对象本身的属性,也检测从原型继承的属性

$.isEmptyObject({}) // true
$.isEmptyObject({ foo: "bar" }) // false

11、 .isWindow(obj)Frame12.isNumeric(value)
确定它的参数是否是一个数字。
$.isNumeric() 方法检查它的参数是否代表一个数值。如果是这样,它返回 true。否则,它返回false。该参数可以是任何类型的


字符串操作

13、$.trim(str)
去掉字符串起始和结尾的空格

$.trim("  hello, how are you?  ");
//"hello, how are you?"

插件编写

14、 $.fn.jquery
代表 jQuery 版本号的字符串。

//取得页面上当前使用的 jQuery 的版本号。
alert( 'You are running jQuery version: ' + $.fn.jquery );
作者:MYTLJP 发表于2017/11/26 0:27:59 原文链接
阅读:68 评论:0 查看评论

Unity3D - Shader - 凹凸映射(Bump mapping)

$
0
0

凹凸映射的目的:是使用纹理来修改模型表面的法线,用于为模型提供更多细节。

凹凸映射的方式

  • 高度纹理(height map):用于模拟表面位移(displacement),也称作高度映射(height mapping)
  • 法线纹理(normal map):用于直接存储表面法线,又称为法线映射(normal mapping)

高度纹理

高度图中存储的是强度值(intensity),用于表示局部海拔高度。

颜色越浅表明该位置的表面越向外凸起,颜色越深表明该位置越向里凹。

有点是直观,缺点是计算复杂,无法实时得到表面法线。

法线纹理

法线纹理中存储的是表面法线的方向。

需要使用如下公式将,法线方向的分量[-1,1]映射到像素分量[0,1]:

pixel=normal+12

当在Shader中对法线纹理进行采样后,需要对结果使用公式进行一次反映射,用于得到原先的法线方向:

normal=pixel21

法线纹理:

  • 模型空间的法线纹理(object-space normal map)
  • 切线空间的法线纹理(tangent-space normal map)

模型空间的法线纹理

将修改后的模型空间中表面法线存储在一张纹理中。

切线空间的法线纹理

在实际制作中使用,模型顶点的切线空间(tangent space)来存储发现。对于模型的每个顶点,它都有一个属于自己的切线空间,这个切线空间的原点就是该顶点本身,而Z轴是顶点的发现方向(n),X轴是顶点的切线方向(t),而Y轴是法线和切线的叉积,称为副切线(bitangent,b)或副法线。

这里写图片描述

这里写图片描述

切线空间的优点:

  • 自由度高,模型空间下的法线纹理记录的是绝对法线信息,仅可以用于创建它的那个模型。而切线空间下的法线纹理记录的是相对法线信息。
  • 可进行UV动画。可以移动一个纹理的UV坐标来实现凹凸移动的效果。UV动画在水或者火山熔岩这种类型的物体长经常用到。
  • 可重用法线纹理。
  • 可压缩。

实现

在计算光照模型时,需要统一各个方向矢量所在的坐标空间。由于法线纹理中存储的法线是切线空间下的方向,因此通常有两个选择:

  • 切线空间下进行光照计算,需要把光照方向、视角方向变换到切线空间下
  • 世界空间下进行光照计算,需要把采样得到的法线方向变换到世界空间下,再和世界空间下的光照方向和视角方向进行计算。

优缺点:

  • 性能上切线空间优于世界空间
  • 通用性上世界空间优于切线空间

切线空间

基本思路是:在片元着色器中通过纹理采样得到切线空间下的法线,然后再与切线空间下的视角方向、光照方向等进行计算,得到最终的计算结果。

需要先在顶点着色器中把视角方向和光照方向从模型空间变换到切线空间,即需要知道从模型空间到切线空间的变换矩阵。

从模型空间到切线空间的变换矩阵就是从切线空间到模型空间的变换矩阵的逆矩阵,把切线(x轴)、副切线(y轴)、法线(z轴)按顺序排列即可以得到。

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 7/Normal Map Tangent Space" {

    Properties {
        _Color ("Color Tint", Color) = (1, 1, 1, 1) 
        _MainTex("Main Tex", 2D ) = "white" {}
        // 法线纹理
        // bump是Unity内置的法线纹理
        _BumpMap("Normap Map", 2D) = "bump" {}
        // 用于控制凹凸程度,当它为0时,意味着该法线纹理不会对
        // 光照产生任何影响
        _BumpScale("Bump Scale", Float) = 1.0

        _Specular("Specular", Color) = (1, 1, 1, 1)
        _Gloss("Gloss", Range(8.0, 256)) = 20
    }

    SubShader {
        Pass {
            Tags {"LightMode"="ForwardBase"}

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            // 与Properties语义块中的属性建立联系
            fixed4 _Color;
            sampler2D _MainTex;
            // 得到MainTex纹理属性的平铺和偏移系数
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            // 得到BumpMap纹理属性的平铺和偏移系数
            float4 _BumpMap_ST;
            float _BumpScale;
            fixed4 _Specular;
            float _Gloss;

            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                // 顶点的切线方向
                // 需要使用tangent.w分量来决定切线空间中的第三个坐标轴-副切线的方向性
                float4 tangent : TANGENT;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;
                // 光照方向
                float3 lightDir : TEXCOORD1;
                // 视角方向
                float3 viewDir : TEXCOORD2;
            };

            v2f vert(a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);

                // xy分量存储了_MainTex的纹理坐标
                o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                // zw分量存储了_BumpMap的纹理坐标
                o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;

                // 将模型空间下的切线方向、副切线方向和法线方向按行排列得到从模型空间到
                // 切线空间的变换矩阵rotation。

                // 之所以和w分量相乘,是为了决定使用哪一个方向
                // float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) ) * v.tangent.w; 
                // float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal )
                TANGENT_SPACE_ROTATION;

                // Transform the light direction from object space to tangent space
                // ObjSpaceLightDir用于得到模型空间下的光照方向
                o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
                // ObjSpaceViewDir用于得到模型空间下的视角方向
                o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;

                return o;
            }

            // 采样得到切线空间下的法线方向,再在切线空间下进行光照计算即可
            fixed4 frag(v2f i) : SV_Target {
                fixed3 tangentLightDir = normalize(i.lightDir);
                fixed3 tangentViewDir = normalize(i.viewDir);

                // Get the texel in the normal map
                // 法线纹理中存储的是经过映射后得到的像素值
                fixed4 packedNormal = tex2D(_BumpMap, i.uv.zw);
                fixed3 tangentNormal;

                // If the texture is not marked as "Normal map"
                // tangentNormal.xy = (packedNormal.xy * 2 - 1 ) * _BumpScale;
                // tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));

                //  Or mark the texture as "Normal map", and use the built-in funciton
                tangentNormal = UnpackNormal(packedNormal);
                tangentNormal.xy *= _BumpScale;
                tangentNormal.z = sqrt(1.0 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));

                fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

                fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));

                fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);

                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(tangentNormal,halfDir)), _Gloss);

                return fixed4(ambient + diffuse + specular, 1.0);
            }

            ENDCG
        }
    }
    Fallback "Specular"
}

世界空间

基本思路:在顶点着色器中计算从切线空间到世界空间的变换矩阵,并传递给片元着色器。变换矩阵的计算可以由顶点的切线、副切线和法线在世界空间的表示来得到。

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "Unity Shaders Book/Chapter 7/Normal Map World Space" {
    Properties {
        _Color ("Color Tint", Color) = (1, 1, 1, 1) 
        _MainTex("Main Tex", 2D ) = "white" {}
        // 法线纹理
        // bump是Unity内置的法线纹理
        _BumpMap("Normap Map", 2D) = "bump" {}
        // 用于控制凹凸程度,当它为0时,意味着该法线纹理不会对
        // 光照产生任何影响
        _BumpScale("Bump Scale", Float) = 1.0

        _Specular("Specular", Color) = (1, 1, 1, 1)
        _Gloss("Gloss", Range(8.0, 256)) = 20
    }

    SubShader {
        Pass {
            Tags {"LightMode"="ForwardBase"}

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Lighting.cginc"

            // 与Properties语义块中的属性建立联系
            fixed4 _Color;
            sampler2D _MainTex;
            // 得到MainTex纹理属性的平铺和偏移系数
            float4 _MainTex_ST;
            sampler2D _BumpMap;
            // 得到BumpMap纹理属性的平铺和偏移系数
            float4 _BumpMap_ST;
            float _BumpScale;
            fixed4 _Specular;
            float _Gloss;

            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                // 顶点的切线方向
                // 需要使用tangent.w分量来决定切线空间中的第三个坐标轴-副切线的方向性
                float4 tangent : TANGENT;
                float4 texcoord : TEXCOORD0;
            };

            struct v2f {
                float4 pos : SV_POSITION;
                float4 uv : TEXCOORD0;
                float4 TtoW0 : TEXCOORD1;
                float4 TtoW1 : TEXCOORD2;
                float4 TtoW2 : TEXCOORD3;
            };

            v2f vert(a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);

                // xy分量存储了_MainTex的纹理坐标
                o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                // zw分量存储了_BumpMap的纹理坐标
                o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;

                // 世界空间下位置                 
                float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                // 世界空间法线
                fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);
                // 世界空间切线
                fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
                // 世界空间副切线
                fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;

                // Compute the matrix that transform directions from tangent space to world space
                // Put the world postion in w component for optimizeation
                o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); 
                o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); 
                o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); 

                return o;
            }

            fixed4 frag(v2f i) : SV_Target {

                // Get the position in world space
                // 构建世界空间下的坐标
                float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);

                // Compute the light and view dir in world space
                // 世界空间的光照
                fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
                // 世界空间的视角
                fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

                // Get the normal in tangent space
                // 使用UnpackNormal对法线纹理进行采样和解码(需要把法线纹理的格式识别为Normal map)
                // 并使用_BumpScale进行缩放。
                fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));
                bump.xy *= _BumpScale;
                bump.z = sqrt(1.0 - saturate(dot(bump.xy, bump.xy)));

                // Transform the normal from tangent space to world space
                // 使用TtoW0/TtoW1/TtoW2存储的变换矩阵把法线变换到世界空间下。
                bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));

                fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;

                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

                fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, lightDir));

                fixed3 halfDir = normalize(lightDir + viewDir);

                fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(bump, halfDir)), _Gloss);

                return fixed4(ambient + diffuse + specular, 1.0);
            }

            ENDCG
        }
    }
    Fallback "Specular"
}
作者:biezhihua 发表于2017/11/26 2:28:53 原文链接
阅读:48 评论:0 查看评论

pandas之get_dummies

$
0
0

方法

pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False)

该方法可以讲类别变量转换成新增的虚拟变量/指示变量。

常用参数

  • data : array-like, Series, or DataFrame
    输入的数据
  • prefix : string, list of strings, or dict of strings, default None
    get_dummies转换后,列名的前缀
    *columns : list-like, default None
    指定需要实现类别转换的列名
  • dummy_na : bool, default False
    增加一列表示空缺值,如果False就忽略空缺值
  • drop_first : bool, default False
    获得k中的k-1个类别值,去除第一个

实验

这里写图片描述
这里写图片描述

作者:u010665216 发表于2017/11/26 9:54:03 原文链接
阅读:72 评论:0 查看评论

ELK之Logstash安装与配置及使用

$
0
0

1 Logstash介绍

        Logstash 是开源的服务器端数据处理管道,能够同时 从多个来源采集数据、转换数据,然后将数据发送到您最喜欢的 “存储库” 中。(我们的存储库当然是 Elasticsearch。)


2、安装jdk

# yum -y install java-1.8.0
# java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)



3 安装logstash
# wget https://artifacts.elastic.co/downloads/logstash/logstash-6.0.0.tar.gz
# tar zxf logstash-6.0.0.tar.gz -C /Data/apps/




配置logstash的环境变量
# echo "export PATH=\$PATH:/Data/apps/logstash-6.0.0/bin" > /etc/profile.d/logstash.sh
# . /etc/profile




4 查看帮助
# logstash --help




5 logstash常用参数
-e :指定logstash的配置信息,可以用于快速测试;
-f :指定logstash的配置文件;可以用于生产环境;


6、启动logstash
6.1 通过-e参数指定logstash的配置信息,用于快速测试,直接输出到屏幕。--quiet:日志输出安静模式
$ logstash -e "input {stdin{}} output {stdout{}}" --quiet




6.2 
$ logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'




7 logstash以配置文件方式启动

$ vim logstash.conf
input { stdin {} }
output {
   stdout { codec=> rubydebug }
}
$ logstash -f logstash.conf --quie
yes ,i can
{
      "@version" => "1",
          "host" => "wechat1-dev.bj1.xxxx.net",
    "@timestamp" => 2017-11-25T10:28:38.763Z,
       "message" => "yes ,i can"
}




8 更多样例,
请参考官方文档样例:https://www.elastic.co/guide/en/logstash/current/config-examples.html
8.1 样例 elasticsearch
input { stdin { } }
output {
  elasticsearch { hosts => ["localhost:9200"] }
  stdout { codec => rubydebug }
}




8.2 样例 access_log

input {
  file {
    path => "/tmp/access_log"
    start_position => "beginning"
  }
}


filter {
  if [path] =~ "access" {
    mutate { replace => { "type" => "apache_access" } }
    grok {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
    }
  }
  date {
    match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
  }
}


output {
  elasticsearch {
    hosts => ["localhost:9200"]
  }
  stdout { codec => rubydebug }
}



8.3 写入redis
input { stdin { } }
output {
    stdout { codec => rubydebug }
    redis {
        host => '192.168.1.104'
        data_type => 'list'
        key => 'logstash:redis'
    }
}



作者:CleverCode 发表于2017/11/26 10:48:48 原文链接
阅读:68 评论:0 查看评论

解决VMware虚拟机报错“无法连接MKS:套接字连接尝试次数太多,正在放弃”

$
0
0

1.错误描述

在VMware中打开虚拟机时报错:
“无法连接MKS:套接字连接尝试次数太多,正在放弃”
物理机操作系统:
Windows 7
虚拟机操作系统:
Kali Linux

2.解决办法如下

a.关闭出问题的虚拟机

b.依次打开:

“我的电脑”->“管理”->“服务和应用程序”->“服务”

c.右键启动以下服务:

VMware Authorization Service
VMware DHCP Service
VMware NAT Service
VMware USB Arbitration Service
VMware Workstation Server

开启原来出问题的虚拟机,可以正常启动,问题解决。
end
更多内容请访问我的个人网站荒原之梦

作者:wy_bk 发表于2017/11/26 10:50:05 原文链接
阅读:57 评论:0 查看评论

一起Talk Android吧(第五十一回:Android中的Fragment嵌套二)

$
0
0

各位看官们,大家好,上一回中咱们说的是Android中Fragment的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起Talk Android吧!


看官们,我们在上一回中提到了Fragment的两种嵌套方法:静态嵌套和动态嵌套,并且介绍了静态嵌套Fragment的方法,这一回中我们将介绍动态嵌套Fragment的方法。

动态嵌套Fragment的方法和动态加载Fragment的方法类似,也是在父Fragment的布局文件中给子Fragment预留一个位置,然后在父Fragment的代码中通过代码来加载子Fragment,总体的思想就是这样,具体的细节我们将结合代码来说明。

  • 1.创建一个名为frag_a的布局文件,该文件就是FragmentA的布局文件,至于布局文件中的内容,可以自己去定义;
  • 2.创建一个名为FragmentA的类,该类继承自Fragment,接着重写该类的onCreateView方法, 具体的代码为:
public class FragmentB extends Fragment { 

  //重写onCreateView方法
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  {
    View view = inflater.inflate(R.layout.frag_a,container,false); //frag_a就是刚才创建的布局文件
    return view;
  }
    //override other callback
}
这两个步骤创建了FragmentA的布局文件和逻辑文件,我们把它当作父Fragment,再用同样的方法创建子Fragment,我们叫它FragmentB。
  • 3.通过修改FragmentA的布局文件,使用布局标签把刚才创建的FragmentA和FragmentB关联起来,具体的代码为:
<LinearLayour ...>    //这是FragmentA的布局文件
    <Fragment    //使用Fragment标签或者其它布局标签都可以,比如LinearLayout。
        android:id=frag_son_container   //这个不可少,它是父Fragment给子Fragment预留的位置
        ....  //其它长度,宽度等大小属性省略不写
    />
</LinearLayour> 
  • 4.在FragmentA的onCreateView()方法中使用FragmentManager的相关方法来加载FragmentB.
FragmentManager fm = getchildFragmentManager();           //首先需要获取FragmentManager
FragmentTransaction transaction = fm.beginTransaction();  //开始FragmentManager的事务
transaction.add(R.id.frag_son_container,new FragmentB()); //添加FramentB到Fragment给它预留的位置
transaction.commit();                                     //提交事务

看官们,看完这个代码细节后是不是觉得动态嵌套Fragment和动态加载Fragment十分类似?是的,仔细对比一下就会发它们的不同之处只有一点:获取FragmentManager的方法不同。动态嵌套Fragment使用的是FragmentgetchildFragmentManager()方法,而动态加载Fragment使用的是ActivitygetSupportFragmentManager()方法。类不同其方法自然也不同,大家使用的时候不要混淆就可以。

此外,我们在这里没有写出Activity的布局文件,FragmentA和FragmentB是不能单独使用的,它需要加载到Activity中,至于使用静态加载还是动态加载,我们不关心,因为使用哪种方式都一样。这和静态嵌套方法中的处理方式一样。

各位看官,关于Android中Fragment的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!


作者:talk_8 发表于2017/11/26 10:50:19 原文链接
阅读:30 评论:0 查看评论

Spring Boot学习总结(10)——SpringBoot打包成Docker镜像

$
0
0
<build>
<!--定义jar文件名,可以自定义-->
<finalName>${project.name}-${project.version}</finalName> 
<plugins> 
<plugin> 
<groupId>org.springframework.boot</groupId> 
<artifactId>spring-boot-maven-plugin</artifactId>
<!--指定主类,建议手动指定-->
<configuration> 
<mainClass>io.pumelo.HelloApplication</mainClass> 
</configuration> 
<executions>
<!--打包依赖到当前服务中-->
<execution> 
<goals> 
<goal>repackage</goal> 
</goals> 
</execution> 
</executions> 
</plugin>
<!--docker打包插件-->
<plugin> 
<groupId>com.spotify</groupId> 
<artifactId>docker-maven-plugin</artifactId> 
<version>0.4.11</version> 
<configuration>
<!--打包后的镜像名称,可以自定义-->
<imageName>${docker.image.prefix}/${project.artifactId}-${version}</imageName>
<!--基础镜像,包含oraclejdk8-->
<baseImage>frolvlad/alpine-oraclejdk8:slim</baseImage>
<!--java初始化参数,可以自定义-->
<entryPoint>[ "sh", "-c", "java -Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom -jar /${project.build.finalName}.jar" ]</entryPoint> 
<resources>
<!--需要打包进镜像的文件,还可以加其他的文件-->
<resource> 
<targetPath>/</targetPath> 
<directory>${project.build.directory}</directory> 
<include>${project.build.finalName}.jar</include> 
</resource>
</resources> 
</configuration> 
</plugin> 
</plugins>
</build>

在控制台中输入:mvn clean package -pl hello-service docker:build 即可打包出docker镜像。如果你的项目不是多模块的,那么去掉-pl 参数变为:mvn clean package docker:build ,多模块需要指定模块。


作者:u012562943 发表于2017/11/26 11:34:47 原文链接
阅读:59 评论:0 查看评论

Google提出的新型激活函数:Swish

$
0
0

简介

Swish是Google在10月16号提出的一种新型激活函数,其原始公式为:f(x)=x * sigmod(x),变形Swish-B激活函数的公式则为f(x)=x * sigmod(b * x),其拥有不饱和,光滑,非单调性的特征,而Google在论文中的多项测试表明Swish以及Swish-B激活函数的性能即佳,在不同的数据集上都表现出了要优于当前最佳激活函数的性能.

论文地址:这里写链接内容

这里写图片描述

详细讲述

激活函数常在神经网络中用于添加非线性因素,可以将激活函数定义为一个几乎处处可微的函数:h : R → R .[1].

公式

激活函数存在饱和问题,当激活函数满足上述公式第一种情况时,称之为右饱和,反之为左饱和.

如果激活函数在非极限状态下存在一个常数C可以证明,在x大于或小于该常数C时,h(x)的一次导数存在恒等于零的情况时,则称h(x)为右硬饱和函数或左硬饱和函数.否则称其为软饱和函数.

因为反向传播算法的计算方式,可证明饱和激活函数会导致神经网络的性能大幅度下降.从而产生梯度消失问题,如常见的sigmod或tanh函数都存在该问题.

而现在深度神经网络中常用的激活函数为ReLU激活函数,其存在有上界,无下界,光滑的特点,其变种拥有在大多数数据集上的最佳性能.但是其变种复杂多样想要使用仍然存在很多的调试问题.而新的Swish函数则不同,其Swish-B形式在谷歌论文中的大型数据集即各种神经网络中中拥有绝对的优势,虽然现在还没有数学证明,但是其实践结果却可能意味着,我们之后再也不需要测试很多的激活函数了,这大大降低了我们的工作量.

Swish与ReLU一样有上界而无下界,但是其非单调性确与其他常见的激活函数不同,通知其也拥有平滑和一阶导数,二阶导数平滑的特性.

谷歌测试证明,Swich适应于局部响应归一化,并且在40以上全连接层的效果要远优于其他激活函数,而在40全连接层之内则性能差距不明显.但是根据在mnist数据上AleNet的测试效果却证明,Swich在低全连接层上与Relu的性能差距依旧有较大的优势.

对于MNIST数据集而言,五层内的全连接层已经可以达到更好的测试性能,但是为了测试两种激活函数的不同,我使用了3,10,45三种不同的全连接层进行测试,同时为了加大数据集的难度,我同时使用了Fashion-MNIST数据集进行测试

测试结果:
这里写图片描述

总结.

google的论文告诉我们在更大的数据集与更深的神经网络上,Swish拥有更好的性能,而且当其与局部响应归一化结合使用时,味道更佳,但是我们在mnist与Fashion-MNIST数据集上的测试同时也表明,其实在部分中小型数据集上Swish激活函数,可能也拥有不错的性能表现.优于该函数没有数学证明,我们在使用时可能需要多实践一些.但是总体上我们可以认为,该激活函数是有效的.看来我们之后又多了一个炼丹的利器.

参考
[1] Noisy Activation Functions: Caglar Gulcehre, Marcin Moczulski
,Misha Denil, Yoshua Bengio.arXiv:1603.00391v3

[2] Fashion-MNIST: a Novel Image Dataset for Benchmarking Machine Learning Algorithms. Han Xiao, Kashif Rasul, Roland Vollgraf. arXiv:1708.07747

[3] Swish: a Self-Gated Activation Function.Prajit Ramachandran, Barret Zoph, Quoc V. Leoc V. Le. arXiv:1710.05941

作者:FontThrone 发表于2017/11/26 11:35:15 原文链接
阅读:39 评论:0 查看评论

2017年Kali Linux更新源

$
0
0

终端输入:

leafpad /etc/apt/sources.list

打开更新源配置文件,将下面的更新源复制到原内容的前面:

#163网易 Kali源
deb http://mirrors.163.com/debian wheezy main non-free contrib 
deb-src http://mirrors.163.com/debian wheezy main non-free contrib 
deb http://mirrors.163.com/debian wheezy-proposed-updates main non-free contrib 
deb-src http://mirrors.163.com/debian wheezy-proposed-updates main non-free contrib 
deb-src http://mirrors.163.com/debian-security wheezy/updates main non-free contrib 
deb http://mirrors.163.com/debian-security wheezy/updates main non-free contrib

#阿里云 Kali源
deb http://mirrors.aliyun.com/kali kali main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali main non-free contrib
deb http://mirrors.aliyun.com/kali-security kali/updates main contrib non-free

#中科大 Kali源
deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib

#浙江大学 Kali源
deb http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free
deb-src http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free

#东软大学 Kali源
deb http://mirrors.neusoft.edu.cn/kali kali-rolling/main non-free contrib
deb-src http://mirrors.neusoft.edu.cn/kali kali-rolling/main non-free contrib

#重庆大学 Kali源
deb http://http.kali.org/kali kali-rolling main non-free contrib
deb-src http://http.kali.org/kali kali-rolling main non-free contrib

#官方Kali源
#deb http://http.kali.org/kali kali-rolling main non-free contrib
#deb-src http://http.kali.org/kali kali-rolling main non-free contrib

最后保存并退出

end
更多内容请访问我的个人网站荒原之梦

作者:wy_bk 发表于2017/11/26 11:38:02 原文链接
阅读:48 评论:0 查看评论

mysqldump原理解析

$
0
0

mysqldump原理解析

mysqldump过程中,server都执行了哪些操作呢?可以通过strace命令和打开general_log来查看。

1、strace

[mysql26@localhost ~]$ **strace mysqldump -uroot -p'db10$ZTE' --single-transaction --master-data=2 yzs t1 >  1.txt**
execve("/home/mysql26/bin/mysqldump", ["mysqldump", "-uroot", "-pdb10$ZTE", "--single-transaction", "--master-data=2", "yzs", "t1"], [/* 19 vars */]) = 0
brk(0)                                  = 0x9a11000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=37531, ...}) = 0
mmap2(NULL, 37531, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f4d000
close(3)                                = 0
open("/lib/libpthread.so.0", O_RDONLY)  = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P\270\315\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=129716, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f4c000
mmap2(0xcd7000, 94692, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xcd7000
mmap2(0xceb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13) = 0xceb000
mmap2(0xced000, 4580, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xced000
close(3)                                = 0
open("/lib/librt.so.1", O_RDONLY)       = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200(\317\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=44060, ...}) = 0
mmap2(0xcf1000, 33324, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xcf1000
mmap2(0xcf8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6) = 0xcf8000
close(3)                                = 0
open("/lib/libdl.so.2", O_RDONLY)       = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P\212\312\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=16428, ...}) = 0
mmap2(0xca8000, 12408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xca8000
mmap2(0xcaa000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1) = 0xcaa000
close(3)                                = 0
open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0pZ\4\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=5384191, ...}) = 0
mmap2(NULL, 1042080, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x560000
mmap2(0x653000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xf2) = 0x653000
mmap2(0x658000, 26272, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x658000
close(3)                                = 0
open("/lib/libm.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\24\313\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=208352, ...}) = 0
mmap2(0xcae000, 155760, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xcae000
mmap2(0xcd3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24) = 0xcd3000
close(3)                                = 0
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`6\263\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=46636, ...}) = 0
mmap2(0xb32000, 48196, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb32000
mmap2(0xb3d000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa) = 0xb3d000
close(3)                                = 0
open("/lib/libc.so.6", O_RDONLY)        = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340_\267\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1611564, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f4b000
mmap2(0xb60000, 1332676, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb60000
mprotect(0xc9f000, 4096, PROT_NONE)     = 0
mmap2(0xca0000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13f) = 0xca0000
mmap2(0xca3000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xca3000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f4a000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f4a8e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xca0000, 8192, PROT_READ)     = 0
mprotect(0xcd3000, 4096, PROT_READ)     = 0
mprotect(0x653000, 16384, PROT_READ)    = 0
mprotect(0xcaa000, 4096, PROT_READ)     = 0
mprotect(0xcf8000, 4096, PROT_READ)     = 0
mprotect(0xceb000, 4096, PROT_READ)     = 0
mprotect(0xb5c000, 4096, PROT_READ)     = 0
munmap(0xb7f4d000, 37531)               = 0
set_tid_address(0xb7f4a928)             = 7153
set_robust_list(0xb7f4a930, 0xc)        = 0
futex(0xbfab1164, FUTEX_WAKE_PRIVATE, 1) = 0
rt_sigaction(SIGRTMIN, {0xcdb3e0, [], SA_SIGINFO}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0xcdb2e0, [], SA_RESTART|SA_SIGINFO}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0
uname({sys="Linux", node="localhost.localdomain", ...}) = 0
brk(0)                                  = 0x9a11000
brk(0x9a32000)                          = 0x9a32000
stat64("/etc/my.cnf", 0xbfaad7f4)       = -1 ENOENT (No such file or directory)
stat64("/etc/mysql/my.cnf", 0xbfaad7f4) = -1 ENOENT (No such file or directory)
stat64("/home/mysql26/etc/my.cnf", {st_mode=S_IFREG|0664, st_size=858, ...}) = 0
open("/home/mysql26/etc/my.cnf", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0664, st_size=858, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f56000
read(3, "# For advice on how to change se"..., 4096) = 858
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7f56000, 4096)                = 0
stat64("/home/mysql26/.my.cnf", 0xbfaad7f4) = -1 ENOENT (No such file or directory)
stat64("/home/mysql26/.mylogin.cnf", 0xbfaad7f4) = -1 ENOENT (No such file or directory)
write(2, "Warning: Using a password on the"..., 73Warning: Using a password on the command line interface can be insecure.
) = 73
stat64("/home/mysql26/share/charsets/Index.xml", {st_mode=S_IFREG|0644, st_size=18305, ...}) = 0
open("/home/mysql26/share/charsets/Index.xml", O_RDONLY|O_LARGEFILE) = 3
read(3, "<?xml version='1.0' encoding=\"ut"..., 18305) = 18305
close(3)                                = 0
futex(0x8403e00, FUTEX_WAKE_PRIVATE, 2147483647) = 0
open("/etc/nsswitch.conf", O_RDONLY)    = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=1696, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f56000
read(3, "#\n# /etc/nsswitch.conf\n#\n# An ex"..., 4096) = 1696
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb7f56000, 4096)                = 0
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=37531, ...}) = 0
mmap2(NULL, 37531, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f4d000
close(3)                                = 0
open("/lib/libnss_files.so.2", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\30\0\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=46680, ...}) = 0
mmap2(NULL, 41616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x111000
mmap2(0x11a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8) = 0x11a000
close(3)                                = 0
mprotect(0x11a000, 4096, PROT_READ)     = 0
munmap(0xb7f4d000, 37531)               = 0
open("/etc/services", O_RDONLY)         = 3
fcntl64(3, F_GETFD)                     = 0
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=362031, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f56000
read(3, "# /etc/services:\n# $Id: services"..., 4096) = 4096
read(3, "rotocol\nntp\t\t123/tcp\nntp\t\t123/ud"..., 4096) = 4096
read(3, "767/udp\nrsync\t\t873/tcp\t\t\t\t# rsyn"..., 4096) = 4096
read(3, "stmanager\ncvspserver\t2401/tcp\t\t\t"..., 4096) = 4096
close(3)                                = 0
munmap(0xb7f56000, 4096)                = 0
rt_sigaction(SIGPIPE, {0x1, [PIPE], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
socket(PF_FILE, SOCK_STREAM, 0)         = 3
**connect**(3, {sa_family=AF_FILE, path="/home/mysql26/bin/mysql.sock"...}, 110) = 0
mmap2(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e4a000
setsockopt(3, SOL_IP, IP_TOS, [8], 4)   = -1 EOPNOTSUPP (Operation not supported)
setsockopt(3, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
recv(3, "T\0\0\0\n5.6.26-debug-log\0\7\0\0\0001o_k}R"..., 16384, 0) = 88
send(3, "\270\0\0\1\5\242>\0\0\0\200\1!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 188, 0) = 188
recv(3, "\7\0\0\2\0\0\0\2\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\36\0\0\0\3/*!40100 *SET @@SQL_MODE=''* "..., 34, 0) = 34
recv(3, "\7\0\0\1\0\0\0\2\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "#\0\0\0\3/*!40103 *SET TIME_ZONE='+00"*..., 39, 0) = 39
recv(3, "\7\0\0\1\0\0\0\2\0\0\0", 16384, 0) = 11
fstat64(1, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f56000
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\37\0\0\0\3*FLUSH /*!40101 LOCAL */ TAB*"..., 35, 0) = 35
recv(3, "\7\0\0\1\0\0\0\2\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\34\0\0\0\3*FLUSH TABLES WITH READ LOCK*", 32, 0) = 32
recv(3, "\7\0\0\1\0\0\0\2\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "8\0\0\0\3*SET SESSION TRANSACTION ISO*"..., 60, 0) = 60
recv(3, "\7\0\0\1\0\0\0\2\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "7\0\0\0\3*START TRANSACTION* /*!40100 "..., 59, 0) = 59
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "!\0\0\0\3*SHOW VARIABLES LIKE 'gtid\*\_"..., 37, 0) = 37
recv(3, "\1\0\0\1\2T\0\0\2\3def\22information_schema"..., 16384, 0) = 210
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\23\0\0\0\3*SHOW MASTER STATUS*", 23, 0) = 23
recv(3, "\1\0\0\1\5\32\0\0\2\3def\0\0\0\4File\0\f!\0\0\6\0\0\375\1\0"..., 16384, 0) = 238
brk(0x9a54000)                          = 0x9a54000
brk(0x9a52000)                          = 0x9a52000
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\16\0\0\0\3*UNLOCK TABLES*", 18, 0) = 18
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\371\1\0\0\3*SELECT LOGFILE_GROUP_NAME*, "..., 509, 0) = 509
recv(3, "\1\0\0\1\6V\0\0\2\3def\22information_schema"..., 16384, 0) = 473
ioctl(3, FIONREAD, [0])                 = 0
send(3, "X\1\0\0\3*SELECT DISTINCT TABLESPACE_*"..., 348, 0) = 348
recv(3, "\1\0\0\1\6P\0\0\2\3def\22information_schema"..., 16384, 0) = 489
ioctl(3, FIONREAD, [0])                 = 0
send(3, "'\0\0\0\3*SHOW VARIABLES LIKE* 'ndbinf"..., 43, 0) = 43
recv(3, "\1\0\0\1\2T\0\0\2\3def\22information_schema"..., 16384, 0) = 192
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\4\0\0\0\2yzs", 8, 0)          = 8
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\26\0\0\0\3*SHOW TABLES LIKE* 't1'", 26, 0) = 26
recv(3, "\1\0\0\1\1Z\0\0\2\3def\22information_schema"..., 16384, 0) = 124
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\r\0\0\0\3*SAVEPOINT sp*", 17, 0) = 17
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\34\0\0\0\3*show table status like* 't1'", 32, 0) = 32
recv(3, "\1\0\0\1\22B\0\0\2\3def\22information_schema"..., 16384, 0) = 1493
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\34\0\0\0\3*SET SQL_QUOTE_SHOW_CREATE*=1", 32, 0) = 32
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "-\0\0\0\3*SET SESSION character_set_r*"..., 49, 0) = 49
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\27\0\0\0\3*show create table* `t1`", 27, 0) = 27
recv(3, "\1\0\0\1\2\33\0\0\2\3def\0\0\0\5Table\0\f?\0@\0\0\0\375\1"..., 16384, 0) = 264
ioctl(3, FIONREAD, [0])                 = 0
send(3, "+\0\0\0\3*SET SESSION character_set_r*"..., 47, 0) = 47
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\26\0\0\0\3*show fields from `t1`*", 26, 0) = 26
recv(3, "\1\0\0\1\6F\0\0\2\3def\22information_schema"..., 16384, 0) = 532
ioctl(3, FIONREAD, [0])                 = 0
send(3, ",\0\0\0\3*SELECT* /*!40001 SQL_NO_CACH"..., 48, 0) = 48
recv(3, "\1\0\0\1\3#\0\0\2\3def\3yzs\2t1\2t1\3id1\3id1\f"..., 16384, 0) = 246
write(1, "-- MySQL dump 10.13  Distrib 5.6"..., 1546) = 1546
ioctl(3, FIONREAD, [0])                 = 0
send(3, "-\0\0\0\3*SET SESSION character_set_r*"..., 49, 0) = 49
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\n\0\0\0\3use `yzs`", 14, 0)   = 14
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\34\0\0\0\3*select* @@collation_database", 32, 0) = 32
recv(3, "\1\0\0\1\1*\0\0\2\3def\0\0\0\24@@collation_dat"..., 16384, 0) = 89
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\30\0\0\0\3SHOW TRIGGERS LIKE 't1'", 28, 0) = 28
recv(3, "\1\0\0\1\vK\0\0\2\3def\22information_schema"..., 16384, 0) = 952
ioctl(3, FIONREAD, [0])                 = 0
send(3, "+\0\0\0\3SET SESSION character_set_r"..., 47, 0) = 47
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\31\0\0\0\3*ROLLBACK TO SAVEPOINT sp*", 29, 0) = 29
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
ioctl(3, FIONREAD, [0])                 = 0
send(3, "\25\0\0\0\3*RELEASE SAVEPOINT sp*", 25, 0) = 25
recv(3, "\7\0\0\1\0\0\0\3\0\0\0", 16384, 0) = 11
write(1, "/*!40000 *ALTER TABLE `t1` ENABLE*"..., 57) = 57
fsync(1)                                = 0
send(3, "\1\0\0\0\1", 5, 0)             = 5
shutdown(3, 2 /* send and receive */)   = 0
close(3)                                = 0
munmap(0xb7e4a000, 1048576)             = 0
time(NULL)                              = 1511597961
open("/etc/localtime", O_RDONLY)        = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2819, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=2819, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f55000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\0\4\0\0\0\0"..., 4096) = 2819
close(3)                                = 0
munmap(0xb7f55000, 4096)                = 0
clock_gettime(CLOCK_REALTIME, {1511597961, 322250554}) = 0
write(1, "/*!40103 SET TIME_ZONE=@OLD_TIME"..., 471) = 471
exit_group(0) 

2、general_log

171125  0:19:21     7 Connect   root@localhost on
            /*修改session级别的sql_mode为空,避免可能有些些sql_mode值会对备份产生影响*/ 
            7 Query /*!40100 SET @@SQL_MODE='' */
            7 Query /*!40103 SET TIME_ZONE='+00:00' */
            /*强制刷新表缓存到磁盘,并关闭表。如果另一个会话已经加上表锁,那么该语句会被阻塞*/
            7 Query FLUSH /*!40101 LOCAL */ TABLES
            /*对整个实例加全局读锁,如果存在表锁将阻塞该语句*/
            7 Query FLUSH TABLES WITH READ LOCK
            /*在session级别将隔离级别设置成RR,因为开启一个一致性快照事务,需要在RR隔离级别下*/
            7 Query SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ
            /*开启一个一致性快照事务*/
            7 Query START TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */
            /*查看是否开启GTID*/
            7 Query SHOW VARIABLES LIKE 'gtid\_mode'
            /*查看当前数据的binlog pos:对应的选项是--master-data=2*/
            7 Query SHOW MASTER STATUS
            /*释放全局读锁。因为MVCC的关系,整个事务中select的都是事务开始时的值,这里可以释放锁了*/
            7 Query UNLOCK TABLES
            7 Query SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IN (SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='yzs' AND TABLE_NAME IN ('t1'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE ORDER BY LOGFILE_GROUP_NAME
            7 Query SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='yzs' AND TABLE_NAME IN ('t1')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
            7 Query SHOW VARIABLES LIKE 'ndbinfo\_version'
            7 Init DB   yzs
            7 Query SHOW TABLES LIKE 't1'
            /*在一个database开始备份前,设置一个保存点*/
            7 Query SAVEPOINT sp
            /*查看整个表的状态*/
            7 Query show table status like 't1'
            /*对每个表的每个字段加上反引号'*/
            7 Query SET SQL_QUOTE_SHOW_CREATE=1
            /*表结构的备份都是binary格式,所以需要先修改*/
            7 Query SET SESSION character_set_results = 'binary'
            /*查看整个表的定义语句*/
            7 Query show create table `t1`
            /*修改session数据结果返回字符集,备份数据需要使用数据原本的字符集*/
            7 Query SET SESSION character_set_results = 'utf8'
            /*查看整个表的字段信息*/
            7 Query show fields from `t1`
            /*查看表数据,结合show fields from t1,字段信息生成insert into语句*/
            7 Query SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1`
            7 Query SET SESSION character_set_results = 'binary'
            7 Query use `yzs`
            7 Query select @@collation_database
            7 Query SHOW TRIGGERS LIKE 't1'
            7 Query SET SESSION character_set_results = 'utf8'
            /*表备份结束,回滚到保存点sp,以释放select *语句产生的MDL锁,如果不回滚,后续整个备份过程中无法对该表执行DDL操作*/
            7 Query ROLLBACK TO SAVEPOINT sp
            /*备份完成后,释放该保存点*/
            7 Query RELEASE SAVEPOINT sp
            7 Quit  
作者:yanzongshuai 发表于2017/11/26 11:39:39 原文链接
阅读:65 评论:0 查看评论

mysqldump原理图

$
0
0

对于mysqldump过程中有哪些坑,如何避免,请参考http://geek.csdn.net/news/detail/210851这篇文章

参考:

https://www.cnblogs.com/cchust/p/5452557.html

http://geek.csdn.net/news/detail/210851

作者:yanzongshuai 发表于2017/11/26 11:44:56 原文链接
阅读:67 评论:1 查看评论

Java基础学习总结(119)——Java8 JVM与Java7 JVM比较

$
0
0
jdk 7的jvm 内存分配,请看下图:
在JDK7以及其前期的JDK版本中,JVM空间可以分成三个大区,新生代、老年代、永久代。其中新生代可以划分为三个区,Eden区,两个幸存区。
一个对象被创建以后首先被放到新生代中的Eden内
存中,如果存活期超两个Survivor之后就会被转移到老年代(Old Generation)中。
永久内存中存放着对象的方法、变量等元数据信息。通过如果永久内存不够,我们就会得到如下错误:
java.lang.OutOfMemoryError: PermGen
JDK8 HotSpot JVM 将移除永久区,使用本地内存来存储类元数据信息并称之为:元空间(Metaspace);
永久代被移除后它的JVM参数:PermSize 和 MaxPermSize 会被忽略并给出警告(如果在启用时设置了这两个参数)。
Metaspace 容量
默认情况下,类元数据只受可用的本地内存限制(容量取决于是32位或是64位操作系统的可用虚拟内存大小)。
新参数(MaxMetaspaceSize)用于限制本地内存分配给类元数据的大小。如果没有指定这个参数,元空间会在运行时根据需要动态调整。
Metaspace 垃圾回收
对于僵死的类及类加载器的垃圾回收将在元数据使用达到“MaxMetaspaceSize”参数的设定值时进行。
适时地监控和调整元空间对于减小垃圾回收频率和减少延时是很有必要的。持续的元空间垃圾回收说明,可能存在类、类加载器导致的内存泄漏或是大小设置不合适。
作者:u012562943 发表于2017/11/26 11:45:24 原文链接
阅读:54 评论:0 查看评论
Viewing all 35570 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>