Perla

Perla 查看完整档案

上海编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑

Maybe, that's not your limit。
个人微信:byf_6579069
淘宝店铺:https://shop566459201.taobao....

个人动态

Perla 收藏了文章 · 9月2日

【网页特效】11 个文本输入和 6 个按钮操作 特效库

作者:lindelof
译者:前端小智
来源:github
点赞再看,微信搜索 【大迁世界】 关注这个没有大厂背景,但有着一股向上积极心态人。本文 GitHubhttps://github.com/qq44924588... 上已经收录,文章的已分类,也整理了很多我的文档,和教程资料。

大家都说简历没项目写,我就帮大家找了一个项目,还附赠【搭建教程】

文本输入特效

1.power-mode-input

PowerModeInput 可以让你的文本输入框更引人注目。

地址:https://github.com/lindelof/power-mode-input

2.TextInputEffects

简单的样式和效果,可增强文本输入交互。

地址:https://github.com/codrops/TextInputEffects

3.typewriterjs

一个简单而强大的原生javascript插件,具有很酷的打字机效果。

地址:https://github.com/tameemsafi/typewriterjs

4.t.js

轻量级 $.Hypertext.Typewriter

地址: https://github.com/mntn-dev/t.js

5.shuffle-text

ShuffleText 是一款纯js文字洗牌式切换特效插件。该插件在鼠标滑过指定的文本时,文字会不停的逐个进行翻转,类似洗牌效果,非常炫酷。

地址: https://github.com/ics-ikeda/shuffle-text

6.react-typewriter

适用于 react 的打字机的效果

地址:https://github.com/ianbjorndilling/react-typewriter

7.t-writer.js

T-Writer.js 用于实现原生打字机效果,没有任何依赖。

地址: https://github.com/ChrisCavs/t-writer.js

8.malarkey

模拟在DOM元素上的打字机效果。

地址:https://github.com/yuanqing/malarkey

  • 友好,灵活的API,提供精细的控制
  • 选项到重复该效果的限制。
  • 用于对自定义元素属性应用效果的选项。
  • 允许暂停和恢复顺序 on-the-fly
  • 广泛的测试,带有 100%覆盖范围。
  • 无相关性,超轻量,仅 1.5 缩小,或者 0.8 KB缩小和压缩

9.tinytyper

TinyTyper 一个微小的库用于在一段指定的文本元素上创建打字效果。

地址:https://github.com/lourenc/tinytyper

https://klxxcdn.oss-cn-hangzhou.aliyuncs.com/histudy/hrm/media/66/8MTkbe9Crg.gif

10.jquery.typer

typer.js插件是一个非常有意思的jQuery插件,实现一个一个字输出,类似打字的效果。typer.js是一个比较小的插件,依赖于jQuery。typer.js使用起来也比较方便,允许设置打字时间间隔,循环输出,清除打字效果时间等。

11. Phaser-typewriter

Phaser.io Javascript库的打字机效果包装器。

地址: https://github.com/netgfx/Phaser-typewriter


按钮操作特效

1.ElasticProgress

ElasticProgress 可以创建一个有弹力效果的进度条。

地址: https://github.com/codrops/ElasticProgress

https://klxxcdn.oss-cn-hangzhou.aliyuncs.com/histudy/hrm/media/66/1sfasfsafasf564safsaf6saf1as.gif

2. vue-particle-effect-buttons

爆发粒子特效按钮组件。

地址: https://github.com/dreambo8563/vue-particle-effect-buttons

3.nativescript-shine-button

NativeScript插件,可为按钮添加发光效果。

地址:https://github.com/hamdiwanis/nativescript-shine-button

4.react-parallax-button

让按钮有一个水平视差效果。

地址: https://github.com/venits/react-parallax-button

5.RippleButton

具有Material Theme波纹效果的按钮。

地址: https://github.com/mig82/RippleButton

6.css-ripple-effect

css-ripple-effect 是一款使用纯CSS3制作的炫酷扁平风格按钮点击波特效。该效果是仿照Android系统的Material design风格点击波来制作的。

地址:https://github.com/mladenplavsic/css-ripple-effect

人才们的 【三连】 就是小智不断分享的最大动力,如果本篇博客有任何错误和建议,欢迎人才们留言,最后,谢谢大家的观看。


代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://github.com/lindelof/a...

交流

文章每周持续更新,可以微信搜索 【大迁世界 】 第一时间阅读,回复 【福利】 有多份前端视频等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,欢迎Star。

查看原文

Perla 回答了问题 · 8月26日

用div id写了个input图片上传,样式与判断写在了js里,通过js渲染,要存到数据库中该如何获取上传的图片?

1.首先你的确认你是否想服务器发送了上传文件的请求(一般是form或者formdata形式)
2.如果确定传了,直接在服务器获取$_FILES变量就可以获得上传文件的信息,然后用move_uploaded_file保存起来就可以了

关注 3 回答 2

Perla 回答了问题 · 8月26日

php如何实现这样的特殊数据操作

绝对的平均应该是不可能的,可以相对平均,主要取决于你的展示规则,比如在前面更容易展示或者中间更容易展示。

假设你用的redis,那么你可以用有序集合zset来实现,以信息的id为名字,点击量为score,每次在展示之前按照从小到大排序,分别按照展示程度的从高到低来展示,这样可以尽量平均的展示这些信息了

关注 3 回答 2

Perla 收藏了文章 · 8月26日

30 多个有内味道且笑死的人代码注释

作者:xor
译者:前端小智
来源:medium
点赞再看,微信搜索 【大迁世界】 关注这个没有大厂背景,但有着一股向上积极心态人。本文 GitHubhttps://github.com/qq44924588... 上已经收录,文章的已分类,也整理了很多我的文档,和教程资料。

大家都说简历没项目写,我就帮大家找了一个项目,还附赠【搭建教程】

代码注释,有些人说它太丑,也有些人说它是标准和良好的做法。在本文中, 列出了一些在编程中遇到的有趣的代码注释。

注释 1

// Weed Effect ! 

这是杂草效应的意思?不是很懂,有谁知道,可以留言一下。

注释 2

/**** 原文 *****/
//The following code was written by <developer name>.
// Unless it doesn't work, then I have no idea who wrote it.

/**** 自译 *****/
// 以下代码是由<developer name>编写的。
// 除非它不起作用,否则我不知道是谁写的。

注释 3

/**** 原文 *****/
// Ad Index scheming and plotting - Those with
//    heart conditions are advised to not continue

/**** 自译 *****/
// 广告索引的设计和绘图模块
// 建议不要深入阅读,否则容得得心脏病

注释 4

/**** 原文 *****/
// nobody read comments!

/**** 自译 *****/
// 没人会读的注释

注释 5

/**** 原文 *****/
i++; // increment i

/**** 自译 *****/
i++; // 自增 i

注释 6

/**** 原文 *****/
// Magic. Do not touch.


/**** 自译 *****/
// 这里已经结界,不要碰.

注释 7

/**** 原文 *****/
// sometimes I believe compiler ignores all my comments

/**** 自译 *****/
// 有时我相信编译器会忽略我的所有注释

注释 8

/**** 原文 *****/
// I am not responsible of this code.
// They made me write it, against my will.

/**** 自译 *****/
// 我对此代码不承担任何责任。
// 是他们强迫我让我写的,这已违背了我的意愿。

注释 9

/**** 原文 *****/
// 
// Dear maintainer:
// 
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
// 
// total_hours_wasted_here = 42

