Redis缓存方案
1 Redis简介
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
2 安装
2.1 安装环境:
CentOS 6.5
Redis 2.8.13
2.2 下载安装:
下载文件到 /opt/ 目录下
wget http://download.redis.io/releases/redis-2.8.13.tar.gz
解压文件
tar zxvf redis-2.8.13.tar.gz
切换目录到 redis-2.8.13 目录下
cd redis-2.8.13
执行make命令,最后几行的输出结果
Hint: To run ‘make test’ is a good idea
make[1]: Leaving directory `/opt/redis-2.8.13/src’
2.3 执行安装命令
make install
提示:
cd src && make install
make[1]: Entering directory `/opt/redis-2.8.13/src'
Hint: To run 'make test' is a good idea
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install
make[1]: Leaving directory `/opt/redis-2.8.13/src'
根据提示,执行:cd src && make install
提示:
Hint: To run 'make test' is a good idea
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL instal
按照提示执行:make test
提示:
You need tcl 8.5 or newer in order to run the Redis test
make: *** [test] Error 1
解决方法参考:http://www.linuxfromscratch.org/blfs/view/cvs/general/tcl.html
3 Redis之java操作篇(Jedis)
主要介绍如何用Jedis对Redis数据库进行操作,只做了简单的例子。前提:安装好Redis数据库,并已启动好服务。
1) 新建测试工程,修改 pom.xml 配置文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.viking</groupId>
<artifactId>redis_demo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>redis_demo Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java-version}</source>
<target>${java-version}</target>
<encoding>utf8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
2) 创建 RedisUtil.java (用来测试Reids连接池使用)
package demo; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; public final class RedisUtil { //Redis服务器IP
private static String ADDR = "127.0.0.1"; //Redis的端口号
private static int PORT = 6379; //访问密码
//private static String AUTH = "admin"; //可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = 1024; //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = 200; //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private static int MAX_WAIT = 10000; private static int TIMEOUT = 10000; //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private static boolean TEST_ON_BORROW = true; private static JedisPool jedisPool = null; /**
* 初始化Redis连接池
*/
static {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(MAX_ACTIVE);
//change "maxActive" -> "maxTotal" and "maxWait" -> "maxWaitMillis" in all examples.
config.setMaxTotal(MAX_ACTIVE);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT);
config.setTestOnBorrow(TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 获取Jedis实例
* @return
*/
public synchronized static Jedis getJedis() {
try {
if (jedisPool != null) {
Jedis resource = jedisPool.getResource();
return resource;
} else {
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 释放jedis资源
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedisPool.returnResource(jedis);
}
}
}
3) 创建 TestRedis.java
package demo; import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis; public class TestRedis {
private Jedis jedis; @Before
public void setup() {
//连接redis服务器
jedis = new Jedis("127.0.0.1", 6379);
} /**
* redis存储字符串
*/
@Test
public void testString() {
//-----添加数据----------
jedis.set("name","yuanxj");//向key-->name中放入了value-->yuanxj
System.out.println(jedis.get("name"));//执行结果:yuanxj jedis.append("name", " is Fraud"); //拼接
System.out.println(jedis.get("name")); jedis.del("name"); //删除某个键
System.out.println(jedis.get("name"));
//设置多个键值对
jedis.mset("name","Viking","age","30","qq","1001");
jedis.incr("age"); //进行加1操作
System.out.println(jedis.get("name") + "-" + jedis.get("age") + "-" + jedis.get("qq")); } /**
* redis操作Map
*/
@Test
public void testMap() {
//-----添加数据----------
Map<String, String> map = new HashMap<String, String>();
map.put("name", "yuanxj");
map.put("age", "30");
map.put("qq", "1001");
jedis.hmset("user1",map);
//第一个参数是存入redis中map对象的key,后面跟的是放入map中的对象的key,后面的key可以跟多个,是可变参数
List<String> rsmap = jedis.hmget("user1", "name", "age", "qq");
System.out.println(rsmap); //删除map中的某个键值
jedis.hdel("user1","age");
System.out.println(jedis.hmget("user1", "age")); //因为删除了,所以返回的是null
System.out.println(jedis.hlen("user1")); //返回key为user的键中存放的值的个数2
System.out.println(jedis.exists("user1"));//是否存在key为user的记录 返回true
System.out.println(jedis.hkeys("user1"));//返回map对象中的所有key
System.out.println(jedis.hvals("user1"));//返回map对象中的所有value Iterator<String> iter=jedis.hkeys("user1").iterator();
while (iter.hasNext()){
String key = iter.next();
System.out.println(key+":"+jedis.hmget("user1",key));
}
} /**
* jedis操作List
*/
@Test
public void testList(){
//开始前,先移除所有的内容
jedis.del("java framework");
System.out.println(jedis.lrange("java framework",0,-1));
//先向key java framework中存放三条数据
jedis.lpush("java framework","spring");
jedis.lpush("java framework","struts");
jedis.lpush("java framework","hibernate");
//再取出所有数据jedis.lrange是按范围取出,
// 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有
System.out.println(jedis.lrange("java framework",0,-1)); jedis.del("java framework");
jedis.rpush("java framework","spring");
jedis.rpush("java framework","struts");
jedis.rpush("java framework","hibernate");
System.out.println(jedis.lrange("java framework",0,-1));
} /**
* jedis操作Set
*/
@Test
public void testSet(){
//添加
jedis.sadd("user2","yuanxj");
jedis.sadd("user2","Fraud");
jedis.sadd("user2","Viking");
jedis.sadd("user2","Jake");
jedis.sadd("user2","who");
//移除noname
jedis.srem("user2","who");
System.out.println(jedis.smembers("user2"));//获取所有加入的value
System.out.println(jedis.sismember("user2", "who"));//判断 who 是否是user集合的元素
System.out.println(jedis.srandmember("user2"));
System.out.println(jedis.scard("user2"));//返回集合的元素个数
} @Test
public void test() throws InterruptedException {
//jedis 排序
//注意,此处的rpush和lpush是List的操作。是一个双向链表(但从表现来看的)
jedis.del("a");//先清除数据,再加入数据进行测试
jedis.rpush("a", "1");
jedis.lpush("a","6");
jedis.lpush("a","3");
jedis.lpush("a","9");
System.out.println(jedis.lrange("a",0,-1));// [9, 3, 6, 1]
System.out.println(jedis.sort("a")); //[1, 3, 6, 9] //输入排序后结果
System.out.println(jedis.lrange("a",0,-1));
} @Test
public void testRedisPool() {
RedisUtil.getJedis().set("newname", "中文测试");
System.out.println(RedisUtil.getJedis().get("newname"));
}
}
4) 测试运行结果
Run as Junit Test -> See the result!
4 Redis之java操作篇(数据对象的存取)
摘要:Redis本身没有存取对象的功能,而是有存取byte数据的功能,我们可以对要存取的对象进行序列化后,进行操作.
创建SerializeUtil.java
public class SerializeUtil {
/**
* 序列化
* @param object
*/
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
// 序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 反序列化
* @param bytes
*/
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
1) 新建测试对象
package demo.bean; import java.io.Serializable; public class Goods implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6856239042967045162L;
private String name;
private Float price;
private String desc;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
} }
2) 新建测试代码
package demo; import demo.bean.Goods; public class TestObject {
public static void main (String[] args) {
Goods g1 = new Goods();
g1.setName("苹果");
g1.setPrice(5f);
g1.setDesc("这里的苹果大又甜"); Goods g2 = new Goods();
g2.setName("橘子");
g2.setPrice(3.5f);
g2.setDesc("这里的橘子水很多"); RedisUtil.getJedis().set("g1".getBytes(), SerializeUtil.serialize(g1));
byte[] bg1 = RedisUtil.getJedis().get("g1".getBytes());
Goods rg1 = (Goods)SerializeUtil.unserialize(bg1);
System.out.println(rg1.getName());
System.out.println(rg1.getPrice());
System.out.println(rg1.getDesc());
}
}
5 使用mybatis-redis
mybatis-redis是mybatis集成redis实现二级缓存的一个实现,和mybatis-memcached类似,这种方式是mybatis集成redis最快的方式,无需自己编写代码实现cache接口
mybatis-redis的官方git地址https://github.com/mybatis/redis-cache
项目集成mybatis-redis
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
在mybatis配置中开启缓存
<setting name="cacheEnabled" value="true"/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
<!--<setting name="lazyLoadingEnabled" value="false"/>-->
<!--<setting name="aggressiveLazyLoading" value="true"/>-->
</settings>
<plugins>
<!--mybatis 分页插件-->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql" />
</plugin>
</plugins>
</configuration>
在项目的资源(maven resource)目录中加入redis.propertis文件
host=localhost
2 port=6379
timeout=5000
最后在mapper映射文件中开启cache即可
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lisi.test.dao.UserDao">
<!--启用mybatis-redis-->
<cache type="org.mybatis.caches.redis.RedisCache"/>
<resultMap type="User" id="UserResult">
<result property="id" column="id"/>
<result property="uuid" column="uuid"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="createTime" column="create_time"/>
</resultMap>
<insert id="save" parameterType="User">
<selectKey resultType="int" keyProperty="id" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
insert into
t_user(uuid,username,password,create_time)
values(#{uuid},#{username},#{password},#{createTime})
</insert> <delete id="delete" parameterType="long">
delete from t_user where id =
#{id}
</delete> <select id="getById" parameterType="long" resultType="User">
select
id,uuid,username,password,create_time as createTime from t_user
where id=#{id}
</select> <update id="update" parameterType="User">
update t_user set
username=#{username}
where id = #{id}
</update>
</mapper>
6 使用spring-data-redis
spring-data-redis是比较有名的项目,相关资料很多。
使用spring-data-redis的关键依赖,因为用到spring,所以spring的相关依赖是需要加入的。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
mybatis使用spring-data-redis集成redis缓存和第一种方式很相似,都需要自己实现cache接口,只是使用spring-data-redis后方便使用spring的方式来管理,
代码:
/**
* Use JedisConnectionFactory
*/
public class SpringRedisCache implements Cache {
private static Logger logger = LoggerFactory.getLogger(SpringRedisCache.class); private JedisConnectionFactory jedisConnectionFactory = (JedisConnectionFactory)SpringContextHolder.getBean("jedisConnectionFactory");
private final String id; private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); public SpringRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug("SpringRedisCache:id=" + id);
this.id = id;
} @Override
public void clear() {
RedisConnection connection = null;
try {
connection = jedisConnectionFactory.getConnection();
connection.flushDb();
connection.flushAll();
} catch (JedisConnectionException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
} @Override
public String getId() {
return this.id;
} @Override
public Object getObject(Object key) {
Object result = null;
RedisConnection connection = null;
try {
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
result = serializer.deserialize(connection.get(serializer.serialize(key)));
} catch (JedisConnectionException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return result;
} @Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
} @Override
public int getSize() {
int result = 0;
RedisConnection connection = null;
try {
connection = jedisConnectionFactory.getConnection();
result = Integer.valueOf(connection.dbSize().toString());
} catch (JedisConnectionException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return result;
} @Override
public void putObject(Object key, Object value) {
RedisConnection connection = null;
try {
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value));
} catch (JedisConnectionException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
} @Override
public Object removeObject(Object key) {
RedisConnection connection = null;
Object result = null;
try {
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
result = connection.expire(serializer.serialize(key), 0);
} catch (JedisConnectionException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.close();
}
}
return result;
}
}
上面使用的SpringContextHolder源码
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext context; @Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
SpringContextHolder.context = context;
}
public static <T> T getBean(String name){
return (T)context.getBean(name);
}
}
在项目的资源(maven resource)目录中加入redis.propertis文件
redis.host=localhost
redis.port=6379
redis.pass=
redis.timeout=5000
redis.default.db=0
redis.maxIdle=300
redis.maxActive=600
redis.maxWait=1000
redis.testOnBorrow=true
在spring中配置加入
<!-- redis数据池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="maxTotal" value="${redis.maxActive}" />
<property name="maxWaitMillis" value="${redis.maxWait}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- Spring-data-redis connectFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="usePool" value="true"></property>
<property name="hostName" value="${redis.host}" />
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.pass}" />
<property name="timeout" value="${redis.timeout}" />
<property name="database" value="${redis.default.db}"/>
<constructor-arg index="0" ref="jedisPoolConfig" />
</bean>
最后修改mapper文件中cache的type为SpringRedisCache即可;
使用spring-data-redis还可以使用它的RedisTemplate去实现cache接口,不过因为RedisTemplate是对JedisConnectionFactory的包装,在spring配置文件的配置更多.
<!-- Start -->
获知及时信息,请关注我的个人微信订阅号:0与1的那点事
<!-- End -->
本文为博主原创文章,转载请注明出处!
http://www.cnblogs.com/libingbin/
感谢您的阅读。
Redis缓存方案的更多相关文章
- Redis缓存集群方案
由于单台Redis服务器的内存管理能力有限,使用过大内存的Redis又会使得服务器的性能急剧下降,一旦服务器发生故障将会影响更大范围业务,而Redis 3.0 beta1支持的集群功能还不适合生产环境 ...
- 高并发架构系列:Redis缓存和MySQL数据一致性方案详解
一.需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景, ...
- Redis缓存和MySQL数据一致性方案(转)
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- java web开发缓存方案,ehcache和redis哪个更好
Ehcache在java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS中取出来的高花费.高延迟采取的一种缓存方案.正因为Ehcache具有健壮性(基于java开发).被认证(具有apac ...
- 缓存方案之Redis
Redis简介 Redis是Remote Dictionary Server(Redis) 的缩写,或许光听名字你就能猜出它大概是做什么的.不错,它是一个由Salvatore Sanfilippo ...
- 总结:如何使用redis缓存加索引处理数据库百万级并发
前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1000万条数据,可以参考我之前的文章插入数据, ...
- 使用redis缓存加索引处理数据库百万级并发
使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...
- ABP入门系列(13)——Redis缓存用起来
ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 1. 引言 创建任务时我们需要指定分配给谁,Demo中我们使用一个下拉列表用来显示当前系统的所有用 ...
- Spring+SpringMVC+MyBatis+easyUI整合进阶篇(十四)Redis缓存正确的使用姿势
作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 简介 这是一篇关于Redis使用的总结类型文章,会先简单的谈一下缓存 ...
随机推荐
- CAN2.0A帧格式 与 LIN帧格式 简单说明
一.标准的2.0A帧格式 各字段解释:SOF帧开始标志比特是一个显性比特(0),由一个或多个准备发送帧的节点传输.SOF标志着帧的开始(或仲裁发送帧的权利),并用于“硬同步”总线上的设备.只有在开始发 ...
- NEXIQ 125032 USB Link Diesel Truck Diagnose Interface Introduction
What are the features of nexiq usb link? 1.Compatible with applications that diagnose engines, trans ...
- 899. Orderly Queue
A string S of lowercase letters is given. Then, we may make any number of moves. In each move, we c ...
- CDH集群安装配置(四)- mysql 的安装
安装mysql,并且创建相关的表(只需要在chd1上面安装而且需要root权限)1.1 查看Centos自带mysql是否已经安装 yum list installed | grep mysql 卸载 ...
- Macaca 等待机制
看代码注释todo 写博客 服务写脚本开吧 , 因为窗口太多, 不知道要去哪关闭服务 开的话无所谓 , 哪里都能开 要确认是否有开 , 直接跑代码 下面的要先过 别人的环境 工具软件自己的问题 不支 ...
- window server 搭建git服务器
Git服务器Gogs简易安装-Windows环境 1.下载git for windows 1 https://github.com/git-for-windows/git/releases/dow ...
- C 标准库 - string.h之strncpy使用
strncpy 把 src 所指向的字符串复制到 dest,最多复制 n 个字符.当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充. char *strncpy(char *dest ...
- PHP自然排序,非自然排序(未完成)
还要研究一下,暂时先添加个链接 参考:PHP数组的“自然”排序
- a 标签的跳转属性
a 标签中调用js的几种方法 我们常用的在a标签中有点击事件:1. a href="JavaScript:js_method();" 这是我们平台上常用的方法,但是这种方法在 ...
- Java - 让1+1的结果变成3
原出处是国外某论坛某帖子中楼主提问:如何让1+1=3?于是出现了各种语言实现的各种机制的答案,当然其中也包括直接用字符串输出"1+1=3"...最后被采纳的是用Java语言实现的答 ...