Git命令-rebase和merge的区别

 编写: zhangyue
 时间: 2017-02-23
 说明: git的一些命令使用

1 merge和rebase的区别
merge:合并两个分支,根据两个分支的同一个起点,同相同起点开始,把两个分支的修改进行合并,之后生成生成一个commit。
rebase:合并两个分支,抽取出当前的分支的commit, 之后合并目标分支commit,再将置顶抽出的commit重新合并入当前分支的commit

2 两者合并的示意图

merge:
    master: master:1 -- master:2
                                 |
    dev   :     |-- dev:1 --- dev:2 执行git merge master

    dev的log:
    dev   : master:1 --> dev:1 --> dev:2 --> master:2 --> merge commit

rebase:
    master: master:1 -- master:2
                                 |
    dev   :     |-- dev:1 -- dev:2 执行git rebase master

    dev的log:
    dev   : master:1 --> master:2 --> dev:1 --> dev:2

3 在发生冲突时两者的不同处理方式
merge: 有冲突->停止合并->手动解决后->再次merge
rebase:有冲突->暂停操作->手动解决,
git rebase --continue继续(--skip跳过/--abort 停止rebase操作)
4 rebase对commit的操作

git rebase -i HEAD~3 对所做的提交进行修改
    # Commands:
    # p, pick = use commit 不做任何修改
    # r, reword = use commit, but edit the commit message 只修改提交注释信息
    # e, edit = use commit, but stop for amending 
        修改提交的文件,做增补提交
    # s, squash = use commit, but meld into previous commit
        将该条提交合并到上一条提交,提交注释也一并合并
    # f, fixup = like "squash", but discard this commit's log message
        将该条提交合并到上一条提交,废弃该条提交的注释
    # x, exec = run command (the rest of the line) using shell
    # d, drop = remove commit
        删除某次提交

5 其他的一些功能命令

    git cherry-pick  取某一个分支中的一个或几个commit(s)来进行合并
    git stash [pop/apply /drop/save] 将改动存入暂存区[弹出暂存区记录/恢复一个暂存区内记录]
    git blame 文件逐行追溯
    git clean 清除工作区未跟踪文件

针对存在Ajax的页面状态的处理

编  写:    zhangyue
日  期:    2017.1.6
说  明:    针对ajax页面的一些前进后退的处理

一 Ajax页面的特殊性
存在Ajax加载数据的页面,其url不会自动发生改变,除非通过手动更改url。此时,导致了当页面发生ajax加载的时候,页面url状态不会发生改变,后退页面时,会直接返回原始状态。

针对单页面应用,如果在A页面进行相关操作,然后跳转到B页面,此时再从B页面返回到A页面,A页面会重新加载,不会保持A页面之前进行的操作。

二 解决办法的过程
2.1 location.hash
通过location.hash调整地址栏的地址,使得浏览器里边的“前进”、“后退”按钮能正常使用,。然后再根据hash值的不同来显示不同的面板.
http://shopdev.ci123.com/svn/zydev/xinyi/category/itemlist/#sort=price&order=asc
#代表网页中的一个位置。其右面的字符,就是该位置的标识符

为网页位置指定标识符,有两个方法。一是使用锚点,比如,二是使用id属性。

#是用来指导浏览器动作的,对服务器端完全无用。所以,HTTP请求中不包括#。第一个#后面出现的任何字符,都会被浏览器解读为位置标识符。这意味着,这些字符都不会被发送到服务器端,改变#后的部分,不会重新加载网页。

每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"按钮,就可以回到上一个位置。这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。

window.location.hash这个属性可读可写。读取时,可以用来判断网页状态是否改变;写入时,则会在不重载网页的前提下,创造一条访问历史记录。
window.location.hash=value;

2.2 localStorage,SessionStorage
a.存储客户端临时信息的对象

b.localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。

c.sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。

d.使用:

键值对方式储存值:
    localStorage.key = v
    localStorage['key'] = v
    localStorage.setItem("key",v)
取值:
    localStorage.key
    localStorage.getItem("key");
清除:
    localStorage.remove("key");
    localStorage.clear();

通过localStorage或sessionStorage存储关键字段,当重新加载该页面的时候,检测,如果存在该字段,通过字段拼接,重新同过ajax请求加载数据;或者直接存储当前页面的某个元素的所有内容,重新加载该页面的时候,检测,如果存在值,则直接填充,无需再次去通过ajax请求


三 存在的问题

1 如果改变location.hash,那么会导致history增多,返回时,需要一步一步回退,不能直接返回原始界面,用户体验差。
2 可以考虑使用history的Api:

history.pushstate();//增加当前url
history.replacestate();//替换当前url

进一步的可以参考:HTML5 操纵浏览器的历史记录history
3 后续完善版,可以参考: 移动端列表页操作优化

Js关于this和事件冒泡的一些总结

整  理:zhangyue
日  期:2017.1.6
说  明:关于js的this和事件冒泡等的部分总结