/**** 自译 *****/
// 亲爱的程序媛
// 
// 一旦你尝试“优化”此代码,并意识到这是一个可怕的错误,
// 请增加以下计数器,以警告下一个人
//  total_hours_wasted_here = 42

注释 10

/**** 原文 *****/

# To understand recursion, see the bottom of this file
At the bottom of the file
# To understand recursion, see the top of this file


/**** 自译 *****/

# 要了解递归,请参见此文件的底部

在文件的底部

# 要了解递归,请参见此文件的顶部

注释 11

/**** 原文 *****/

// I will give you two of my seventy-two virgins if you can fix this.

/**** 自译 *****/
// 如果你能解决这个问题,我就把我七十二个处女中的两个给你。

注释 12

/**** 原文 *****/
//Dear future me. Please forgive me. 
//I can't even begin to express how sorry I am.


/**** 自译 *****/
// 你好,未来帅气的我,请原谅我。
// 我现在无法表达我的歉意,因为我写下了这段代码。

注释 13

/**** 原文 *****/
//private instance variable for storing age
public static int age;

/**** 自译 *****/
// 用于存储年龄的私有实例变量
public static int age;

注释 14

/**** 原文 *****/
const int TEN=10; // s if the value of 10 will fluctuate...


/**** 自译 *****/
const int TEN=10; // 10 是会改变的值

注释 15

/**** 原文 *****/

/* You are not meant to understand this */


/**** 自译 *****/

/* 你不应该理解这一点 */

注释 16

/**** 原文 *****/
/*
* TODO: Remove this function

function remove($customer_id)
    {
        $this->Customer->remove($id);
    }

*/


/**** 自译 *****/
/*
* TODO: 删除函数

function remove($customer_id)
    {
        $this->Customer->remove($id);
    }

*/

注释 17

/**** 原文 *****/
//When I wrote this, only God and I understood what I was doing
//Now, God only knows


/**** 自译 *****/

// 当我写这段代码,只有上帝和我知道这是在做什么
...

// 现在,只有上帝知道这段代码在做什么

注释 18

/**** 原文 *****/

// drunk, fix later

/**** 自译 *****/

// 喝醉了,待会解决

注释 19

/**** 原文 *****/

// I'm sorry.

/**** 自译 *****/

// 我很抱歉

注释 20

/**** 原文 *****/

// I am not responsible of this code.

/**** 自译 *****/

// 我对此代码不承担任何责任。

注释 21

/**** 原文 *****/
// I have to find a better job

/**** 自译 *****/

// 我必须找到更好的工作

注释 22

/**** 原文 *****/

// Joe is sorry
A few hundred lines later...
// Harry is sorry too

/**** 自译 *****/

// 老五抱歉了

写了几百行代码之后...

// 小五对不住了

注释 23

/**** 原文 *****/
# Christmas tree initializer  
    toConnect = []  
    toRead =   [  ]  
    toWrite = [    ]   
    primes = [      ]  
    responses = {}  
    remaining = {}
    
    
/**** 自译 *****/

# 圣诞树初始化器
    toConnect = []  
    toRead =   [  ]  
    toWrite = [    ]   
    primes = [      ]  
    responses = {}  
    remaining = {} 

注释 24

/**** 原文 *****/

Catch (Exception e) {
 // who cares?
}

/**** 自译 *****/

Catch (Exception e) {
 // 管它呢?
}

注释 25

/**** 原文 *****/

// IE7 update. this is still bad code, but IE8 is probably a long way off :)

/**** 自译 *****/

IE7更新,这仍然是错误的代码,看来 IE8 还有很长的路要走:)

大家都说简历没项目写,我就帮大家找了一个项目,还附赠【搭建教程】

注释 26

/**** 原文 *****/

// If this code works, it was written by Paul DiLascia. If not, I don't know

/**** 自译 *****/

// 如果这个代码有效的话,它就是由 前端小智 编写的。如果出错了,我也不知道是谁写的。

注释 27

/**** 原文 *****/

// This comment is self explanatory.

/**** 自译 *****/

// 这个注释不言自明。

注释 28

/**** 原文 *****/

int main(void)
/* Program starts here */

/**** 自译 *****/

int main(void)
/* 程序从这里开始 */

注释 29

/**** 原文 *****/

// I am not sure if we need this, but too scared to delete.

/**** 自译 *****/

// 我不确定我们是否需要这个,但又害怕删除

注释 30

/**** 原文 *****/
/**
 * Always returns true.
 */
public boolean isAvailable() {
    return false;
}


/**** 自译 *****/
/**
 * 总是返回 true.
 */
public boolean isAvailable() {
    return false;
}

注释 31

/**** 原文 *****/

// Autogenerated, do not edit. All changes will be undone.

/**** 自译 *****/

// 自动生成,不要编辑。所有的更改都将被撤销。

注释 32

/**** 原文 *****/

// hack for ie browser (assuming that ie is a browser)


/**** 自译 *****/
// 破解ie浏览器(假设ie是一个浏览器)

注释 33

/**** 原文 *****/

/////////////////////////////////////// this is a well commented line

/**** 自译 *****/

/////////////////////////////////////// 这是一个很好的注释

注释 34

/**** 原文 *****/

// Mr. Compiler, please do not read this.

/**** 自译 *****/

// 编译先生,请不要读取这个

注释 35

/**** 原文 *****/

// All bugs added by David S. Miller

/**** 自译 *****/

// 所有 bug 都是由 老王 添加的

注释 36

/**** 原文 *****/

//If you're reading this, then my program is probably a success


/**** 自译 *****/

// 如果你现在在认真详细的阅读这段代码,那么写的这段代码应该是没有问题的。

注释 37

/**** 原文 *****/

Catch (Exception e) {
    //eat it
}

/**** 自译 *****/

Catch (Exception e) {
    // 吃掉它
}

注释 38

/**** 原文 *****/

//todo: never to be implemented

/**** 自译 *****/

// todo:永远不会执行

注释 39

/**** 原文 *****/

// simply copied from another code

/**** 自译 *****/

// 别问,问我也是从另一个代码拷贝过来的

注释 40

/**** 原文 *****/

//Please comment on your source code

/**** 自译 *****/

// 拜托啦,请把你写的代码注释一下

注释 41

/**** 原文 *****/
# as you can see: I comment the code!


/**** 自译 *****/

# 如你所见:我注释了代码!

注释 42

/**** 原文 *****/

// if i ever see this again i'm going to start bringing guns to work

/**** 自译 *****/

// 如果我再看到这个,我会带枪去工作

注释 43

def format_ticket_content(text, recursive = true)
  if text.is_a?(TicketNote)
    note = text
    text = note.content
  else
    note = nil
  end

  ## Safety pig has arrived!
  text = h(text)
  ##                               _
  ##  _._ _..._ .-',     _.._(`))
  ## '-. `     '  /-._.-'    ',/
  ##    )         \            '.
  ##   / _    _    |             \
  ##  |  a    a    /              |
  ##  \   .-.                     ;  
  ##   '-('' ).-'       ,'       ;
  ##      '-;           |      .'
  ##         \           \    /
  ##         | 7  .__  _.-\   \
  ##         | |  |  ``/  /`  /
  ##        /,_|  |   /,_/   /
  ##           /,_/      '`-'
  ##

大家都说简历没项目写,我就帮大家找了一个项目,还附赠【搭建教程】

注释 44

/**** 原文 *****/

long long ago; /* in a galaxy far far away */


/**** 自译 *****/

long long ago; /* 在遥远的星系中 */

注释 45

/**** 原文 *****/
try {

} finally { // should never happen 

}

/**** 自译 *****/
try {

} finally { // 这里永远不会被执行

}

