mysql生成数据字典

建立数据库时一定要写好表和字段的备注

#表名
select table_name, table_comment from information_schema.`tables` where table_schema='dbname' and table_name like 'tables';
#列名
select table_name, column_name, data_type, column_comment from information_schema.columns where table_schema='dbname' and table_name like 'tables';
发表在 mysql | mysql生成数据字典已关闭评论

Android adb 调试程序没有权限解决方案

1. 用adb 连接到手机 adb shell
2. 执行命令:run-as com.ivhong.testproject,就会直接切换到你的程序目录下,并有了这个app的权限

发表在 Android | 标签为 , , , | Android adb 调试程序没有权限解决方案已关闭评论

Mac下Android Studio 的 Android SDK默认安装路径

/Users//Library/Android/sdk

发表在 MAC | 标签为 , , | Mac下Android Studio 的 Android SDK默认安装路径已关闭评论

php 实现双向链表 及 建立链表耗时

这个就是为了学习而使用,php有自身的链表实现,功能更全面,百度搜索 php spl

<?php
class node {
	public $val = null;
	public $pre = null;
	public $nex = null;
	//存放该node的位置
	public $index = null;
	public $num = 1;
	public function __construct($val){
		$this->val = $val;
		$this->pre = null;
		$this->nex = null;
	}
}

class links{
	//链表头
	static $head = null;
	//链表尾
	static $end = null;
	//链表内容
	static $nodes = [];
	
	/**
	 * 添加一个节点
	 * @param int $val 节点内容
	 */
	public static function add($val){
		//初始化一个节点
		$newNode = new node($val);
		$newNode->index = count(static::$nodes);
		static::$nodes[$newNode->index] = $newNode;
		//链表为空
		if( static::$head === null ){
			//头和尾都指向这个节点
			static::$head = $newNode->index;
			static::$end = $newNode->index;
		}else{
			static::searchSet($newNode, static::$nodes[static::$head]);
		}
	}

	/**
	 * 搜索链表插入
	 * @param node $newNode 新节点
	 * @param node $node 链表中的节点,和新节点做比较
	 */
	public static function searchSet($newNode, $node){
		//新插入的节点值小于目标节点值,则在目标节点前插入
		if($newNode->val < $node->val){
			if($node->pre === null){//如果目标节点前一个指向的是null,则说明需要在链表开头插入
				static::$head = $newNode->index;
			}else{//否则将前一个节点的后指针指向新节点,新节点的前指针指向前一个节点
				$pre = static::$nodes[$node->pre];
				$pre->nex = $newNode->index;
				$newNode->pre = $pre->index;
			}

			//新节点的后指针指向目标节点
			$newNode->nex = $node->index;
			//目标节点前指针指向新节点
			$node->pre = $newNode->index;

		}elseif($newNode->val == $node->val){
			++$node->num;
		}else{//新节点和下个节点比较
			if($node->nex === null){//如果下个节点为null,说明在链表尾部插入新节点
				$node->nex = $newNode->index;
				$newNode->pre = $node->index;
				static::$end = $newNode->index;
			}else{
				static::searchSet($newNode, static::$nodes[$node->nex]);
			}
		}
	}

    /**
     * 输出
     * @param bool $isasc 是否为正序输出
     */
	public static function printfs($isasc=true){
        static $index = null;

		if($index === null){
			if($isasc){
				$index = static::$head;
			}else{
				$index = static::$end;
			}
		}
		
		echo static::$nodes[$index]->val . ' ';

		if($isasc){
			if(static::$nodes[$index]->nex === null) return;
			$index = static::$nodes[$index]->nex;
		}else{
			if(static::$nodes[$index]->pre === null) return;
			$index = static::$nodes[$index]->pre;
		}

        static::printfs($isasc);
	}
}


function microtimeFloat() {
        list($usec, $sec) = explode(" ", microtime());
        return ((float) $usec + (float) $sec);
}


$time = microtimeFloat();
$ary = range(0, 1000);
shuffle($ary);

foreach($ary as $v){
	links::add($v);	
}
$time2 = microtimeFloat();
links::printfs();
$time3 = microtimeFloat();
echo "\n\n";
links::printfs(0);
$time4 = microtimeFloat();

echo "---------------\n";
echo ($time2 - $time) . "\n";
echo ($time3 - $time2) . "\n";
echo ($time4 - $time3) . "\n";

发表在 php小程序 | 标签为 , | php 实现双向链表 及 建立链表耗时已关闭评论

在redis中优化频繁操作redis产生多次链接引发的网络延时

在程序中可能存在频繁操作redis,每次操作redis都需要产生网络链接,虽然每次操作的返回处理非常快(几十甚至几毫米),但是非常多的redis操作在超高的并发请求中,还是有必要优化的,那么php中如何避免产生多次操作,每次都链接一次redis呢?其实和上篇文章的方法是一样,仅仅是把 multi 的参数指定为Redis::PIPELINE,但是这样操作禁止了原子性操作,代码如下:

<?php
$redis = new \Redis(); 
$redis->connect('127.0.0.1', 6379);
$key = 'watchkey';

$redis->watch($key);
//仅仅这里的参数不同
$redis->multi(Redis::PIPELINE);

sleep(3);
$redis->incr($key);
$redis->get($key);