一 Js中this和Jquery中$(this)的区别
1.1 两者是不同的对象
$(this) :jquery对象
this:dom对象

1.2 dom对象和jquery对象的转换:

$(this)[0] == this; 

var $argument=$("#argument"); //jquery对象
var argument = $argument[0]; //dom对象 也可写成 var argument=$argument.get(0);

var argument=document.getElementById("argument"); //dom对象
var $argument = $(argument); //转换成jquery对象

二 Js事件冒泡和事件委托
事件冒泡:子级元素的某个事件被触发,它的上级元素的该事件也被递归执行
事件委托:将子级元素的事件绑定在父级元素上;
对于动态生成的Dom元素,其事件绑定有两种方式:第一种,是在dom元素后生成的地方添加相应的绑定事件;第二种,将事件绑定在已经存在的父元素dom节点上。如果一开始就对该元素进行绑定事件,而该元素动态添加后,是不能够响应改绑定事件的。




//js 部分
createSonDom();

//第一种方式
$("#son").click(function(){
    alert('son');
});

//第二种方式 事件委托
$("#parent").on('click', '#son', function() {
    alert('son');
});

function createSonDom()
{
    var tmp = [];
    tmp.push('
'); $("#parent").append(tmp); //第三种方式 $("#son").click(function(){ alert('son'); }); } 第一种方式对于son元素无法响应,第二种可行,第三种可行。第三种存在缺陷,可能会导致事件多次响应

三 Js中this和event对比
js中事件是会冒泡的,所以this是可以变化的,
event.target不会变化,它永远是直接接受事件的目标DOM元素;

$(this)和event.currentTarget永远指向监听该事件发生的DOM元素;
event.target则是那个被点击的DOM元素.

四 使用this的冒泡问题解决
4.1 第一种:事件委托,不把事件绑定在自身元素上
4.2 off(),解除绑定事件,之后在进行绑定

$(this).off('click').on('click', function(){
    alert('off');
});

4.2 使用event.stopPropagation()
能阻止父元素的click事件函数执行,但不阻止当前元素同时绑定的其它click事件函数执行
ps:event.preventDefault() 不组织冒泡事件,阻止默认行为

$('#son').on('click', function(event){
    $(event.target).stopPropagation();//阻止事件冒泡
});

01背包问题基础

编 写: zhangyue
时 间: 2016-12-27
说 明: 利用背包问题解决红包使用问题

一 01背包问题

    01背包问题是指在一个容量大小固定为M的背包中,装入体积和价值不同的宝石,怎么选择才能在背包中得到最大的价值。

二 动态规划

动态规划是指
        通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以一种循环的方式去解决。
        通常基于一个递推公式和一个或多个初始状态,当前子问题的解由上一个子问题的解推出。
        有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最        好的活动效果。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展,当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线
        
        状态转移方程:
            d(N,M) = max(d(N-1,M), d(N-1, M-weight(i)) + value(i));
            d(N,M) 有容量为M的背包,有N个宝石
            d(N-1,M) 当前的宝石不放入背包,所能获取的最大价值
            d(N-1, M-weight(i)) + value(i) 当前宝石放入背包,所能够获取的最大价值

三 代码

function getResult($bagItems, $bagSize) {
        var result = array();
        //生成状态数组
        foreach ($i = 0; $i < $bagSize; $i ++) {
            foreach ($j = 0; $j < count($bagItems); $j ++) {
                if ($bagItems[$j]['weight'] > $i) {
                    //当前重量大于当前背包总重量
                    if (j != 0) {
                        $result[$j][$i] = $result[$j-1][$i];
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = 0;
                    }
                } else {
                    //当前重量小于背包,可以放入背包
                    if ($j != 0 ) {
                        $tmp_value = $result[$j-1][$i - $bagItems[$j]['weight']] + $bagItems[$j]['weight'];
                        $result[$j][$i] = max($result[$j-1][$i], $tmp_value);
                    } else {
                        //第一个元素 $j-1不存在,不存在前一个状态
                        $result[$j][$i] = $bagItems[$j]['weight'];
                    }
                }
            }
        }

        //根据得到的状态得到所选的数组
        $return  = array();//存储放回的组合
        $cur_size = $bagSize;//当前红包容量
        for ($n = count($bagItems); $n >= 0 ; $n--) {
            if ($cur_size == 0) {
                break;
            } 

            if ($n == 0 && $bagItems[$n]['weight'] < $cur_size) {
                $return[] = $bagItems[$n]['id'];
                break;
            }

            if ($bagItems[$n][$cur_size] - $bagItems[$n-1][$cur_size - $bagItems[$n]['weight']] == $bagItems[$n]['weight']) {
                //判断当前的这个商品是不是在最优解里,如果不在则不放入
                $return[] = $bagItems[$n]['id'];
                $cur_size = $cur_size - $bagItems[$n]['weight'];
            }
        }

        //得到结果
        return $return;

    }

四 递推表格

函数得到的递推表格和最终最优结果:
体积 价值 0 1 2 3 4 5 6 7 8 9 10 11
4 4 0 0 0 0 4 4 4 4 4 4 4 4
5 5 0 0 0 0 4 5 5 5 5 9 9 9
6 6 0 0 0 0 4 5 6 6 6 9 10 11
解释: 1 表格是从上到下,即4-6,从左到右,即0-11生成的 2 第一行的意思:代表在0-11的背包容量下,只有一个体积为4价值为4的宝石时,所能获得最大容量 3 第二行的意思:代表在0-11的背包容量下,有一个体积为4价值为4和体积为5价值为5的两块宝石时,所能获得最大容量 4 第三行的意思:代表在0-11的背包容量下,有一个体积为4价值为4,体积为5价值为5,体积为6价值为6的三块宝石时,所能获得最大容量 5 最终结果:[6,11] = 11 这个最优解。

五 红包问题

使用红包时,只需要将价值和体积都类比于红包的金额即可,这样可以选出最后得到的红包使用组合。
存在问题:
    1 红包会涉及小数的问题,红包现在只保留两位小数,最简单的方法是给红包*100,这样会增加递推数组的大小,增加空间复杂度
    2 红包还存在过期时间,可考虑如何加上过期时间这一条件
    3 由于红包价格和体积是同一个值,可考虑简化算法

sql执行顺序

基础版,未考虑性能优化而做出的改变
sql执行顺序
(1)from
(2) on
(3) join
(4) where
(5)group by
(6) avg,sum....
(7)having
(8) select
(9) distinct
(10) order by

整个流程

  • 1 from:
  • from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表table_1

    Table A Table B
    ID ID
    1 3
    2 4
    笛卡尔乘积后:
    AID BID
    1 3
    1 4
    2 3
    2 4

  • 2 on筛选器:
  • on中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 table_2

  • 3 join:
  • 根据join语句中多个表之间字段的联系,生成一个新的表table_3
    几种用法:
    INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录。
    LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
    RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。

    Table A Table B
    ID Name ID Name
    1 aa 1 bb
    2 bb 2 cc
    3 cc 3 dd
    4 dd 4 ee

    inner join: select * from A inner join B on A.name = B.name;

    ID Name ID Name
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd

    left join: select * from A left join B on A.name = B.name;

    ID Name ID Name
    1 aa Null Null
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd

    right join: select * from A right join B on A.name = B.name;

    ID Name ID Name
    2 bb 1 bb
    3 cc 2 cc
    4 dd 3 dd
    Null Null 4 ee

  • 4 重复1-3步骤
  • from子句中的表数目多余两个表,那么就将table_3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 table_3。

  • 5 where筛选器
  • 上一步生产的虚拟表引用where筛选器,生成虚拟表table_4
    在含有join操作时:on和where的一点区别:
    现有两张表A和B:都只有一个字段ID,A数据有4,B的数据有3个

    Table A Table B
    ID ID
    1 1
    2 2
    3 3
    4

    1 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID WHERE B.ID<3

    AID BID
    1 1
    2 2

    2 select A.ID as AID, B.ID as BID from A left join B ON A.ID = B.ID AND B.ID<3

    AID BID
    1 1
    2 2
    3 Null
    4 Null

    原因: 优先级: on > left join > where
    第一条语句的顺序:
    a)执行leftjoin A left join B结果:
    AID BID
    1 1
    2 2
    3 Null
    4 Null

    b)执行where B.ID < 2结果: AID BID 1 1 2 2 第二条语句的顺序: a)先执行 A.ID = B.ID and B.ID < 2,得到结果 ID 1 2 b)再执行left join,得到结果 AID BID 1 1 2 2 3 Null 4 Null

  • 6 group by
  • group by 子句将中的唯一的值组合成为一组,得到虚拟表table_5。
    根据“By”指定的规则对数据进行分组,所谓的分组就是将一个“数据集”划分成若干个“小区域”,然后针对若干个“小区域”进行数据处理。
    Table A
    ID Level
    1 A
    2 A
    3 B
    4 B
    5 B
    6 B
    7 C

    Select count(ID) as Num ,Level from table group by Level

    table
    Num Level
    2 A
    4 B
    1 C

  • 7 having
  • 应用having筛选器,生成table_6。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。
    如在6中针对筛选的结果需要进行Num>2的筛选:只能通过having,而不能通过where
    Where的执行在group by之前,不能够针对group 不要生成的table进行操作,因此,需要对group by后生成的table进行操作可以使用having对数据进行筛选

  • 8 select
  • 处理select子句。将table_6中的在select中出现的列筛选出来。生成table_7
    注意:由此可以看出,select是在from之后被执行的,所以在select中使用的别名在where中是不可以被使用的。

  • 9 distinct
  • 应用distinct子句,table_7中移除相同的行,生成table_8。事实上如果应用了group by子句那么distinct是多余的,
    原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。

  • 10 order by
  • 应用order by子句。按照order by 的条件去排序table_8

  • 11 返回结果