php json_encode 中文不转unicode码

json_encode($msg, JSON_UNESCAPED_UNICODE)
发表在 未分类 | 留下评论

js 奇怪的问题之0

//输出 true
console.log(0 == "0")
//输出1
if(0){
   console.log(0) 
}else{
   console.log(1)
}
//输出0
if("0"){
   console.log(0) 
}else{
   console.log(1)
}
发表在 js | 留下评论

ssl 免密登陆

假如有2台机器a、b,使a机器免密登陆b机器。
1. 在a机器中输入 ssh-keygen -t rsa,一路回车
2. 复制 ~/.ssh/id_rsa.pub 中的内容
3. 在b机器中:
1):vim /etc/ssh/sshd_config
2):去掉下面的注释
RSAAuthentication yes # 启用 RSA 认证
PubkeyAuthentication yes # 启用公钥私钥配对认证方式
AuthorizedKeysFile %h/.ssh/authorized_keys # 公钥文件路径(和上面生成的文件相同)
3):将步骤2中的内容复制到 ~/.ssh/authorized_keys 中(类似 cat xxxx >> bbbb 的操作,非覆盖)
4):service sshd restart
4. 直接在a机器中 ssh [username]@b username 如果一样的话,可以不必输入

发表在 Shell | 标签为 | 留下评论

php 中文字符集修改成UTF8编码

$t = mb_detect_encoding($a,["GB18030", "UTF-8","GB2312","GBK","BIG5"]);
if($t !== false && $t != "UTF-8"){
    $a = mb_convert_encoding($a, 'UTF-8', $t);
}
发表在 php, php 优化, 基础 | 标签为 , , , , | 留下评论

mysql生成数据字典

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

#表名
select table_name, table_comment from `tables` where table_schema='dbname' and table_name like 'tables';
#列名
select table_name, column_name, column_comment from information_schema.columns where table_schema='dbname' and table_name like 'tables';
发表在 mysql | 留下评论

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

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

发表在 Android | 标签为 , , , | 留下评论

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

/Users//Library/Android/sdk

发表在 Android | 标签为 , , | 留下评论

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小程序 | 标签为 , | 留下评论

在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 事务之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 | 标签为 , , | 留下评论