注释 46

/**** 原文 *****/

/* Ah ah ah! You'll never understand why this one works. */


/**** 自译 *****/

// 啊啊啊!你永远都不会明白为什么这个方法有效。

注释 47

/**** 原文 *****/
// this formula is right, work out the math yourself if you don't believe me

/**** 自译 *****/

// 这个公式是正确的,如果你不相信我,自己动手算一下

注释 48

/**** 原文 *****/

// This was clearly written under duress

/**** 自译 *****/

// 这显然是在胁迫下写的

注释 49

 
                                   .='  ' .`/,/!(=)Zm.           
                     .._,,._..  ,-`- `,\ ` -` -`\\7//WW.         
                ,v=~/.-,-\- -!|V-s.)iT-|s|\-.'   `///mK%.        
              v!`i!-.e]-g`bT/i(/[=.Z/m)K(YNYi..   /-]i44M.       
            v`/,`|v]-DvLcfZ/eV/iDLN\D/ZK@%8W[Z..   `/d!Z8m       
           //,c\(2(X/NYNY8]ZZ/bZd\()/\7WY%WKKW)   -'|(][%4.      
         ,\\i\c(e)WX@WKKZKDKWMZ8(b5/ZK8]Z7%ffVM,   -.Y!bNMi      
         /-iit5N)KWG%%8%%%%W8%ZWM(8YZvD)XN(@.  [   \]!/GXW[      
        / ))G8\NMN%W%%%%%%%%%%8KK@WZKYK*ZG5KMi,-   vi[NZGM[      
       i\!(44Y8K%8%%%**~YZYZ@%%%%%4KWZ/PKN)ZDZ7   c=//WZK%!      
      ,\v\YtMZW8W%%f`,`.t/bNZZK%%W%%ZXb*K(K5DZ   -c\\/KM48       
      -|c5PbM4DDW%f  v./c\[tMY8W%PMW%D@KW)Gbf   -/(=ZZKM8[       
      2(N8YXWK85@K   -'c|K4/KKK%@  V%@@WD8e~  .//ct)8ZK%8`       
      =)b%]Nd)@KM[  !'\cG!iWYK%%|   !M@KZf    -c\))ZDKW%`        
      YYKWZGNM4/Pb  '-VscP4]b@W%     'Mf`   -L\///KM(%W!         
      !KKW4ZK/W7)Z. '/cttbY)DKW%     -`  .',\v)K(5KW%%f          
      'W)KWKZZg)Z2/,!/L(-DYYb54%  ,,`, -\-/v(((KK5WW%f           
       \M4NDDKZZ(e!/\7vNTtZd)8\Mi!\-,-/i-v((tKNGN%W%%            
       'M8M88(Zd))///((|D\tDY\\KK-`/-i(=)KtNNN@W%%%@%[           
        !8%@KW5KKN4///s(\Pd!ROBY8/=2(/4ZdzKD%K%%%M8@%%           
         '%%%W%dGNtPK(c\/2\[Z(ttNYZ2NZW8W8K%%%%YKM%M%%.          
           *%%W%GW5@/%!e]_tZdY()v)ZXMZW%W%%%*5Y]K%ZK%8[          
            '*%%%%8%8WK\)[/ZmZ/Zi]!/M%%%%@f\ \Y/NNMK%%!          
              'VM%%%%W%WN5Z/Gt5/b)((cV@f`  - |cZbMKW%%|          
                 'V*M%%%WZ/ZG\t5((+)L\'-,,/  -)X(NWW%%           
                      `~`MZ/DZGNZG5(((\,    ,t\\Z)KW%@           
                         'M8K%8GN8\5(5///]i!v\K)85W%%f           
                           YWWKKKKWZ8G54X/GGMeK@WM8%@            
                            !M8%8%48WG@KWYbW%WWW%%%@             
                              VM%WKWK%8K%%8WWWW%%%@`             
                                ~*%%%%%%W%%%%%%%@~               
                                   ~*MM%%%%%%@f`                 
                                       '''''

注释 50

/************************************************************
        *                                                           *
        *  .=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-.       *
        *   |                     ______                     |      *
        *   |                  .-"      "-.                  |      *
        *   |                 /            \                 |      *
        *   |     _          |              |          _     |      *
        *   |    ( \         |,  .-.  .-.  ,|         / )    |      *
        *   |     > "=._     | )(__/  \__)( |     _.=" <     |      *
        *   |    (_/"=._"=._ |/     /\     \| _.="_.="\_)    |      *
        *   |           "=._"(_     ^^     _)"_.="           |      *
        *   |               "=\__|IIIIII|__/="               |      *
        *   |              _.="| \IIIIII/ |"=._              |      *
        *   |    _     _.="_.="\          /"=._"=._     _    |      *
        *   |   ( \_.="_.="     `--------`     "=._"=._/ )   |      *
        *   |    > _.="                            "=._ <    |      *
        *   |   (_/                                    \_)   |      *
        *   |                                                |      *
        *   '-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-='      *
        *                                                           *
        *      LASCIATE OGNI SPERANZA, VOI CH'ENTRATE               *              LEAVE EVERY HOPE, YOU COME IN
        *************************************************************/

注释 51

/**** 原文 *****/
// This was clearly written under duress

/**** 自译 *****/
// 如果将来我读到这篇文章,我会回到过去并自杀。

注释 52

/**** 原文 *****/
// This was clearly written under duress

/**** 自译 *****/
// 乱七八糟的 SQL语句,但它有效,所以请不要触摸它

注释 53

//        .==.        .==.          
//       //`^\\      //^`\\         
//      // ^ ^\(\__/)/^ ^^\\        
//     //^ ^^ ^/6  6\ ^^ ^ \\       
//    //^ ^^ ^/( .. )\^ ^ ^ \\      
//   // ^^ ^/\| v""v |/\^ ^ ^\\     
//  // ^^/\/ /  `~~`  \ \/\^ ^\\    
//  -----------------------------
/// 这是条龙

注释54

/**** 原文 *****/
// I from the future read this I'll back in time and kill myself.

/**** 自译 *****/
// 这是垃圾代码,但现在是凌晨3点,我需要把它修好。

注释55

// 我不确定我做了什么

注释56

如果你想被解雇,请将其删除

注释 57

// 切勿动以下代码,否则我会踢你的 PP

编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://medium.com/javascript...

交流

文章每周持续更新,可以微信搜索 【大迁世界 】 第一时间阅读,回复 【福利】 有多份前端视频等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 已经收录,欢迎Star。

查看原文

Perla 赞了回答 · 7月2日

解决php框架的ORM 是否能屏蔽MySQL数据库高低版本之间的语法问题?

也要看框架的版本是新是旧吧

关注 5 回答 4

Perla 赞了回答 · 2019-12-24

swoole 进程杀不掉,杀死又起一个新的进程,怎么彻底杀死?

Kill主进程。

关注 4 回答 2

Perla 收藏了文章 · 2019-11-27

🇨🇳最全最新中国【省、市、区县、乡镇街道】json,csv,sql数据

中华人民共和国行政区划代码

中华人民共和国行政区划(五级):省级、地级、县级、乡级和村级。

来自中华人民共和国民政部,用于查询中国省,市和区数据的网站。

Github:https://github.com/uiwjs/province-city-china

数据更新 Diff

安装

npm install province-city-china --save-dev

使用

const { data, province, city, area, town } = require('province-city-china/data');
  • data - 总数据(省/地/县/乡)
  • province - 省级(省/直辖市/特别行政区)
  • city - 地级(城市)
  • area - 县级(区县)
  • town - 乡级(乡镇/街)

所有数据

const provinces = require('province-city-china/dist/data.json');
// provinces 输出 ===>
[
  {"code":"110000","name":"北京市","province":"11","city":0,"area":0,"town":0},
  {"code":"110101","name":"东城区","province":"11","city":"01","area":"01","town":0},
  {"code":"110102","name":"西城区","province":"11","city":"01","area":"02","town":0},
  {"code":"110105","name":"朝阳区","province":"11","city":"01","area":"05","town":0},
  ....
]

规则:

  • province - 省级(省/直辖市/特别行政区) - city=0, area=0, town=0
  • city - 地级(城市) - area=0, town=0
  • area - 县级(区县) - town=0 其它不为 0
  • town - 乡级(乡镇/街) - 所有值不为 0
province 第一位表示:华北区1,东北区2,华东区3,中南区4,西南区5,西北区6。 如 湖北省 -> 424 开头,表示为 中南区

获取城市数据

const city = require('province-city-china/dist/city.json');
// city 输出 ===>
[
  {"code":"01","name":"石家庄市","province":"13"},
  {"code":"02","name":"唐山市","province":"13"},
  {"code":"03","name":"秦皇岛市","province":"13"},
  {"code":"04","name":"邯郸市","province":"13"},
  {"code":"05","name":"邢台市","province":"13"},
  ....
]

说明:

  • code - 城市代码
  • name - 城市名称
  • province - 省/直辖市/特别行政区代码

更多数据

可以通过 UNPKG 下载使用 CDN 资源: https://unpkg.com/province-ci...
文件列表JSONCSVSQLCDN
总数据(省/地/县/乡)data.jsondata.csvdata.sqldata.sql / csv / json
省/地/县/乡层级数据level.json--level.json
省级(省/直辖市/特别行政区)province.jsonprovince.csv-province.json / csv
地级(城市)city.jsoncity.csv-city.json / csv
县级(区县)area.jsonarea.csv-area.json / csv
乡级(乡镇/街)town.jsontown.csv-town.json / csv
县市区没有乡级数据cityNotFoundTown.json--cityNotFoundTown.json

更多 CDN 数据访问

总数据(省/地/县/乡)

data.json | data.csv | data.sql

[
  {
    "code": "110000",
    "name": "北京市",
    "province": "11",
    "city": 0,
    "area": 0,
    "town": 0
  },
  // ...
]

省/地/县/乡层级数据

level.json

[
  {
    "code": "420000",
    "name": "湖北省",
    "province": "42",
    "children": [
      {
        "code": "420100",
        "name": "武汉市",
        "province": "42",
        "city": "01",
        "children": [
          {
            "code": "420102",
            "name": "江岸区",
            "province": "42",
            "city": "01",
            "area": "02"
          },
          // ...
        ]
      }
      // ...
    ]
  }
  // ...
]

省级(省/直辖市/特别行政区)

province.json | province.csv

[
  {
    "code": "110000",
    "name": "北京市",
    "province": "11"
  },
  {
    "code": "120000",
    "name": "天津市",
    "province": "12"
  },
  // ...
]

地级(城市)

city.json | city.csv

[
  {
    "code": "130100",
    "name": "石家庄市",
    "province": "13",
    "city": "01"
  },
  // ...
]

县级(区县)

area.json | area.csv

[
  {
    "code": "110101",
    "name": "东城区",
    "province": "11",
    "city": "01",
    "area": "01"
  },
  // ...
]

乡级(乡镇/街)

town.json | town.csv

[
  {
    "code": "110101001000",
    "name": "东华门街道",
    "province": "11",
    "city": "01",
    "area": "01",
    "town": "001000"
  },
  // ...
]

县市区没有乡级数据

cityNotFoundTown.json

[
  {
    "code": "659010",
    "name": "胡杨河市",
    "province": "65",
    "city": "90",
    "area": "10",
    "town": 0
  },
  // ...
]

参考链接

查看原文

Perla 收藏了文章 · 2019-11-15

Andriod监听支付宝收款实现个人支付宝支付接口!附安卓App

个人微信支付宝免签约支付解决方案

http://www.likeyunba.com/pay/

首先呢,我不会开发安卓App,这款APP是我在酷安网看到的,非常简单的一款APP,安装后填写我们的后端接口(用于接收收款通知的)就可以接收收款通知了。所以就算我们没有这款APP的源码,我们也可以做一个支付系统了。

APP界面:

clipboard.png

界面就这点东西了!
只需要设置后端接口
就可以接收这个APP监听的支付宝收款数据了

APP会以POST方式向您的接口POST一段JSON数据

数据格式如下:

{"title":0.01,"time":"2019-02-26","title":"支付宝支付","content":"成功收款1.00元。享免费提现等更多专属服务,点击查看"}

下面是我写的PHP后端简易版:

<?php
// 定义接收JOSN数据
header("Content-Type:application/json");

// 接收从APP端POST过来的数据
$json = $GLOBALS['HTTP_RAW_POST_DATA'];

// 将JSON数据转换为PHP对象
$obj = json_decode($json);

// 解析对象返回字符串
$money = $obj->money; //  返回支付金额
$title = $obj->title; //返回支付标题
$time = $obj->time; // 返回支付时间
$content = $obj->content; // 返回支付内容

// 连接数据库
$con = mysql_connect("数据库地址","数据库账号","数据库密码");
if (!$con){die('Could not connect: ' . mysql_error());}

//选择数据
mysql_select_db("数据库名", $con);

//设置字符集
mysql_query("SET NAMES UTF8");

//插入数据库
mysql_query("INSERT INTO 表名 (paymoney, paytime, title, content) VALUES ('$money', '$time', '$title', '$content')");

//关闭数据库连接
mysql_close($con);

?>

数据库接收到的通知:

clipboard.png

App下载

https://www.lanzous.com/i39bt9g

支付demo

http://likeyunba.com/demo/Ali...

App开源

https://github.com/WeihuaGu/r...

个人免签约支付宝/微信支付解决方案整理

http://www.likeyunba.com/pay

2020-5-10
有网友表示软件不行了,我没测试,但是我找到了其他的代替软件。
https://segmentfault.com/a/11...

作者:TANKING
时间:2019-2-26
网站:http://likeyunba.com
学习交流微信:face6009

查看原文

Perla 收藏了文章 · 2019-11-11

SegmentFault 技术周刊 Vol.26 - 年中复盘 --- 程序员的自我修养

图片描述

不知不觉已是 6 月中旬了,掐指一算 2017 年已经过去了一半。过去的半年,也许你刚跳槽进入一家新公司,在一个全新的环境里学习和成长;也许你还是和去年一样,仍然奋斗在各种各样的项目和需求里,每天和产品、设计、运营打交道;也许你还在无休止的加班,每天忙忙碌碌却没有方向;也许你正在犹豫是否辞职,彷徨着不知道下一步要怎么走。

不管怎样,现在就可以让自己停下来,找一个清新的早餐,或者在某个安静的夜晚,重新审视自己,对工作、对生活做一个全面的复盘,重新规划,适时调整,更好的前行。

生于忧患

相信小伙伴们都还记得前不久网传华为辞退部分 34 岁以上员工的事。很多人不由感慨程序员也是青春饭,并开始思虑自己的未来,犹豫是不是要转行,担心自己 34 岁以后无处可去。

程序员为什么会忧虑自己的未来?

互联网行业工作强度很大,而中国的互联网从业者更忙。程序员更是战场中的排头兵,身体健康的透支导致很难长期抗战。当你意识到自己跟不上节奏的时候,不管是出于对身体状况的担忧,还是对未来潜在威胁的恐惧,又怎会不感到焦虑呢?

“谁的青春不迷茫”,但其实迷茫不仅限于青春期,人生的每一个阶段都可能迷茫。

三十岁程序员的迷茫

回想自己这几年的迷茫,刚毕业那会迷茫要不要进入IT行业,要。工作两三年迷茫要不要离开家乡去互联网公司?去。来北京后,要不要跟着公司搞互联网金融,搞了。去年朋友说创业去不去,思索良久,么去;那么现在呢,要不要继续在北京吸霾,还是没有想好,要不要进入一个新的领域去拼搏,也是没想好?

如果有一天,我们终将离开现在拼搏的城市,那我们将何去何从?

除了北上广深,程序员的归宿还有哪些城市?

我认为如果让我说出我心中中国互联网乃至移动互联网发展最好的十个城市排名,我会这么排:北京,深圳,上海,杭州,广州,成都,武汉,南京,西安,厦门。

如果除了北上广深,这四个一线城市外,让我推荐程序员最好的归宿和去的地方,首选应该是杭州,其次是成都,再次是武汉,然后是厦门。

PS:从关注 SF 微信公众号的小伙伴们所在城市的分布来看,排名前十的分别是:北京、上海、杭州、武汉、深圳、广州、南京、成都、西安、厦门。

所谓程序员

要想不被淘汰,每个人都需要有自己的核心竞争力,有自己的存在的价值。而在发展变化如此之快的互联网行业,风口浪尖上的程序员们尤甚。

何为技术人的核心竞争力

我观察圈子里很多成功和不成功的技术人,提出一个观点,那就是个人的核心竞争力是他独特的个性知识经验组合。这个行业里拥挤着上百万聪明人,彼此之间真正的不同在哪里?不在于你学的是什么技术,学得多深,IQ多少,而在于你身上有别人没有的独特的个性、背景、知识和经验的组合。如果这种组合,1,绝无仅有;2,在实践中有价值,3,具有可持续发展性,那你就具备核心竞争力。

【转】程序员该如何定位?看这四大方向

定位能够产生目标,目标会让你聚焦在一个方向上,远离迷茫。所以,只要你根据自身的实际情况,找好定位,就拥有了摆脱迷茫的银弹。

博客

和书籍一样,博客是知识最好的沉淀。

我为什么坚持写博客?

最后奉劝大家,如果你还没有写博客,那从现在开始开通个博客,走出第一步,如果你已经开始写博客了,不要去奢望靠写博客去赚钱,安心的写博客提升自己能力,总结经验,把它看成一种投资自己的手段,别把目标搞错了,也许有一天你会突然发现,原来你已经走了这么远,而且还有意外收获!

勿忘初心,才能方得始终!

阮一峰:为什么写博客?

我的每一篇文章,通常需要2小时~6小时的写作时间。有时候写完以后,觉得特别累,都不想干别的事情了。不过,我还是觉得这是值得的。回过头看,我幸亏把时间花在写作博客上面,否则那些时间就白白过去了,没有留下任何印记。

坚持写博一年半,我的收获与成长

在2016年我主要做了两件事情,即编程与写作。在编程方面我主要把重点放在了JavaScript、Vue、React的学习与探究上,而在写作方面我主要发表了20余篇关于前端的原创技术文章。

古人云:学而不思则罔,思而不学则殆。在我看来编程与写作其实并不冲突,编程是一个学习与探究的过程,而写作则是一个分享与记录的过程,只有举一反三,方能为师矣。

书山有路

互联网的发达几乎可以让我们在网上找到任何我们想要的信息,我们也越来越习惯碎片化的阅读和学习。但当我们想要全面、深入地去了解某一样技术、某一门语言的时候,仅有网上的碎片化信息是远远不够的。

“优秀的编程书是没有时间限制的。它们会超越语言的限制,IDE 的限制和平台的限制。它们不是解释 how,而是 why。”

私以为可以提高程序员技术档次的书和博客

为什么中国的程序员总是在不断学习新的开发工具、钻研程序代码,而不逐步提升自己的视野、思维和经验?

【干货】程序员必读书单(上)

本文把程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必读书籍,以及延伸阅读。旨在成为最好最全面的程序员必读书单。

良好的程序设计能力:

  • 掌握常用的数据结构和算法(例如链表,栈,堆,队列,排序和散列);

  • 理解计算机科学的核心概念(例如计算机系统结构、操作系统、编译原理和计算机网络);

  • 熟悉至少两门以上编程语言(例如C++,Java,C#,和Python);

【干货】程序员必读书单(下)

专业的软件开发素养:

  • 具备良好的编程实践,能够编写可测试(Testable),可扩展(Extensible),可维护(Maintainable)的代码;

  • 把握客户需求,按时交付客户所需要的软件产品;

  • 理解现代软件开发过程中的核心概念(例如面向对象程序设计,测试驱动开发,持续集成,和持续交付等等)。

最简编程基本功指南 - 瀚阳的博客

整理分为四大块:编程语言(能写代码)->程序设计(能写好代码)->计算机底层(能做别人做不到)->计算机理论(能做别人想不到)

不过以我的经历,实际过程中会螺旋上升,编程语言->程序设计->计算机底层->计算机理论->编程语言->…,因为一下啃完一整块是不现实的。

简历

写好一份技术简历很重要

其实很多技术人员有很强的工程能力,但是不屑于上述的一些活动,个人觉得这是一个误区,只有有效和这个社会融合,才能获取更多有用的知识和体验,而具备这些能力,才能更好的为公司服务。

最后,如同写博客一样,将你写好的简历不断的修改和完善,直到自己满意,然后将简历投递给心仪的公司吧。

程序员如何写好简历 && 一份优秀的程序员简历是什么样的?

简历就是简单的介绍一下你自己有多 NB。所以,你需要介绍以下的内容:

  • 我是谁。

  • 我会什么。

  • 做过什么。

  • 结果如何。

然后把这些内容放到一个模子里,就可以了。

程序员简历应该怎么写?

作为一个潜入 IT 圈五年之久、看过数万份简历的 HR,在这个问题上还是有点发言权的。HR 在筛选简历时主要从公司需求出发,重点不一,不过还是有很多“通用”的套路,为了在 30 秒内判断出这份简历是否值得跟进,我认为程序员写简历的正确姿势是这样的:

每个程序员都应该有个 Github 简历

相信程序员对 Github 都不会陌生,你的 Github 也是自己的简历,在 Github 的贡献越大,对求职的帮助就越大,也能够慢慢增加自己的影响力。

面试

程序员找工作,应该怎么应对面试官?

  • 面试过程中,应该注意哪些问题?

  • 面试中遇到冷场怎么化解?

  • 如何给面试官留下好印象?

如何在没有实际项目经验的情况下找到工作

  对于许多年轻的计算机或 IT 相关专业毕业生,在没有实际项目开发经验的情况下找到第一份全职工作可能是你在职业生涯中遇到的最大的挑战。

程序员应聘/面试相关整理

我整理这篇文章的重点不在于资源的整理,上面 4 点:面试前的准备——面试题库——大公司面试总结——面试相关的网站和书籍,我是按照先后顺序整理的。

  • 想要去应聘参加面试,首先当然得准备好简历以及自检技能咯;

  • 然后再看看你所面试领域的一些题库,看看自己是否能够回答上来;

  • 再者去针对性看看你要应聘的公司,看看以往面试者是怎样的一个流程以及问了一些什么问题之类的;

  • 最后,如果以上几点都做了之后还觉得美准备好,那么可以找一些网站和书籍看看;

英语这个硬伤

如今英语对程序员而言,已经不仅仅是看懂国外的开发文档和技术博客这么简单了。无数的中国开发者走出国门,进入到各大世界顶级公司从事 IT 开发工作,参加各大开发者会议,和无数国外程序员交流合作。英语对于程序员来说,毫无疑问已经越来越重要了。

别让英语成为自己进步的硬伤。

程序员如何提高自身的英语水平

在此之前,我不并不知道原来有那么多的同学在学习英语的道路上是一路走到黑的。 他们甚至从未想过:英语作为一门语言,学习起来应该是一件比较自然而然的事情,就像我们自然而然地学会汉语那样。

在这份指南里,我会尽可能地综合我主观的看法与一定的科学依据,为大家提供一份详尽的英语进阶指南,真心希望本指南能给你带来一点小小的帮助。

程序员拿什么来学英语

作为程序员,工作中不得不接触英语。如果你对一些新的技术或开源项目感兴趣,英语更是必不可少的。如果你不想花太多时间、精力和金钱去上学习班,又希望可以在日常生活和工作中去提高英语,那么希望这篇文章可以给你带来些帮助。

老码农教你学英语

对于咱们这些高端大气、时刻需要和国际接轨的码农,英语的重要性自然是毋庸置疑的。尤其是那些胸怀大志的潜在大牛们,想在码农行业闯出一片天地,秒杀身边的小弟们,熟练掌握英语更是实现其目标最关键的因素之一。否则,试想在你捧着某出版社刚刚翻译出来的《JSP 高效编程》苦苦学习JSP模板的时候,你旁边的小弟却是拿着原版的《AngularJS in Action》学习开发单页面应用,虽然你们都同样认真地学习了一个月,可做出来东西的效果能一样吗?

软技能

程序员走江湖必备。

程序员怎么找到想要的资源?

这篇文章从以下几个方面进行了整理和推荐,对新手小白自学找资料很实用:

  • 学新技术:想学新技术去哪里找教程?

  • 找项目:想要开发项目,去哪里找点子?找教程?

  • 找书籍:哪里可以找到免费的书籍?

  • 交流探讨:遇到问题哪里可以交流?

  • 其他:一些程序员相关

如何发现优秀的开源项目?

GitHub 其中一个最重要的作用就是发现全世界最优秀的开源项目,你没事的时候刷刷微博、知乎,而人家没事的时候刷刷 GitHub ,看看最近有哪些流行的项目,久而久之,这差距就越来越大。那么如何发现优秀的开源项目呢?

整理一些好的开源项目

通过这些项目你可以大幅度减少不必要的开发而将精力放在更重要的地方。

16个小众却很实用的网站(程序员 向)

16个相对来说比较小众,但是对程序员来说却有趣或者有用的网站

21个国外受欢迎的学习编程的网站:总有一个理由会让你爱上它们

21个与学习编程有关的网站。 每个网站,我会作一些简单的介绍。

中国程序员容易发音错误的单词

中国程序员容易发音错误的单词 (以美式发音为准, 非音标为字母发音)

研发团队GIT开发流程新人学习指南

本文定位于为使用GIT标准分支开发流程的开发团队新人提供一份参考指南,其中的内容都是我们公司在研发团队初创时所遵循的一些开发流程标准,经过近一年的实践,虽说还有很多不足,但是随着团队经验的丰富和人员的扩张,我会适时地更新本文,分享我们在使用GIT开发流程中遇到的问题和解决方案。

《Git权威指南》GotGit 书稿开源

2015年底,在为华为做咨询顾问一年多之后,我决定接受新的挑战,加入华为公司,成为这个拥有着最大的开发者群体的世界级公司的一员。 如何有效地在大公司内进行过知识的传递也是一个课题,我决定将这本书的书稿开源,惠及更多的开发者。

程序员优雅提问宝典《九步真经》 | 软技能

基本口诀

  • 先靠自己、再靠别人

  • 排除原因、礼貌问答

  • 善于总结、手留余香

程序员如何提一个好问题?

我实际上是那种总是会问出愚蠢问题或“不好”问题的大信徒。我一直在问人们一些愚蠢并且完全可以通过谷歌搜索或搜索代码库解决的问题。大多数时候我都不愿意自己去搜索解决,但有的时候我又会无论如何都自己去搞定,而且也不会认为这如同世界末日一样可怕。

所以本文中列举的各个策略不是关于“在提问之前你必须要做的所有事情”,而是“一些可以帮助提出更好的问题并得到我想要的答案的要点!”。

程序员,你真的会解决问题吗?

作为一枚程序员,我们天生就是来解决问题的。在你不知道你的问题之前,我帮不了你,Google 也不能帮你解决问题。

积跬步,致千里

大神不是一天练成的。

工程师成长之路:工作1-3年工程师如何突破瓶颈期?

成熟期是整个职业生涯中最关键的时期,快的可能一两年就能走过去;慢的,可能整个职业生涯都定格在成熟期。

从上面分析中可以看到,这些问题最终都和“心”相关。要想高速成长,就得克服掉温水中的舒适。要想提高自信,还得思考成就感获取渠道这么虚头巴脑的问题。所以要想迈过去这个坎儿,必须有一颗非常强大的内心。

面试感悟:一名3年工作经验的程序员应该具备的技能

每个程序员、或者说每个工作者都应该有自己的职业规划,如果看到这里的朋友没有自己的职业规划,希望你可以思考一下自己的将来。

天天写业务代码,如何成为技术大牛?

成为技术大牛梦想固然很美好,但是要付出很多,不管是Do more还是Do better还是Do exercise,都需要大量花费时间和精力,这个过程中可能很苦逼,也可能很枯燥。

这里我想特别强调一下:前面所讲的都是一些方法论的东西。但真正起决定作用的,其实还是我们对技术的热情和兴趣!

当当架构部张亮:从码农到大牛,技术与心境的双重提升

只有保持足够的兴趣才能在技术上走得更远。如果做技术无法体会快乐,完全是为了养家糊口而被迫走上这条路,相信很难在漫长的职业生涯中有足够的动力持续成长。世界很精彩,不喜欢做技术的人不一定非要做技术,如果最终一定要转行,越早就越能在新的行业中掌握主动权。

心经

「代码家」的学习过程和学习经验分享

目前能想到的一些学习的技巧和陷阱,大致都列了出来。都是我个人的一些学习的经验,如果对你有帮助,想必也是极好的,如果你觉得我写的有不合理的地方也欢迎指出。坚持着去实施提及的一些方法,一定会对你的生活和职业带来改变。

技术大牛养成指南,一篇不鸡汤的成功学实践

有的人想成为大牛,却不曾为此努力。有的人辛苦耕耘,却收获寥寥。很多时候,你跟成功的差距并不是能力,也不是运气,或许只是正确的方法?这是一篇不鸡汤的成功学指南,如果你相信且愿意坚持尝试,未必帮不到你!

[译] 我是如何成为一名更优秀的程序员的

关于我的一些详细信息:我现年32岁,有10年以上扎实的工作经验。直到最近几年我才对自己所做的工作充满信心。即使是现在,我也在不断质疑自己。问题在于,这种质疑并不会消失,所以你要做的就是无视它,不断的解决问题,不断的积累经验。

首先我要说明的是以下提到的只是一些帮你提升技能的小贴士。最终你还是需要找到一条最适合你自己的路。这些只是我发现对我有帮助的点。

论程序员的自我修养

我想说的是,本篇里面分享的一些道理和方法,都是通俗易懂的,就和常听到的例如101%和99%的365次方的故事、1万小时的道理等等一样,但真正去认真思考并实践的屈指可数,也许,坚持才是程序员最大的修养,和各位共勉!

出任 CTO

程序员的未来在哪里?当然是“出任CTO,迎娶白富美,走上人生巅峰!”,想想是不是有点小激动?

魔都,3 年,程序员到 CTO

  • 以前的我,只会一味的阅读技术书籍,沉迷于技术。

  • 以前的我,不喜欢和不熟悉的人聊天,甚至有些偏内向。

  • 以前的我,只会用最快的速度完成安排下来的任务。

  • 以前的我,只关注自我成长。

  • 现在的我,阅读的书籍类型有管理,心理,商业,人文。

  • 现在的我,喜欢和人聊天,倾听,讨论,分享自己的想法。

  • 现在的我,在接到任务之前更多的是思考是否合理,有没有更好的解决方案。

  • 现在的我,关注团队每个人的成长。

4 年前端狗,2 年 CTO

在工作 2 年左右,我发现自己在技术深度上很难有专业造诣的时候,我开始把眼光放的更长远,我不再把自己仅仅定位成一个前端工程师,而是会开始关心互联网的发展趋势与整体格局,关心产品从 0 到 1 诞生过程中的盈利模式,关心在产品迭代中工程师与运营多方参与的角度和结合的效率,关心工作流程和团队文化,这一切其实都是我潜意识不自觉的关注,是一种不安分,过后很久才逐渐意识到自己早就在默默铺路,有时候一个选择早就做了,只是你还未意识到。

Coding CTO 孙宇聪:《人,技术与流程》

从 Google 回来在 Coding 做 CTO,对我来说也是人生的一个大改变。最近我在知乎看到一个好问题,“从大公司离开到小公司当 CTO 是怎样的体验”,我摘抄了一个好答案:“ 顶着 CTO 的名号,招聘,培训,鼓励程序猿,拉网线,查机房,装系统这都是 CTO 要做的事;讨论方案,推方案,定方案,确定进度,拖延进度,安抚程序猿,挨老板骂,安抚老板,这也是 CTO 的职务。” 不包括 Coding,而我的工作还包括 Coding,很伤心。(笑)

致程序媛

虽然程序媛们没有程序员鼓励师,但我们自己就是自己的鼓励师。程序媛们正在创造越来越多的可能。PPS:SF 微信公众号的关注者中有 20% 是程序媛~加油吧程序媛们,请为自己自豪!

历史上首位程序员是一名女性

在男性占据技术行业统治地位的今天,人们恐怕难以想象,历史上首位电脑程序员竟然是一名女性!在1842年,人称“数字女王”的阿达-奥古斯塔(Ada Lovelace)编写了历史上首款电脑程序。

冯怡:我想给大家展示一种可能性(图灵访谈)

我觉得就是社会上的social stereotype,这种固有偏见会打消一些姑娘想要成为程序员的想法。她们会听到很多声音:你不适合,或者你做不好,或者说这个很累,坚持不下来,这会导致一件事情在还没开始的时候,就被否定掉了。

我是那种“反着来”的类型,越是说我不行,我就越要证明自己可以。

最后

小时候,我们以为能够改变世界的人只有极少数的科学家。然而今天,互联网正在以几何级的速度改变着世界,改变着我们的生活。“程序员是世界上少有的能改变世界的人”,而每天坐在电脑前敲代码的我们就是这其中的一员。

“这是最好的时代,也是最坏的时代”。我们生于这个世界,也终将改变这个世界。

图片描述

查看原文

Perla 收藏了文章 · 2019-10-22

MySQL的又一神器-锁,MySQL面试必备

原文链接:blog.ouyangsihai.cn >> MySQL的又一神器-锁,MySQL面试必备

在看这篇文章之前,我们回顾一下前面的几篇关于MySQL的文章,应该对你读下面的文章有所帮助。

1 什么是锁

1.1 锁的概述

在生活中锁的例子多的不能再多了,从古老的简单的门锁,到密码锁,再到现在的指纹解锁,人脸识别锁,这都是锁的鲜明的例子,所以,我们理解锁应该是非常简单的。

再到MySQL中的锁,对于MySQL来说,锁是一个很重要的特性,数据库的锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性,这样才能保证在高并发的情况下,访问数据库的时候,数据不会出现问题。

1.2 锁的两个概念

在数据库中,lock和latch都可以称为锁,但是意义却不同。

Latch一般称为闩锁(轻量级的锁),因为其要求锁定的时间必须非常短。若持续的时间长,则应用的性能会非常差,在InnoDB引擎中,Latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的是用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制。

Lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。

2 InnoDB存储引擎中的锁

2.1 锁的粒度

在数据库中,锁的粒度的不同可以分为表锁、页锁、行锁,这些锁的粒度之间也是会发生升级的,锁升级的意思就是讲当前锁的粒度降低,数据库可以把一个表的1000个行锁升级为一个页锁,或者将页锁升级为表锁,下面分别介绍一下这三种锁的粒度(参考自博客:https://blog.csdn.net/baoling...)。

表锁

表级别的锁定是MySQL各存储引擎中最大颗粒度的锁定机制。该锁定机制最大的特点是实现逻辑非常简单,带来的系统负面影响最小。所以获取锁和释放锁的速度很快。由于表级锁一次会将整个表锁定,所以可以很好的避免困扰我们的死锁问题。

当然,锁定颗粒度大所带来最大的负面影响就是出现锁定资源争用的概率也会最高,致使并大度大打折扣。

使用表级锁定的主要是MyISAM,MEMORY,CSV等一些非事务性存储引擎。

特点: 开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

页锁

页级锁定是MySQL中比较独特的一种锁定级别,在其他数据库管理软件中也并不是太常见。页级锁定的特点是锁定颗粒度介于行级锁定与表级锁之间,所以获取锁定所需要的资源开销,以及所能提供的并发处理能力也同样是介于上面二者之间。另外,页级锁定和行级锁定一样,会发生死锁。
在数据库实现资源锁定的过程中,随着锁定资源颗粒度的减小,锁定相同数据量的数据所需要消耗的内存数量是越来越多的,实现算法也会越来越复杂。不过,随着锁定资源 颗粒度的减小,应用程序的访问请求遇到锁等待的可能性也会随之降低,系统整体并发度也随之提升。
使用页级锁定的主要是BerkeleyDB存储引擎。

特点: 开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

行锁

行级锁定最大的特点就是锁定对象的粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。

虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。

特点: 开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

比较表锁我们可以发现,这两种锁的特点基本都是相反的,而从锁的角度来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。

MySQL 不同引擎支持的锁的粒度

2.2 锁的类型

InnoDB存储引擎中存在着不同类型的锁,下面一一介绍一下。

S or X (共享锁、排他锁)

数据的操作其实只有两种,也就是读和写,而数据库在实现锁时,也会对这两种操作使用不同的锁;InnoDB 实现了标准的行级锁,也就是共享锁(Shared Lock)和互斥锁(Exclusive Lock)

  • 共享锁(读锁)(S Lock),允许事务读一行数据。
  • 排他锁(写锁)(X Lock),允许事务删除或更新一行数据。

IS or IX (共享、排他)意向锁

为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB存储引擎支持一种额外的锁方式,就称为意向锁,意向锁在 InnoDB 中是表级锁,意向锁分为:

  • 意向共享锁:表达一个事务想要获取一张表中某几行的共享锁。
  • 意向排他锁:表达一个事务想要获取一张表中某几行的排他锁。

另外,这些锁之间的并不是一定可以共存的,有些锁之间是不兼容的,所谓兼容性就是指事务 A 获得一个某行某种锁之后,事务 B 同样的在这个行上尝试获取某种锁,如果能立即获取,则称锁兼容,反之叫冲突。

下面我们再看一下这两种锁的兼容性。

  • S or X (共享锁、排他锁)的兼容性

  • IS or IX (共享、排他)意向锁的兼容性

3 前面小结

这里用一个思维导图把前面的概念做一个小结。

4 一致性非锁定读和一致性锁定读

一致性锁定读(Locking Reads)

在一个事务中查询数据时,普通的SELECT语句不会对查询的数据进行加锁,其他事务仍可以对查询的数据执行更新和删除操作。因此,InnoDB提供了两种类型的锁定读来保证额外的安全性:

  • SELECT ... LOCK IN SHARE MODE
  • SELECT ... FOR UPDATE

SELECT ... LOCK IN SHARE MODE: 对读取的行添加S锁,其他事物可以对这些行添加S锁,若添加X锁,则会被阻塞。

SELECT ... FOR UPDATE: 会对查询的行及相关联的索引记录加X锁,其他事务请求的S锁或X锁都会被阻塞。 当事务提交或回滚后,通过这两个语句添加的锁都会被释放。 注意:只有在自动提交被禁用时,SELECT FOR UPDATE才可以锁定行,若开启自动提交,则匹配的行不会被锁定。

#### 一致性非锁定读

一致性非锁定读(consistent nonlocking read) 是指InnoDB存储引擎通过多版本控制(MVVC)读取当前数据库中行数据的方式。如果读取的行正在执行DELETE或UPDATE操作,这时读取操作不会因此去等待行上锁的释放。相反地,InnoDB会去读取行的一个快照。所以,非锁定读机制大大提高了数据库的并发性。

来自网络:侵权删

一致性非锁定读是InnoDB默认的读取方式,即读取不会占用和等待行上的锁。在事务隔离级别READ COMMITTEDREPEATABLE READ下,InnoDB使用一致性非锁定读。

然而,对于快照数据的定义却不同。在READ COMMITTED事务隔离级别下,一致性非锁定读总是读取被锁定行的最新一份快照数据。而在REPEATABLE READ事务隔离级别下,则读取事务开始时的行数据版本

下面我们通过一个简单的例子来说明一下这两种方式的区别。

首先创建一张表;

插入一条数据;

insert into lock_test values(1);

查看隔离级别;

select @@tx_isolation;

下面分为两种事务进行操作。

REPEATABLE READ事务隔离级别下;

REPEATABLE READ事务隔离级别下,读取事务开始时的行数据,所以当会话B修改了数据之后,通过以前的查询,还是可以查询到数据的。

READ COMMITTED事务隔离级别下;

READ COMMITTED事务隔离级别下,读取该行版本最新的一个快照数据,所以,由于B会话修改了数据,并且提交了事务,所以,A读取不到数据了。

5 行锁的算法

InnoDB存储引擎有3种行锁的算法,其分别是:

  • Record Lock:单个行记录上的锁。
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。
  • Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。

Record Lock:总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。

Next-Key Lock:结合了Gap Lock和Record Lock的一种锁定算法,在Next-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法。举个例子10,20,30,那么该索引可能被Next-Key Locking的区间为:

除了Next-Key Locking,还有Previous-Key Locking技术,这种技术跟Next-Key Lock正好相反,锁定的区间是区间范围和前一个值。同样上述的值,使用Previous-Key Locking技术,那么可锁定的区间为:

不是所有索引都会加上Next-key Lock的,这里有一种特殊的情况,在查询的列是唯一索引(包含主键索引)的情况下,Next-key Lock会降级为Record Lock

接下来,我们来通过一个例子解释一下。

CREATE TABLE test (
    x INT,
    y INT,
    PRIMARY KEY(x),    // x是主键索引
    KEY(y)    // y是普通索引
);
INSERT INTO test select 3, 2;
INSERT INTO test select 5, 3;
INSERT INTO test select 7, 6;
INSERT INTO test select 10, 8;

我们现在会话A中执行如下语句;

SELECT * FROM test WHERE y = 3 FOR UPDATE

我们分析一下这时候的加锁情况。

  • 对于主键x

  • 辅助索引y

用户可以通过以下两种方式来显示的关闭Gap Lock:

  • 将事务的隔离级别设为 READ COMMITED。
  • 将参数innodb_locks_unsafe_for_binlog设置为1。

Gap Lock的作用:是为了阻止多个事务将记录插入到同一个范围内,设计它的目的是用来解决Phontom Problem(幻读问题)。在MySQL默认的隔离级别(Repeatable Read)下,InnoDB就是使用它来解决幻读问题。

幻读:是指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL可能会返回之前不存在的行,也就是第一次执行和第二次执行期间有其他事务往里插入了新的行。

6 锁带来的问题

6.1 脏读

脏读: 在不同的事务下,当前事务可以读到另外事务未提交的数据。另外我们需要注意的是默认的MySQL隔离级别是REPEATABLE READ是不会发生脏读的,脏读发生的条件是需要事务的隔离级别为READ UNCOMMITTED,所以如果出现脏读,可能就是这种隔离级别导致的。

下面我们通过一个例子看一下。

从上面这个例子可以看出,当我们的事务的隔离级别为READ UNCOMMITTED的时候,在会话A还没有提交时,会话B就能够查询到会话A没有提交的数据。

6.2 不可重复读

不可重复读: 是指在一个事务内多次读取同一集合的数据,但是多次读到的数据是不一样的,这就违反了数据库事务的一致性的原则。但是,这跟脏读还是有区别的,脏读的数据是没有提交的,但是不可重复读的数据是已经提交的数据。

我们通过下面的例子来看一下这种问题的发生。

从上面的例子可以看出,在A的一次会话中,由于会话B插入了数据,导致两次查询的结果不一致,所以就出现了不可重复读的问题。

我们需要注意的是不可重复读读取的数据是已经提交的数据,事务的隔离级别为READ COMMITTED,这种问题我们是可以接受的。

如果我们需要避免不可重复读的问题的发生,那么我们可以使用Next-Key Lock算法(设置事务的隔离级别为READ REPEATABLE)来避免,在MySQL中,不可重复读问题就是Phantom Problem,也就是幻像问题

6.3 丢失更新

丢失更新:指的是一个事务的更新操作会被另外一个事务的更新操作所覆盖,从而导致数据的不一致。在当前数据库的任何隔离级别下都不会导致丢失更新问题,要出现这个问题,在多用户计算机系统环境下有可能出现这种问题。

如何避免丢失更新的问题呢,我们只需要让事务的操作变成串行化,不要并行执行就可以。

我们一般使用SELECT ... FOR UPDATE语句,给操作加上一个排他X锁。

6.4 小结

这里我们做一个小结,主要是在不同的事务的隔离级别下出现的问题的对照,这样就更加清晰了。

1、原创不易,老铁,文章需要你的 点赞 让更多的人看到,希望能够帮助到大家!

2、文章有不当之处,欢迎指正,如果喜欢微信阅读,你也可以关注我的微信公众号好好学java,公众号已有 6W 粉丝,回复:1024,获取公众号的大礼包,公众号长期发布 Java 优质系列文章,关注我们一定会让你收获很多!

查看原文

认证与成就

  • 获得 50 次点赞
  • 获得 7 枚徽章 获得 1 枚金徽章, 获得 1 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-11-02
个人主页被 691 人浏览