$r = $redis->exec();
var_dump($r);

function getRedis(){
   $redis = new \Redis(); 
   $redis->connect('127.0.0.1', 6379); 
   return $redis;
}

和上次一样,连着执行3次看看结果:
redis访问优化
发现 watchkey 被执行了3次,watch 并没有起到作用。
这样的操作仅仅确保进程之间不会产生数据冲突,才能使用这个方法。

发表在 redis | 标签为 , | 在redis中优化频繁操作redis产生多次链接引发的网络延时已关闭评论

redis 事务之watch

事务保证原子性操作,在redis 中实现事务和mysql中实现事务的方法有些不一样。
在 mysql中实现事务,一般是启动一个事务,然后执行 select ... for update 对某个要操作行进行锁定,然后如果并发的进程处理到锁定的行时,判定改行是否被其他的进程正在读(被锁定),如果是,则等待锁释放,然后继续执行结下来的操作,这也就是所谓的悲观锁。
在redis中实现事务也是有多个方法的,比如用 watch 监控某个key是否被其他的进程修改,watch乐观锁的实现方案,也就是说,先假定所有的进程之间的数据操作之间没有任何交集,执行一系列的操作,在最后提交的时候,如果发现被监控的key已经被其他的进程修改了(前面的假定失败),则提交时则返回false。
php中用redis 的 watch 实现的代码如下:

<?php
//创建redis连接
$redis = new \Redis(); 
$redis->connect('127.0.0.1', 6379);

//被监控的键
$key = 'watchkey';
//监控 $key,一定要在事务前监控这个键,因为在执行 multi 命令后,所有的命令将会进入到一个redis队列,然后保证这些命令可以不被其他程序打扰的情况下依次执行,这也是redis实现原子操作的方法
$redis->watch($key);

//启用原子操作(事务)
$redis->multi();
//为了测试结果,休眠3秒
sleep(3);
//修改被监控的键值,incr 是redis 的计数器,原子性操作,每次执行这个命令,将给 $key 自增 1
$redis->incr($key);
//在事务内得所有操作都将返回 redis 连接对象,只有在执行 exec 返回结果中,所有的返回数据将放到数组中返回
$redis->get($key);

//执行事务,如果事务执行失败则返回false,正确则返回事务中的所有返回结果
$r = $redis->exec();
var_dump($r);

把上面的程序保存到t.php中,然后在命令行执行三次,等待执行结果:
redis事务之watch
我们发现,只有第一次执行是成功的,接下来执行的都是失败的。在redis-cli查看 watchkey 的结果,发现也仅仅第一个事务被正确执行了。

发表在 redis | 标签为 , , | redis 事务之watch已关闭评论

队列调度程序

消息队列分配任务,通常未解决大并发问题,我们通常需要用消息队列异步来处理一些请求,把需要处理的数据先放到队列里,然后另有程序监听队列队列,异步处理这些数据。
如果队列内消息过多的话,那么一个消费程序处理起来就需要消耗很多时间,本程序解决的问题是按照队列内消息量的大小,分配异步执行程序的数量,当队列里没消息的时候,就没有任何消费进程,只有当队列内有值,才分配异步执行进程。
本程序是监控的队列是Redis,使用了一些php方法,可以按自己需要修改。
QueueScheduling

发表在 Shell | 标签为 , | 21条评论

shell 版守护进程

本文地址: http://ivhong.com/shell-版守护进程/
shell 实现守护进程,包含两个文件:
1 ctl.sh 控制器文件
2 run.sh 守护进程文件

用法:
1 按照注释修改 ctl.sh 要守护的进程命令
2 ctl.sh [start | stop | restart]

压缩包下载:
守护进程

发表在 Shell | 标签为 , | 3条评论

crontab 重定向错误日志 加上时间

在开发中,我们避免不了写crontab脚本来异步执行一些东西,一般设置crontab用下面的方法

*/1 * * * * commond > /tmp/t.log 2>&1

后面的 2>&1 代表把标准错误输出指向标准输出,意思是当commond异常退出时,把异常退出时的日志也写到 /tmp/t.log 下面,这时记录的日志是没有时间信息的,就是说日志里的数据没有办法知道是什么时候打印出来的。
下面通过一个shell来解决这件事,代码如下

#!/bin/bash

if [ $# -gt 1 ]; then
	istring=''
	#去掉回车
	date=`date +%Y/%m/%d\ %H:%M:%S | tr -s ["\n"]`
	for (( i = 2; i <= $#; i++ ))
	do
		string=$string" "${!i}
	done	
	c=$date": "$string
	echo "" >> $1
	echo $c >> $1
fi

把上面的代码放到根目录下,保存为 datecrontalog.sh

然后在crontab -e用下面的脚本代替

*/1 * * * *  commond 2>&1 | xargs $HOME/datecrontalog.sh /tmp/t.log
发表在 Shell | 标签为 , | 一条评论

修改NetBeans 新建文件默认文件类型为UNIX

1. 安装插件 change-line-endings-on-save

2. 工具-》选项-》编辑器-》Line Endings -> Enable adjusting the line endings 前打勾,然后下面的下拉框选择 Unix(LF)

发表在 NetBeans | 标签为 , , | 修改NetBeans 新建文件默认文件类型为UNIX已关闭评论