携程旅行网技术研发中心资深研发工程师,研发Leader;CSDN博客专家;
能力说明:
精通JVM运行机制,包括类生命、内存模型、垃圾回收及JVM常见参数;能够熟练使用Runnable接口创建线程和使用ExecutorService并发执行任务、识别潜在的死锁线程问题;能够使用Synchronized关键字和atomic包控制线程的执行顺序,使用并行Fork/Join框架;能过开发使用原始版本函数式接口的代码。
阿里云技能认证
详细说明什么是NoSQL? NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。 NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。 RDBMS 回顾 RDBMS即关系数据库管理系统(Relational Database Management System),是将数据组织为相关的行和列的系统,而管理关系数据库的计算机软件就是关系数据库管理系统,常用的数据库软件有Oracle、SQL Server等。 关系型数据库遵循ACID规则 事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性: 1、A (Atomicity) 原子性 原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。 比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。 2、C (Consistency) 一致性 一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。 例如现有完整性约束a+b=10,如果一个事务改变了a,那么必须得改变b,使得事务结束后依然满足a+b=10,否则事务失败。 3、I (Isolation) 独立性 所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。 比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的。 4、D (Durability) 持久性 持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。 RDBMS vs NoSQL RDBMS - 高度组织化结构化数据 - 结构化查询语言(SQL) - 数据和关系都存储在单独的表中。 - 数据操纵语言,数据定义语言 - 严格的一致性 - 基础事务 NoSQL - 代表着不仅仅是SQL - 没有声明性查询语言 - 没有预定义的模式 -键 - 值对存储,列存储,文档存储,图形数据库 - 最终一致性,而非ACID属性 - 非结构化和不可预知的数据 - CAP定理 - 高性能,高可用性和可伸缩性 NoSQL的优点/缺点 优点: · - 高可扩展性 · - 分布式计算 · - 低成本 · - 架构的灵活性,半结构化数据 · - 没有复杂的关系 缺点: · - 没有标准化 · - 有限的查询功能(到目前为止) · - 最终一致是不直观的程序 CAP定理(CAP theorem) 在计算机科学中, CAP定理(CAP theorem), 又被称作 布鲁尔定理(Brewer's theorem), 它指出对于一个分布式计算系统来说,不可能同时满足以下三点: · 一致性(Consistency) (所有节点在同一时间具有相同的数据) · 可用性(Availability) (保证每个请求不管成功或者失败都有响应) · 分隔容忍(Partition tolerance) (系统中任意信息的丢失或失败不会影响系统的继续运作) CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。 因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类: · CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。 · CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。 · AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。 · NoSQL 数据库分类 类型 部分代表 特点 列存储 Hbase Cassandra Hypertable 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 文档存储 MongoDB CouchDB 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。 key-value存储 Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能) 图存储 Neo4J FlockDB 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便。 对象存储 db4o Versant 通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 xml数据库 Berkeley DB XML BaseX 高效的存储XML数据,并支持XML的内部查询语法,比如XQuery,Xpath。
从List中拿出top指的条数数据: /** * 取top x条产品类数据 * * @param sourList 产品类集合 * @param rowsCount 条数 * @return List<ProductInfo> */ public static List<ProductInfo> limitProductInfoList(List<ProductInfo> sourList, int rowsCount) { List<ProductInfo> tempList = new ArrayList<>(); if (sourList != null) { int sourListSize = sourList.size(); if (rowsCount < sourListSize) { int subCount = sourListSize % rowsCount == 0 ? sourListSize / rowsCount : sourListSize / rowsCount + 1; int startIndext = 0; int stopIndext = 0; for (int i = 0; i < subCount; i++) { stopIndext = (i == subCount - 1) ? stopIndext + sourListSize % rowsCount : stopIndext + rowsCount; tempList = new ArrayList<ProductInfo>(sourList.subList(startIndext, stopIndext)); startIndext = stopIndext; if (tempList.size() > 0) { break; } } } else { tempList = sourList; } } return tempList; } 比较字符串是否在数组中: private static String[] StarArray = new String[]{"DHTL", "IHTL", "GPKG", "GDIY", "GCRU"}; ArrayUtils.contains(StarArray, "DHTL") //验证对象为null if (ObjectUtils.equals(sysRole, null)) { sysRole = this.getRole(systemCode, loginName); } //验证List if (CollectionUtils.isNotEmpty(sysRoleList)) { sysRole = sysRoleList.get(0); } //验证字符串-验证时候忽略空白 if (StringUtils.isBlank(formData.getPost())){ } //验证字符串非空 if (StringUtils.isNotEmpty(userCard.getUID())) /** * 清除空白字符 * * @param str * @return */ public static String trimAllWhitespace(String str) { if (str != null) { int len = str.length(); if (len > 0) { char[] dest = new char[len]; int destPos = 0; for (int i = 0; i < len; ++i) { char c = str.charAt(i); if (!Character.isWhitespace(c)) { dest[destPos++] = c; } } return new String(dest, 0, destPos); } } return str; } /** *list转换string * @param list List<String> * @param separator 分隔符 逗号等 * @return */ public static String listToString(List<String> list, char separator) { return org.apache.commons.lang.StringUtils.join(list.toArray(), separator); } /** *string转换list * @param str 分隔符字符串 * @param separator 逗号等 * @return List<String> */ public static List<String> stringToList(String str, String separator) { return java.util.Arrays.asList(str.split(separator)); }
https://www.liaoxuefeng.com/article/001463233913442cdb2d1bd1b1b42e3b0b29eb1ba736c5e000
FastJson时间格式化: @JSONField(format = “yyyy-MM-dd hh:mm:ss”) 单元测试加载Spring配置: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = “classpath:spring/spring-context.xml”) @WebAppConfiguration 读取.properties文件: @Value(“${ShortURLAPIAddress}”) 用于标注业务层组件: @Service 用于标注控制层组件(如struts中的action): @Controller 用于标注数据访问组件,即DAO组件: @Repository 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注: @Component 注释使得接口可以被容器注入: @Autowired
由于系统采用springmvc框架,springmvc核心控制器DispatcherServlet 默认为每个controller生成单一实例来处理所有用户请求,所以在这个单一实例的controller中,它的XXXService也是一个实例处理所有请求, 这样XXXService的成员变量就被所有请求共享。这样就会出现并发请求时变量内容被篡改的问题。 那么出现这种问题如何解决呢? 第一种方式: 既然是全局变量惹的祸,那就将全局变量都编程局部变量,通过方法参数来传递,但是如果多个方法都需要该参数的话,传参就相当繁琐。 第二种方式: jdk提供了java.lang.ThreadLocal,它为多线程并发提供了新思路。 (当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本) ThreadLocal类用来提供线程内部的局部变量。这些变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是private static类型。 总结:ThreadLocal不是为了解决多线程访问共享变量,而是为每个线程创建一个单独的变量副本,提供了保持对象的方法和避免参数传递的复杂性。 父类ThreadLocal定义: //存储MessageContentModel对象,防止对象并发覆盖 private ThreadLocal<MessageContentModel> msgContentModelTL = new ThreadLocal<MessageContentModel>(); //存储HandlerContext对象,防止对象并发覆盖 private ThreadLocal<HandlerContext> contextModelTL = new ThreadLocal<HandlerContext>(); 父类设置对象值: /** * 日志对象 */ public HandlerContext getContext() { return contextModelTL.get() != null ? contextModelTL.get() : new HandlerContext(); } private void setContext(HandlerContext context) { contextModelTL.set(context); } /** * 消息内容服务公用模型 */ public MessageContentModel getMsgContentModel() { return msgContentModelTL.get() != null ? msgContentModelTL.get() : new MessageContentModel(); } private void setMsgContentModel(MessageContentModel msgContentModel) { msgContentModelTL.set(msgContentModel); } 子类使用: this.getContext().writeLogTag("获取链接失败"); ThreadLocal的主要应用场景为按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。例如:同一个网站登录用户,每个用户服务器会为其开一个线程,每个线程中创建一个ThreadLocal,里面存用户基本信息等,在很多页面跳转时,会显示用户信息或者得到用户的一些信息等频繁操作,这样多线程之间并没有联系而且当前线程也可以及时获取想要的数据。 实现原理: ThreadLocal可以看做是一个容器,容器里面存放着属于当前线程的变量。ThreadLocal类提供了四个对外开放的接口方法,这也是用户操作ThreadLocal类的基本方法: (1) void set(Object value)设置当前线程的线程局部变量的值。 (2) public Object get()该方法返回当前线程所对应的线程局部变量。 (3) public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。 (4) protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次,ThreadLocal中的缺省实现直接返回一个null。 可以通过上述的几个方法实现ThreadLocal中变量的访问,数据设置,初始化以及删除局部变量,那ThreadLocal内部是如何为每一个线程维护变量副本的呢? 其实在ThreadLocal类中有一个静态内部类ThreadLocalMap(其类似于Map),用键值对的形式存储每一个线程的变量副本,ThreadLocalMap中元素的key为当前ThreadLocal对象,而value对应线程的变量副本,每个线程可能存在多个ThreadLocal。 http://blog.csdn.net/lhqj1992/article/details/52451136
ArrayList转数组 /* * 获取优惠券全部策略ID String[] */ private String[] getStrategyIDArrayCache() throws Exception { ArrayList<String> list = new ArrayList<String>(); String[] strArray = new String[] {}; int RightsType = BusinessEmun.RightsType.优惠券.getValue(); List<McRights> resultList = cacheManagement.rightsListCache.getData(RightsType); if (resultList != null && resultList.size() > 0) { for (McRights mcRights : resultList) { list.add(mcRights.getStrategyID()); } if (list.size() > 0) { strArray = (String[]) list.toArray(new String[0]); } } return strArray; } 验证是否在String[] arr范围内 /** * 验证是否在String[] arr范围内 * * @Title: IsContains * @Description: TODO * @param * @return * @throws */ private boolean isContains(String[] arr, String targetValue) { int a = Arrays.binarySearch(arr, targetValue); if (a >= 0) return true; else return false; } 根据属性名获取属性值 /** * @Title: getFieldValueByName * @Description: 根据属性名获取属性值 * @param obj:需要查找的对象,fieldName:对象属性 * @return 得到结果对象 * @throws */ private Object getFieldValueByName(Object obj, String fieldName) { try { String firstLetter = fieldName.substring(0, 1).toUpperCase(); String getter = "get" + firstLetter + fieldName.substring(1); Method method = obj.getClass().getMethod(getter, new Class[]{}); Object value = method.invoke(obj, new Object[]{}); return value; } catch (Exception e) { Logger.error("getFieldValueByName异常", e); return null; } }
spark基本概念 http://www.cnblogs.com/shexinwei/p/4823051.html Spark异步job http://www.cnblogs.com/shexinwei/p/5148573.html Spark Streaming 源码详解 http://www.cnblogs.com/shexinwei/p/5042515.html Apache Spark installation on Windows 10 https://hernandezpaul.wordpress.com/2016/01/24/apache-spark-installation-on-windows-10/ http://spark.apache.org/sql/ http://spark.apache.org/docs/latest/sql-programming-guide.html http://spark.apache.org/docs/latest/programming-guide.html
Thymeleaf Thymeleaf是一个页面模板,类似于Freemarker、Velocity等,但Thymeleaf可以在服务器环境和静态环境下都能正常运行的页面模板,深受前后端分离开发的团队人员的青睐。 Thymeleaf的数据展现全部通过以th:开头的html自定义标签来完成。当运行在服务器环境时将会按规则替换th:对应的地方显示出服务器上的数据,当运行在静态环境时,html会自动过虑th:开头的属性,显示默认的数据,从而达到两者都能正常运行。 本人对Thymeleaf接触的时间不长,最开始使用的时候有些痛苦,但越用感觉越好用,使用起来也比较方便灵活。 示例仓库:https://github.com/zsl131/thymeleaf-study 官方: http://www.thymeleaf.org/ 其他资料: http://www.zslin.com/?cateId=5
maven一些常用命令 安装包到本地 Dfile=D:\workspace\Marketing.MessagePush.Service\messagepush\lib\guava-18.0.jar -DgroupId=com.google.guava -DartifactId=guava -Dversion=18.0 -Dpackaging=jar 记录mvn命令执行信息到txt mvn dependency:tree –> tree.txt mvn install–> install.txt 查找包依赖tree mvn dependency:tree -Dverbose -Dincludes=:commons-collections:jar 清理 编译 跳过单元测试 mvn clean -Dmaven.test.skip=true install 设置jar包统一版本 <dependencyManagement> <dependencies> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-core-asl</artifactId> <version>1.9.13</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.13</version> </dependency> </dependencies> </dependencyManagement>
Creating custom data graphics in Visio https://blogs.office.com/2014/06/30/creating-custom-data-graphics-in-visio/
org.apache.poi HSSFWorkbook中设置Excel单元格格式样式(居中,字体,边框等) HSSFCellStyle cellStyle = wb.createCellStyle(); 一、设置背景色: cellStyle.setFillForegroundColor((short) 13);// 设置背景色 cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); 二、设置边框: cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下边框 cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);//左边框 cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);//上边框 cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);//右边框 三、设置居中: cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中 四、设置字体: HSSFFont font = wb.createFont(); font.setFontName("黑体"); font.setFontHeightInPoints((short) 16);//设置字体大小 HSSFFont font2 = wb.createFont(); font2.setFontName("仿宋_GB2312"); font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示 font2.setFontHeightInPoints((short) 12); cellStyle.setFont(font);//选择需要用到的字体格式 五、设置列宽: sheet.setColumnWidth(0, 3766); //第一个参数代表列id(从0开始),第2个参数代表宽度值 参考 :"2012-08-10"的宽度为2500 六、设置自动换行: cellStyle.setWrapText(true);//设置自动换行 七、合并单元格: Region region1 = new Region(0, (short) 0, 0, (short) 6);//参数1:行号 参数2:起始列号 参数3:行号 参数4:终止列号 //此方法在POI3.8中已经被废弃,建议使用下面一个 或者用 CellRangeAddress region1 = new CellRangeAddress(rowNumber, rowNumber, (short) 0, (short) 11); //参数1:起始行 参数2:终止行 参数3:起始列 参数4:终止列 但应注意两个构造方法的参数不是一样的,具体使用哪个取决于POI的不同版本。 sheet.addMergedRegion(region1);
查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的: Ajax 文件下载: jQuery.download = function(url, data, method){ // 获得url和data if( url && data ){ // data 是 string 或者 array/object data = typeof data == 'string' ? data : jQuery.param(data); // 把参数组装成 form的 input var inputs = ''; jQuery.each(data.split('&'), function(){ var pair = this.split('='); inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />'; }); // request发送请求 jQuery('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>') .appendTo('body').submit().remove(); }; }; 用调例实: $.download('../ConfigRights/ExportExcel', condition, 'post');
idea和sonar的集合使用 http://www.cnblogs.com/milletes/p/5985957.html sonar代码审查问题总结 http://blog.csdn.net/xingchao416/article/details/52816882
Intellj 自动载入Mave依赖的功能很好用,但有时候会碰到问题,导致pom文件修改却没有触发自动重新载入的动作,此时需要手动强制更新依赖。 如下: 手动删除Project Settings里面的Libraries内容; 在Maven Project的试图里clean一下,删除之前编译过的文件; 项目右键-》Maven-》Reimport
jvisualvm远程监控Tomcat: http://ihuangweiwei.iteye.com/blog/1219302 使用 VisualVM 进行性能分析及调优: http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/ Java jvisualvm简要说明: http://blog.csdn.net/a19881029/article/details/8432368
Intro to Filtering with Network Monitor 3.0: https://blogs.technet.microsoft.com/netmon/2006/10/17/intro-to-filtering-with-network-monitor-3-0/ IP检索: Contains(property.Description,’10.2.81.140’)
http://www.cnblogs.com/kekec/archive/2012/12/02/2798020.html
PerfView抓取dump和dump比较步骤截图: 其他相关文章: 性能分析工具-PerfView http://www.cnblogs.com/shanyou/p/3773998.html 使用PerfView诊断.Net GC的问题 http://www.cnblogs.com/lenshen/p/3961026.html
Java开发中SecureCRT抓dump和使用Jstack查看线程步骤实践: sudo su – 切换到root ps -ef | grep java 查看进程PID top -H -p [PID] 查看当前应用PID子线程数 /usr/java/jdk1.7.0_51/bin 退回到opt上级目录后切换到jdk bin目录 抓dump: /usr/java/jdk1.7.0_51/bin/jmap -F -dump:format=b,file=/tmp/XXXX.dmp [PID] 对当前PID进行抓dump操作 Sz /tmp/XXXX.dmp 下载dump到本地客户端,默认保存在下载文件夹 使用Jstack查看线程: /usr/java/jdk1.7.0_51/bin 退回到opt上级目录后切换到jdk bin目录 ./jstack -l [PID] 或 ./jstack -F [PID] 打印出全部线程使用情况 保存Seesion到本地电脑: 需要预先设置会话保存位置,可以把本次会话全部记录到本地文本文件中,方便后面分析;
客户提交一个dump文件,WinDbg加载时出现大量WARNING,加载对应版本的SOS后执行相应命令提示”SOS does not support the current target architecture”。 原因在于使用了64位的任务管理器导出了32位进程的dump文件,下面是两个解决方法: 1、使用32位任务管理器,运行:C:\Windows\SysWOW64\taskmgr.exe。 2、使用其它转储工具,比如:ProcessExplorer。 参考资料: Capturing memory dumps for 32-bit processes on an x64 machine
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉。 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和 volatile 关键字机制。 synchronized 同步块大家都比较熟悉,通过 synchronized 关键字来实现,所有加上synchronized 和 块语句,在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法 或者 代码块。 volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。 下面看一个例子,我们实现一个计数器,每次线程启动的时候,会调用计数器inc方法,对计数器进行加一 执行环境——jdk版本:jdk1.6.0_31 ,内存 :3G cpu:x86 2.4G public class Counter { public static int count = 0; public static void inc() { //这里延迟1毫秒,使得结果明显 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 for (int i = 0; i < 1000; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } //这里每次运行的值都有可能不同,可能为1000 System.out.println("运行结果:Counter.count=" + Counter.count); } } 运行结果:Counter.count=995 实际运算结果每次可能都不一样,本机的结果为:运行结果:Counter.count=995,可以看出,在多线程的环境下,Counter.count并没有期望结果是1000 很多人以为,这个是多线程并发问题,只需要在变量count之前加上volatile就可以避免这个问题,那我们在修改代码看看,看看结果是不是符合我们的期望 public class Counter { public volatile static int count = 0; public static void inc() { //这里延迟1毫秒,使得结果明显 try { Thread.sleep(1); } catch (InterruptedException e) { } count++; } public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 for (int i = 0; i < 1000; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } //这里每次运行的值都有可能不同,可能为1000 System.out.println("运行结果:Counter.count=" + Counter.count); } } 运行结果:Counter.count=992 运行结果还是没有我们期望的1000,下面我们分析一下原因 在 java 垃圾回收整理一文中,描述了jvm运行时刻内存的分配。其中有一个内存区域是jvm虚拟机栈,每一个线程运行时都有一个线程栈, 线程栈保存了线程运行时候变量值信息。当线程访问某一个对象时候值的时候,首先通过对象的引用找到对应在堆内存的变量的值,然后把堆内存 变量的具体值load到线程本地内存中,建立一个变量副本,之后线程就不再和对象在堆内存变量值有任何关系,而是直接修改副本变量的值, 在修改完之后的某一个时刻(线程退出之前),自动把线程变量副本的值回写到对象在堆中变量。这样在堆中的对象的值就产生变化了。 文章出处:http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html IBM Java 理论与实践: 正确使用 Volatile 变量: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
IntelliJ IDEA 注册码: http://idea.lanyus.com/
Microsoft Network Monitor 查询命令: Contains(property.Description,’10.2.81.140’) 微软介绍地址: https://blogs.technet.microsoft.com/netmon/2006/10/17/intro-to-filtering-with-network-monitor-3-0/ MySQL查询命令: 1,) INDEX的定义 SHOW INDEXES from tablename 2.) 表的scheme。 EXPLAIN tablename 3,) SQL的执行计划 EXPLAIN SELECT * FROM tablename 4,) 每个表的大概的行数,行的大小等 SHOW TABLE STATUS FROM DBNAME 5,) 删除表中的所有行,而不记录单个行删除操作。 TRUNCATE TABLE tablename; 6,) 查询字段和字段说明、类型 SELECT column_name,column_comment,data_type FROM information_schema.columns WHERE table_name=’mc_usercardupgradelog’ AND table_schema = “mktusermarketingdb”; MySQL Workbench 6.0 CE 当前时间: CURRENT_TIMESTAMP 最后更新时间: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Java 客户端: public void scaneByPrefixFilter(String tablename, String rowPrifix) { try { HTable table = new HTable(conf, tablename); Scan s = new Scan(); s.setFilter(new PrefixFilter(rowPrifix.getBytes())); ResultScanner rs = table.getScanner(s); for (Result r : rs) { KeyValue[] kv = r.raw(); for (int i = 0; i < kv.length; i++) { System.out.print(new String(kv[i].getRow()) + " "); System.out.print(new String(kv[i].getFamily()) + ":"); System.out.print(new String(kv[i].getQualifier()) + " "); System.out.print(kv[i].getTimestamp() + " "); System.out.println(new String(kv[i].getValue())); } } } catch (IOException e) { e.printStackTrace(); } }
java代码对象如下: package com.ctrip.market.messagepush.service.entity; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; public class WaitSendModel { public long MsgID; public String GroupID; public int SendLevel; public int SendType; public long getMsgID() { return MsgID; } public void setMsgID(long msgID) { this.MsgID = msgID; } public String getGroupID() { return GroupID; } public void setGroupID(String groupID) { this.GroupID = groupID; } public int getSendLevel() { return SendLevel; } public void setSendLevel(int sendLevel) { this.SendLevel = sendLevel; } public int getSendType() { return SendType; } public void setSendType(int sendType) { this.SendType = sendType; } } 执行结果,首字母小写: Json={"msgID":100005,"groupID":"00001","sendLevel":5} 以上的对象如果通过jackson转成json格式的话,首字母会自动变成小写,如果我想让首字母变成大写的,该如何处理呢? 在属性上加@JsonProperty 注解,并且在对应的setter ,getter 上面加上@JsonIgnore,这样就可以了,添加完之后的代码如下: package com.ctrip.market.messagepush.service.entity; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; public class WaitSendModel { @JsonProperty public long MsgID; @JsonProperty public String GroupID; @JsonProperty public int SendLevel; @JsonProperty public int SendType; @JsonIgnore public long getMsgID() { return MsgID; } @JsonIgnore public void setMsgID(long msgID) { this.MsgID = msgID; } @JsonIgnore public String getGroupID() { return GroupID; } @JsonIgnore public void setGroupID(String groupID) { this.GroupID = groupID; } @JsonIgnore public int getSendLevel() { return SendLevel; } @JsonIgnore public void setSendLevel(int sendLevel) { this.SendLevel = sendLevel; } @JsonIgnore public int getSendType() { return SendType; } @JsonIgnore public void setSendType(int sendType) { this.SendType = sendType; } } 执行结果,首字母大写: Json={"MsgID":100005,"GroupID":"00001","SendLevel":5,"SendType":0}
去哪儿-余昭辉 http://www.cnblogs.com/yuyijq/default.aspx?page=2 Jacky http://www.cnblogs.com/WCFGROUP/ 李林峰的园子 http://www.cnblogs.com/iamlilinfeng/ 日交易额百亿级交易系统的超轻量日志实现 http://www.cnblogs.com/cyfonly/p/6139049.html happyframework http://www.cnblogs.com/happyframework/
Maven库: http://repo2.maven.org/maven2/ Maven依赖查询: http://mvnrepository.com/ Maven常用命令: 1. 创建Maven的普通java项目: mvn archetype:create -DgroupId=packageName -DartifactId=projectName 2. 创建Maven的Web项目: mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp 3. 编译源代码: mvn compile 4. 编译测试代码:mvn test-compile 5. 运行测试:mvn test 6. 产生site:mvn site 7. 打包:mvn package 8. 在本地Repository中安装jar:mvn install 9. 清除产生的项目:mvn clean 10. 生成eclipse项目:mvn eclipse:eclipse 11. 生成idea项目:mvn idea:idea 12. 组合使用goal命令,如只打包不测试:mvn -Dtest package 13. 编译测试的内容:mvn test-compile 14. 只打jar包: mvn jar:jar 15. 只测试而不编译,也不测试编译:mvn test -skipping compile -skipping test-compile ( -skipping 的灵活运用,当然也可以用于其他组合命令) 16. 清除eclipse的一些系统设置:mvn eclipse:clean ps: 一般使用情况是这样,首先通过cvs或svn下载代码到本机,然后执行mvn eclipse:eclipse生成ecllipse项目文件,然后导入到eclipse就行了;修改代码后执行mvn compile或mvn test检验,也可以下载eclipse的maven插件。 mvn -version/-v 显示版本信息 mvn archetype:generate 创建mvn项目 mvn archetype:create -DgroupId=com.oreilly -DartifactId=my-app 创建mvn项目 mvn package 生成target目录,编译、测试代码,生成测试报告,生成jar/war文件 mvn jetty:run 运行项目于jetty上, mvn compile 编译 mvn test 编译并测试 mvn clean 清空生成的文件 mvn site 生成项目相关信息的网站 mvn -Dwtpversion=1.0 eclipse:eclipse 生成Wtp插件的Web项目 mvn -Dwtpversion=1.0 eclipse:clean 清除Eclipse项目的配置信息(Web项目) mvn eclipse:eclipse 将项目转化为Eclipse项目 在应用程序用使用多个存储库 Ibiblio Ibiblio http://www.ibiblio.org/maven/ PlanetMirror Planet Mirror http://public.planetmirror.com/pub/maven/ mvn deploy:deploy-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DrepositoryId=maven-repository-inner -Durl=ftp://xxxxxxx/opt/maven/repository/ 发布第三方Jar到本地库中: mvn install:install-file -DgroupId=com -DartifactId=client -Dversion=0.1.0 -Dpackaging=jar -Dfile=d:\client-0.1.0.jar -DdownloadSources=true -DdownloadJavadocs=true mvn -e 显示详细错误 信息. mvn validate 验证工程是否正确,所有需要的资源是否可用。 mvn test-compile 编译项目测试代码。 。 mvn integration-test 在集成测试可以运行的环境中处理和发布包。 mvn verify 运行任何检查,验证包是否有效且达到质量标准。 mvn generate-sources 产生应用需要的任何额外的源代码,如xdoclet。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lifxue/archive/2009/10/14/4662902.aspx 常用命令: mvn -v 显示版本 mvn help:describe -Dplugin=help 使用 help 插件的 describe 目标来输出 Maven Help 插件的信息。 mvn help:describe -Dplugin=help -Dfull 使用Help 插件输出完整的带有参数的目标列 mvn help:describe -Dplugin=compiler -Dmojo=compile -Dfull 获取单个目标的信息,设置 mojo 参数和 plugin 参数。此命令列出了Compiler 插件的compile 目标的所有信息 mvn help:describe -Dplugin=exec -Dfull 列出所有 Maven Exec 插件可用的目标 mvn help:effective-pom 看这个“有效的 (effective)”POM,它暴露了 Maven的默认设置 mvn archetype:create -DgroupId=org.sonatype.mavenbook.ch03 -DartifactId=simple -DpackageName=org.sonatype.mavenbook 创建Maven的普通java项目,在命令行使用Maven Archetype 插件 mvn exec:java -Dexec.mainClass=org.sonatype.mavenbook.weather.Main Exec 插件让我们能够在不往 classpath 载入适当的依赖的情况下,运行这个程序 mvn dependency:resolve 打印出已解决依赖的列表 mvn dependency:tree 打印整个依赖树 mvn install -X 想要查看完整的依赖踪迹,包含那些因为冲突或者其它原因而被拒绝引入的构件,打开 Maven 的调试标记运行 mvn install -Dmaven.test.skip=true 给任何目标添加maven.test.skip 属性就能跳过测试 mvn install assembly:assembly 构建装配Maven Assembly 插件是一个用来创建你应用程序特有分发包的插件 mvn jetty:run 调用 Jetty 插件的 Run 目标在 Jetty Servlet 容器中启动 web 应用 mvn compile 编译你的项目 mvn clean install 删除再编译 mvn hibernate3:hbm2ddl 使用 Hibernate3 插件构造数据库
之前写了一个登录表单页面,再iphone上测试遇到了一些奇怪的问题:表单中的input[type=”submit”]按钮在iPhone的safari浏览器下会出现圆角的情况;input[type=”text”]文本输入框会有内阴影,这些问题该怎么处理呢? 阴影图片: 正常图片: 在IOS下,input 表单默认会有个内阴影,一定程度上影响视觉一致,可通过设置下面代码去掉: input{ -webkit-appearance: none; } 如果你还没有碰到,或者你也在开发移动端web,都希望你记住这个小技巧,因为当你在制作中碰到这样的问题时,不会为此抓破头皮,能解决你问题。
C#中类型Type有个GetMethod方法,调用该方法可获取指定方法名的方法信息实例。 使用时,其参数一般为2个,一个是方法名称字符串(可设置条件忽略大小写),另外一个参数为搜索方法的条件枚举。 该方法返回的是MethodInfo类型的实例,获取到了这个实例之后,我们就可以调用并执行该方法了。 MethodInfo method = type.GetMethod( funcName , BindingFlags.IgnoreCase | BindingFlags.Static | BindingFlags.Public ); 这里要注意,搜索条件枚举,即第2个参数,要包含BindingFlags.Public,否则会返回NULL的。 如果是静态的方法,还要设置一个条件BindingFlags.Static。 得到了MethodInfo实例后,反射执行该方法: method.Invoke( obj, arrParam ); obj为调用方法所属的类型实例,如果调用的为静态方法,可设置为null;arrParam为方法参数数组。 通过method.Invoke执行实例: protected void btnExecute_Click(object sender, EventArgs e) { try { var Job_CleanLogDataType = _Job_HermesEDMSubscripton.GetType(); string paramsText = this.txtParam.Text; ThreadPool.QueueUserWorkItem((_) => { var methodInfo = Job_CleanLogDataType.GetMethod("OnStart", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase); methodInfo.Invoke(_Job_HermesEDMSubscripton, new object[] { paramsText }); }); this.lblMsg.Text = "执行OnStart完成"; } catch (Exception ex) { this.lblMsg.Text = ex.ToString(); } }
在java项目开发中考虑到在使用HashMap在并发时会出现不正确行为,自己编写了采用static ConcurrentHashMap来完成静态缓存的处理,目的是为了能够用来处理高并发的线程安全类,如有问题请各指教: package com.hlwfarm.market.service; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.ctrip.market.commom.CLogger; import com.ctrip.market.commom.DateTimeUtil; import com.ctrip.market.commom.Distance; import com.ctrip.market.commom.ServiceFactory; import com.ctrip.market.entity.GfMsgscene; public class MapCacheManager { private static CLogger<MapCacheManager> logger = new CLogger<MapCacheManager>(); private volatile long updateTime = 0L;// 更新缓存时记录的时间 private volatile boolean updateFlag = true;// 正在更新时的阀门,为false时表示当前没有更新缓存,为true时表示当前正在更新缓存 private static Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>();// 缓存容器 private static GfMsgsceneService gfMsgsceneService = (GfMsgsceneService) ServiceFactory .getInstance("gfMsgsceneService");// 场景信息 public MapCacheManager() { this.LoadCache();// 加载缓存 updateTime = System.currentTimeMillis();// 缓存更新时间 } /** * 装载缓存 */ private void LoadCache() { this.updateFlag = true;// 正在更新 /********** 数据处理,将数据放入cacheMap缓存中 **begin ******/ List<GfMsgscene> sceneList = gfMsgsceneService.queryByDateList(); cacheMap.put("sceneList", sceneList); cacheMap.put("key2", "value2"); logger.info("更新缓存完成", "更新缓存完成, date=" + DateTimeUtil.GetNowDateString()); System.out.println("更新缓存完成:" + DateTimeUtil.GetNowDateString()); /********** 数据处理,将数据放入cacheMap缓存中 ***end *******/ this.updateFlag = false;// 更新已完成 } /** * 返回缓存单个对象 * * @return */ public Object getObjectCache(String key) { long currentTime = System.currentTimeMillis(); synchronized (this) { // 如果当前缓存正在更新或者缓存超出时限,需重新加载 if (this.IsTimeOut(currentTime)) { this.ReLoadCache(); this.updateTime = currentTime; } } return this.cacheMap.get(key); } private boolean IsTimeOut(long currentTime) { logger.info("up", "up=" + (currentTime - this.updateTime)); return ((currentTime - this.updateTime) >= 1000 * 60 * 10);// 超过时限,缓存1分钟 } /** * 获取缓存项大小 * * @return */ private int getCacheSize() { return cacheMap.size(); } /** * 获取更新时间 * * @return */ private long getUpdateTime() { return this.updateTime; } /** * 获取更新标志 * * @return */ private boolean getUpdateFlag() { return this.updateFlag; } /** * 重新装载 */ private void ReLoadCache() { this.cacheMap.clear(); this.LoadCache(); } /** * @ClassName: CacheKeyEnum * @Description: 缓存数据key枚举 */ public enum CacheKeyEnum { sceneList, } } /** * 返回缓存全部 * * @return */ public Map<String, Object> getMapCache() { long currentTime = System.currentTimeMillis(); // 如果当前缓存正在更新或者缓存超出时限,需重新加载 if (this.IsTimeOut(currentTime)) { synchronized (this) { this.ReLoadCache(); this.updateTime = currentTime; } } return this.cacheMap; } 单元测试: public class CacheTest { private static MapCacheManager cache = new MapCacheManager(); @Test public void test() { for (int i = 0; i < 10; i++) { Map<String, Object> cacheMap = new ConcurrentHashMap<String, Object>(); cacheMap = cache.getMapCache(); Set<String> set = cacheMap.keySet(); Iterator<String> it = set.iterator(); while (it.hasNext()) { String key = it.next(); System.out.println(key + "=" + JsonSerializer.serialize(cacheMap.get(key))); } } } }
问题说明 : 今天在web应用中用到了Java多线程的技术来并发处理一些业务,但在执行时一直会报NullPointerException的错误,问题定位了一下发现是线程中的Spring bean没有被注入,bean对象的值为null。 原因分析 : web容器在启动应用时,并没有提前将线程中的bean注入(在线程启动前,web容易也是无法感知的) 解决方案 : 线程中获取bean import org.springframework.context.ApplicationContext; public class ServiceFactory { public static ApplicationContext context=null; public static Object getInstance(String serviceName){ if (null==context) { context=ApplicationContextLoaderListener.getApplicationContext(); } return context.getBean(serviceName); } } @Override public void run() { // 记录推荐记录 GfRegistrationService gfRegistrationService = (GfRegistrationService) ServiceFactory.getInstance("gfRegistrationService"); List<GfRegistration> insertRegistrationlist = this.getGfRegistrationlist(); if (insertRegistrationlist.size() > 0) { int[] resultArry = gfRegistrationService.batchInsert(insertRegistrationlist); if (resultArry.length > 0) { logger.info("信息批量记录", "批量记录信息,length= " + resultArry.length); } else { logger.info("信息批量记录", "推荐商户信息为空"); } } }
在矩形范围内随机生成经纬度: /** * @Title: randomLonLat * @Description: 在矩形内随机生成经纬度 * @param MinLon:最新经度 MaxLon: 最大经度 MinLat:最新纬度 MaxLat:最大纬度 type:设置返回经度还是纬度 * @return * @throws */ public String randomLonLat(double MinLon, double MaxLon, double MinLat, double MaxLat, String type) { Random random = new Random(); BigDecimal db = new BigDecimal(Math.random() * (MaxLon - MinLon) + MinLon); String lon = db.setScale(6, BigDecimal.ROUND_HALF_UP).toString();// 小数后6位 db = new BigDecimal(Math.random() * (MaxLat - MinLat) + MinLat); String lat = db.setScale(6, BigDecimal.ROUND_HALF_UP).toString(); if (type.equals("Lon")) { return lon; } else { return lat; } }
java经纬度两点距离计算方法,返回单位米: public class Distance { private static CLogger<Distance> logger = new CLogger<Distance>(); /** * 计算地球上任意两点(经纬度)距离 * * @param long1 第一点经度 * @param lat1 第一点纬度 * @param long2 第二点经度 * @param lat2 第二点纬度 * @return 返回距离 单位:米 */ public static double Distance(double long1, double lat1, double long2, double lat2) { long start = System.nanoTime(); double a, b, R; R = 6378137; // 地球半径 lat1 = lat1 * Math.PI / 180.0; lat2 = lat2 * Math.PI / 180.0; a = lat1 - lat2; b = (long1 - long2) * Math.PI / 180.0; double d; double sa2, sb2; sa2 = Math.sin(a / 2.0); sb2 = Math.sin(b / 2.0); d = 2 * R * Math.asin(Math.sqrt(sa2 * sa2 + Math.cos(lat1) * Math.cos(lat2) * sb2 * sb2)); double TimeMillis = ElapsedTimeUtil.GetElapsedTime(start); logger.info("计算经纬度距离耗时", "TimeMillis= " + TimeMillis); MetricElapsedTime.log(ElapsedNameEnum.计算经纬度距离耗时, TimeMillis); return d; } } 计算地球上两个坐标点(经度,纬度)之间距离sql函数: http://www.cnblogs.com/chenmfly/p/4472785.html
java自习网上资料收集,自学java、转java可能常用到的写文章,例如排序、正则、SpringMVC Java:初学 Java,遇到的问题及解决方案小结 http://www.cnblogs.com/happyframework/p/3349917.html 用Java集合中的Collections.sort方法对list排序的两种方法: http://www.open-open.com/lib/view/open1322614659562.html http://blog.csdn.net/superhill/article/details/7837106 Java 正则表达式: 在线正则验证工具 http://tool.oschina.net/regex/ 正则基础 http://www.runoob.com/java/java-regular-expressions.html java 正则表达式匹配斜杠 http://wangsong76.iteye.com/blog/352982 Java正则表达式替换所有特殊字符 http://blog.csdn.net/lqclh502/article/details/47448135 JAVA正则表达式匹配,替换,查找,切割 http://www.cnblogs.com/jxgxy/archive/2012/07/30/2615997.html SpringMVC: SpringMVC(1)入门之环境搭建与页面数据传递 http://blog.163.com/zhangmihuo_2007/blog/static/27011075201452811058561/ 【@ContextConfiguration】java世界的那些注解 http://www.cnblogs.com/viewcozy/p/4705168.html SpringMVC中Controller的@ResponseBody注解分析 http://www.cnblogs.com/jeremy-blog/articles/4120577.html @RequestMapping 用法详解之地址映射 http://www.cnblogs.com/qq78292959/p/3760560.html 按批次处理list数据 (list按条数取) http://www.cnblogs.com/lzq198754/p/5780234.html 携程开源数据库访问框架Ctrip DAL http://www.oschina.net/news/77400/xiecheng-open-source-ctrip-dal https://github.com/ctripcorp/dal/wiki/代码生成器(CodeGen)安装说明 String Date Calendar之间的转换 http://www.cnblogs.com/qima/p/3652566.html Maven:Maven 入门 http://www.cnblogs.com/happyframework/p/3391691.html Java快速入门 http://www.cnblogs.com/happyframework/p/3332243.html WebApplicationInitializer http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/WebApplicationInitializer.html @order注解 http://www.tuicool.com/articles/VnqUv2 生产唯一ID 简单版:java通过UUID生成16位唯一订单号 http://www.cnblogs.com/shihaiming/p/5979728.html 全局唯一订单号生成方法(参考snowflake) http://blog.csdn.net/u011236357/article/details/51997083 Java中的泛型方法 http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html java 自定义注解以及获得注解的值 http://www.cnblogs.com/mouseIT/p/5033746.html
以下是在做地理位置相关项目要用到的一些资料,都是网上收集,里面根据经纬度如何查找周边区域、计算两点之间距离、如何利用geohash等; JAVA 计算地球上任意两点(经纬度)距离: http://blog.csdn.net/caixiexin/article/details/6799894 通过经纬度坐标计算距离的方法(经纬度距离计算): http://www.cnblogs.com/softfair/p/lat_lon_distance_bearing_new_lat_lon.html 经纬度距离计算在线工具: http://www.storyday.com/wp-content/uploads/2008/09/latlung_dis.html geo hash开源代码git地址: https://github.com/amingguazi/geohash-java.git GeoHash核心原理解析(详细) http://www.cnblogs.com/LBSer/p/3310455.html Geohash 算法的8个矩形 http://evthoriz.com/2015/07/02/Geohash%20%E7%AE%97%E6%B3%95%E7%9A%84%E8%BE%B9%E7%95%8C%E9%97%AE%E9%A2%98/
SpringMVC(1)入门之环境搭建与页面数据传递 http://blog.163.com/zhangmihuo_2007/blog/static/27011075201452811058561/
http://www.runoob.com/java/java-regular-expressions.html http://blog.csdn.net/lqclh502/article/details/47448135
@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件 单个文件 @ContextConfiguration(Locations="../applicationContext.xml") @ContextConfiguration(classes = SimpleConfiguration.class) 多个文件时,可用{} @ContextConfiguration(locations = { "classpath*:/spring1.xml", "classpath*:/spring2.xml" }) @EnableAutoConfiguration”注解的作用在于让 Spring Boot 根据应用所声明的依赖来对 Spring 框架进行自动配置,这就减少了开发人员的工作量。注解“@RestController”和”@RequestMapping”由 Spring MVC 提供,用来创建 REST 服务。这两个注解和 Spring Boot 本身并没有关系。 只需要在主配置 Java 类上添加“@EnableAutoConfiguration”注解就可以启用自动配置。Spring Boot 的自动配置功能是没有侵入性的,只是作为一种基本的默认实现。开发人员可以通过定义其他 bean 来替代自动配置所提供的功能。比如当应用中定义了自己的数据源 bean 时,自动配置所提供的 HSQLDB 就不会生效。这给予了开发人员很大的灵活性。既可以快速的创建一个可以立即运行的原型应用,又可以不断的修改和调整以适应应用开发在不同阶段的需要。可能在应用最开始的时候,嵌入式的内存数据库(如 HSQLDB)就足够了,在后期则需要换成 MySQL 等数据库。Spring Boot 使得这样的切换变得很简单。
需求分析:需要 利用 out 对象返回给财付通是否接收成功 。那么将需要如下代码: /** * 返回处理结果给财付通服务器。 * @param msg: Success or fail。 * @throws IOException */ public void sendToCFT(String msg) throws IOException { String strHtml = msg; PrintWriter out = this.getHttpServletResponse().getWriter(); out.println(strHtml); out.flush(); out.close(); } 那么在Controller中的方法若用此方法注解: //财付通返回URL @ResponseBody @RequestMapping("/pay/tenpay") public String tenpayReturnUrl(HttpServletRequest request, HttpServletResponse response) throws Exception { unpackCookie(request, response); payReturnUrl.payReturnUrl(request, response); return "pay/success"; } 用此办法注解将会在访问的页面上输出 字符串:strHtml,而不会跳转页面至pay/success.jsp页面 原因是: @ResponseBody 作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。 使用时机: 返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用; 那么只需删除注解:@ResponseBody 便可以返回页面pay/success.jsp。而且达到了与客户端后台交互的效果。即: out.println(strHtml); 且不会在页面上输出字符串。 原文地址:http://blog.csdn.net/huaishuming/article/details/31390161
关于redis GEO介绍命令可以参考官方文档:http://redis.io/commands/geoadd 主要命令: GEOADD 添加地理位置信息 GEODIST 查询位置距离 GEOHASH 查询位置GEOHASH编码 GEOPOS 查询位置的坐标 GEORADIUS 查询某点的附近点 GEORADIUSBYMEMBER 查询某位置距离的附近点 如果要演示redis GEO功能我们需要下载Unstable版本进行编译安装,可以在官网下载:http://redis.io/download或到github去下载最新Unstable版本代码编译:https://github.com/antirez/redis。 关于安装请参考:http://blog.csdn.net/zhu_tianwei/article/details/44890579 下面我们来演示一下命令: 1.添加位置信息 [plain] view plain copy print? 192.168.1.90:6379> 192.168.1.90:6379> GEOADD Guangdong-cities 113.2099647 23.593675 Qingyuan (integer) 1 192.168.1.90:6379> GEOADD Guangdong-cities 113.2278442 23.1255978 Guangzhou 113.106308 23.0088312 Foshan 113.7943267 22.9761989 Dongguan 114.0538788 22.5551603 Shenzhen (integer) 4 192.168.1.90:6379> 2.查询位置距离 [plain] view plain copy print? 192.168.1.90:6379> GEODIST Guangdong-cities Qingyuan Guangzhou km 192.168.1.90:6379> 3.查询位置GEOHASH编码 [plain] view plain copy print? 192.168.1.90:6379> GEOHASH Guangdong-cities Qingyuan Guangzhou 1) “ws0w0phgp70” 2) “ws0e89curg0” 192.168.1.90:6379> 4.查询位置的坐标 [plain] view plain copy print? 192.168.1.90:6379> GEOPOS Guangdong-cities Qingyuan Guangzhou Foshan 1) 1) “113.20996731519699” 2) “23.593675019671288” 2) 1) “113.22784155607224” 2) “23.125598202060807” 3) 1) “113.10631066560745” 2) “23.008831202413539” 192.168.1.90:6379> 5.查询某点的附近点 [plain] view plain copy print? 192.168.1.90:6379> GEORADIUS Guangdong-cities 113.2278442 23.1255978 50 km asc 1) “Guangzhou” 2) “Foshan” 192.168.1.90:6379> 6.查询某位置距离的附近点 [plain] view plain copy print? 192.168.1.90:6379> GEORADIUSBYMEMBER Guangdong-cities Guangzhou 50 km asc 1) “Guangzhou” 2) “Foshan” 192.168.1.90:6379> 使用redis Java客户端jedis实例; 由于jedis并没有实现redis GEO的命令,测试使用lua脚本来实现: [java] view plain copy print? package test; import java.util.List; import redis.clients.jedis.Jedis; public class Test { private static Jedis jedis = null; static{ jedis = new Jedis(“192.168.1.90”, 6379); } public static void main(String[] args) throws Exception { System.out.println(geoADD("beijing", 116.312014, 39.963019,"haidian")); System.out.println(geoADD("beijing", 116.227501, 39.90858,"shijingshan")); System.out.println(geoADD("beijing", 116.297641, 39.861631,"fengtai")); System.out.println(geoADD("beijing", 116.428146, 39.9316,"dongcheng")); System.out.println(geoADD("beijing", 116.375829, 39.920091,"xicheng")); System.out.println(geoADD("beijing", 116.110793, 39.943992,"mentougou")); System.out.println(geoADD("beijing", 116.480464, 39.95948,"caoyang")); System.out.println(geoADD("beijing", 116.663862, 39.916107,"tongzhou")); System.out.println(geoADD("beijing", 116.349383, 39.729911,"daxing")); System.out.println(geoADD("beijing", 116.157361, 39.748109,"fangshan")); System.out.println(geoADD("beijing", 116.662137, 40.134017,"sunyi")); System.out.println(geoADD("beijing", 116.2367, 40.224862,"changping")); System.out.println(geoADD("beijing", 117.141617, 40.14196,"pinggu")); System.out.println(geoADD("beijing", 116.64144, 40.316466,"huairou")); System.out.println(geoHash("beijing","haidian")); System.out.println(geoDist("beijing","haidian","shijingshan","km")); System.out.println(geoPos("beijing","haidian")); System.out.println(geoRadius("beijing",116.421822, 39.906809,10,"km",false)); System.out.println(geoRadiusByMember("beijing","dongcheng",10,"km",true)); } /** * 添加geo * @param key * @param longitude * @param latitude * @param name 位置名称 * @return */ public static Long geoADD(String key,double longitude,double latitude,String dName){ return (Long)jedis.eval("return redis.call('GEOADD',KEYS[1],KEYS[2],KEYS[3],KEYS[4])", 4,key,String.valueOf(longitude),String.valueOf(latitude),dName); } /** * 查询2位置距离 * @param key * @param d1 * @param d2 * @param unit * @return */ public static Double geoDist(String key,String d1,String d2,String unit){ return Double.valueOf((String)jedis.eval("return redis.call('GEODIST',KEYS[1],KEYS[2],KEYS[3],KEYS[4])",4, key,d1,d2,unit)); } /** * 查询位置的geohash * @param key * @param dName * @return */ public static String geoHash(String key,String dName){ Object data = jedis.eval("return redis.call('GEOHASH',KEYS[1],KEYS[2])", 2, key,dName); List<String> resultList = (List<String>)data; if(resultList!=null&&resultList.size() > 0){ return resultList.get(0); } return null; } /** * 查询位置坐标 * @param key * @param dName * @return */ public static List<Double> geoPos(String key,String dName){ Object data = jedis.eval("return redis.call('GEOPOS',KEYS[1],KEYS[2])", 2, key,dName); List<List<Double>> resultList = (List<List<Double>>)data; if(resultList!=null&&resultList.size() > 0){ return resultList.get(0); } return null; } /** * 查询附近坐标地址 * @param key * @param longitude * @param latitude * @param unit * @param asc * @return */ public static List<String> geoRadius(String key,double longitude,double latitude,int radius,String unit,boolean asc){ Object data = jedis.eval("return redis.call('GEORADIUS',KEYS[1],KEYS[2],KEYS[3],KEYS[4],KEYS[5],KEYS[6])", 6, key,String.valueOf(longitude), String.valueOf(latitude),String.valueOf(radius),unit,asc?"ASC":"DESC"); return (List<String>)data; } /** * 根据位置查询附近点 * @param key * @param dName * @param unit * @param asc * @return */ public static List<String> geoRadiusByMember(String key,String dName,int radius,String unit,boolean asc){ Object data = jedis.eval("return redis.call('GEORADIUSBYMEMBER',KEYS[1],KEYS[2],KEYS[3],KEYS[4],KEYS[5])", 5, key,dName,String.valueOf(radius),unit,asc?"ASC":"DESC"); return (List<String>)data; } } 增加jar包依赖: [html] view plain copy print? redis.clients jedis 2.7.3 参考文章: 1.redis官网lua脚本 2.spring+springdata redis入门教程实现java端调用redis lua脚本片段和lua脚本文件 3.利用redis + lua解决抢红包高并发的问题 原文地址: http://blog.csdn.net/zhu_tianwei/article/details/49149699 其他介绍: http://blog.jobbole.com/89225/
大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符。 比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/ KEAUFFR0Cbng3nQPw68ArZdAlOZppPFIBhH5EAB8b+Tlt9MYQ6i1BuqFaq1CKSVcxZ2Acs6406KUgpt5/ LCKuVgz5BDCSb13ZO99ZOdcZGvt4mJjzMVKqcha68iIePB86GAiOv8CDADlIUQBs7MD3wAAAABJRU5ErkJggg==。 那么这是什么呢? 这是Data URI scheme。 Data URI scheme是在RFC2397中定义的,目的是将一些小的数据,直接嵌入到网页中,从而不用再从外部文件载入。比如上面那串字符,其实是一张小图片,将这些字符复制黏贴到火狐的地址栏中并转到,就能看到它了,一张1X36的白灰png图片。 在上面的Data URI中,data表示取得数据的协定名称,image/png 是数据类型名称,base64 是数据的编码方法,逗号后面就是这个image/png文件base64编码后的数据。 目前,Data URI scheme支持的类型有: data:,文本数据 data:text/plain,文本数据 ;javascript:;,HTML代码 ;javascript:;;base64,base64编码的HTML代码 data:text/css,CSS代码 data:text/css;base64,base64编码的CSS代码 data:text/javascript,Javascript代码 data:text/javascript;base64,base64编码的Javascript代码 data:image/gif;base64,base64编码的gif图片数据 data:image/png;base64,base64编码的png图片数据 data:image/jpeg;base64,base64编码的jpeg图片数据 data:image/x-icon;base64,base64编码的icon图片数据 base64简单地说,它把一些 8-bit 数据翻译成标准 ASCII 字符,网上有很多免费的base64 编码和解码的工具,在PHP中可以用函数base64_encode() 进行编码,如echo base64_encode(file_get_contents(‘wg.png’)); 目前,IE8、Firfox、Chrome、Opera浏览器都支持这种小文件嵌入。 举个图片的例子: <img src=“http://www.letuknowit.com/images/wg.png”/> 也可以这样显示: <img src=“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAYAAABIdFAMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHhJREFUeNo8zjsOxCAMBFB/KEAUFFR0Cbng3nQPw68ArZdAlOZppPFIBhH5EAB8b+Tlt9MYQ6i1BuqFaq1CKSVcxZ2Acs6406KUgpt5/LCKuVgz5BDCSb13ZO99ZOdcZGvt4mJjzMVKqcha68iIePB86GAiOv8CDADlIUQBs7MD3wAAAABJRU5ErkJggg==”/> 我们把图像文件的内容直接写在了HTML 文件中,这样做的好处是,节省了一个HTTP 请求。坏处呢,就是浏览器不会缓存这种图像。大家可以根据实际情况进行自由取舍。
数据库中记录了商家在百度标注的经纬度(如:116.412007, 39.947545) 最初想法,以圆心点为中心点,对半径做循环,半径每增加一个像素(暂定1米)再对周长做循环,到数据库中查询对应点的商家(真是一个长时间的循环工作),上网百度类似的文章有了点眉目 大致想法是已知一个中心点,一个半径,求圆包含于圆抛物线里所有的点,这样的话就需要知道所要求的这个圆的对角线的顶点,问题来了 经纬度是一个点,半径是一个距离,不能直接加减 代码如下: /// <summary> /// 经纬度坐标 /// </summary> public class Degree { public Degree(double x, double y) { X = x; Y = y; } private double x; public double X { get { return x; } set { x = value; } } private double y; public double Y { get { return y; } set { y = value; } } } public class CoordDispose { private const double EARTH_RADIUS = 6378137.0;//地球半径(米) /// <summary> /// 角度数转换为弧度公式 /// </summary> /// <param name="d"></param> /// <returns></returns> private static double radians(double d) { return d * Math.PI / 180.0; } /// <summary> /// 弧度转换为角度数公式 /// </summary> /// <param name="d"></param> /// <returns></returns> private static double degrees(double d) { return d * (180 / Math.PI); } /// <summary> /// 计算两个经纬度之间的直接距离 /// </summary> public static double GetDistance(Degree Degree1, Degree Degree2) { double radLat1 = radians(Degree1.X); double radLat2 = radians(Degree2.X); double a = radLat1 - radLat2; double b = radians(Degree1.Y) - radians(Degree2.Y); double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; } /// <summary> /// 计算两个经纬度之间的直接距离(google 算法) /// </summary> public static double GetDistanceGoogle(Degree Degree1, Degree Degree2) { double radLat1 = radians(Degree1.X); double radLng1 = radians(Degree1.Y); double radLat2 = radians(Degree2.X); double radLng2 = radians(Degree2.Y); double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2)); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; } /// <summary> /// 以一个经纬度为中心计算出四个顶点 /// </summary> /// <param name="distance">半径(米)</param> /// <returns></returns> public static Degree[] GetDegreeCoordinates(Degree Degree1, double distance) { double dlng = 2 * Math.Asin(Math.Sin(distance / (2 * EARTH_RADIUS)) / Math.Cos(Degree1.X)); dlng = degrees(dlng);//一定转换成角度数 原PHP文章这个地方说的不清楚根本不正确 后来lz又查了很多资料终于搞定了 double dlat = distance / EARTH_RADIUS; dlat = degrees(dlat);//一定转换成角度数 return new Degree[] { new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-top new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y - dlng,6)),//left-bottom new Degree(Math.Round(Degree1.X + dlat,6), Math.Round(Degree1.Y + dlng,6)),//right-top new Degree(Math.Round(Degree1.X - dlat,6), Math.Round(Degree1.Y + dlng,6)) //right-bottom }; } } 测试方法: 代码如下: static void Main(string[] args) { double a = CoordDispose.GetDistance(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918));//116.416984,39.944959 double b = CoordDispose.GetDistanceGoogle(new Degree(116.412007, 39.947545), new Degree(116.412924, 39.947918)); Degree[] dd = CoordDispose.GetDegreeCoordinates(new Degree(116.412007, 39.947545), 102); Console.WriteLine(a+" "+b); Console.WriteLine(dd[0].X + "," + dd[0].Y ); Console.WriteLine(dd[3].X + "," + dd[3].Y); Console.ReadLine(); } 试了很多次 误差在1米左右 拿到圆的顶点就好办了 数据库要是sql 2008的可以直接进行空间索引经纬度字段,这样应该性能更好(没有试过) lz公司数据库还老 2005的 这也没关系,关键是经纬度拆分计算,这个就不用说了 网上多的是 最后上个实现的sql语句 代码如下: SELECT id,zuobiao FROM dbo.zuobiao WHERE zuobiao<>'' AND dbo.Get_StrArrayStrOfIndex(zuobiao,',',1)>116.41021 AND dbo.Get_StrArrayStrOfIndex(zuobiao,',',1)<116.413804 AND dbo.Get_StrArrayStrOfIndex(zuobiao,',',2)<39.949369 AND dbo.Get_StrArrayStrOfIndex(zuobiao,',',2)>39.945721
IIS7.0 Appcmd 命令详解 废话不说!虽然有配置界面管理器!但是做安装包的时候命令创建是必不可少的!最近使用NSIS制作安装包仔细研究了一下Appcmd的命令,可谓是功能齐全. 上网查了些资料,那些博客大部分都是转载的别人的。都是些基本的介绍,很多命令都没介绍到(不知道是不是我走眼了)。 就连微软的 技术资源库 也不详细: 附地址:http://technet.microsoft.com/zh-cn/library/cc772200(WS.10).aspx(反正我找了一遍!没找到我要的) 微软的 技术资源库 有的我就不介绍了,点开上面的链接自己去看。 (介绍我们能用到的一些命令,目前只包含site 的操作,其他apppool config app vdir 后续有时间在加入) 一:准备工作 APPcmd.exe 位于 C:\Windows\System32\inetsrv 目录 使用 Cd c:\Windows\System32\inetsrv 切换到该目录 二:命令操作简介 IIS 命令行管理工具基本格式: APPCMD (命令) (对象类型) <标识符>
HeidiSQL 是一个功能非常强大的 MySQL 客户端软件。它是德国程序员Ansgar Becker和几个Delphi程序员开发的一个开源工具。要通过HeidiSQL来管理数据库,用户应该用有效地凭证登陆到MySQL服务器,创建一个会话。HeidiSQL最大的特色就是操作方便,界面设计合理,功能都是最实用的,尤其适合DBA,它更加强调了对MySQL运行时的参数设置和性能监控等. 它可以浏览和编辑数据,创建和编辑表格,视图,过程,触发器和安排日程。另外,还可以导出结构和数据SQL文件。 HeidiSQL特点: •连接到多个服务器窗口 •可以使用命令行连接到服务器 •创建和编辑表格,视图,存储程序,触发器和安排日程。 •SQL数据导出 •从一台服务器/数据库直接导入数据到另一台服务器/数据库 •管理用户权限 •导入文本文件 •为CSV,HTML,XML和SQL的Wiki标记LaTeX和导出表行 •批量修改表(移动到DB,改变发动机,整理等) •批量插入到表中ASCII或二进制文件 •写自定义语法高亮和代码自动完成查询 •漂亮的SQL格式化 •监视和杀灭客户进程 •找到一个所有数据库的所有表的具体文本服务器 •在批处理方式优化和修复表 官网地址:http://www.heidisql.com/
mvc Razor除了在视图上解析外,一样可以这样用。 在有些项目需求上或许需要根据模板生产静态页面,那么你一样可以用Razor语法去直接解析你的页面从而把解析的页面生成静态页,首先介绍下RazorEngine,在nuget上可以直接引用到项目上,这个东西通俗的来讲就是可以在任何地方解析razor语法,个人觉得要比 NVelocity灵活好用很多。在codeplex上有介绍,现在好像搬到Github上了,链接http://razorengine.codeplex.com/,最新的版本在Github上,大家可以看看,使用上很方便,如下: string template = “Hello @Model.Name! Welcome to Razor!”; string result = Razor.Parse(template, new { Name = “World” }); 就这么简单你就可以不只在视图页面上使用Razor了,它完全支持动态类型,如下: dynamic ViewBag = new DynamicViewBag(); ViewBag.list = “流年莫逝”; string template = “Hello Word @ViewBag.list”; string result = Razor.Parse(template,null,ViewBag,Guid.NewGuid().ToString()); 一样可以解析出来,看源码活着是VS的智能提示你可以看到Razor.Parse后面需要传递的参数类型,只要对号入座就行了,它是支持cache的,当然它的这种cache我个人理解的并不是那种数据缓存的cache,如上面dynamic类型的解析Razor.Parse我是演示用的Guid,但是你可以用其他的string字符,如果你下次预编译模板的时候还是用的这个名字的话就会直接取cache里的模板来做解析,这样减少了解析时间,这是我的个人理解,目前还没有深入的去研究。 RazorEngine还支持自定义模板,如下代码: //自定义模板 public class MyTemplateBase : TemplateBase { public string GetStr() { return “流年莫逝”; } } //注册自定义模板 public class CustomTemplate : TemplateService { public CustomTemplate() { var Service = new RazorEngine.Configuration.TemplateServiceConfiguration(); Service.BaseTemplateType = typeof(MyTemplateBase<>); var MyTemplate = new TemplateService(Service); Razor.SetTemplateService(MyTemplate); } } 简单介绍下啊,上面那个是自定义的模板,里面你可以按你的需求写相应的方法,这样在解析的时候你一样可以使用你的方法,比方我的是返回的字符串,你用@GetStr()一样可以得到你的返回值,另外你的自定义模板一样要继承TemplateBase,我看了它的源码不知道为什么一样要带上一个泛型,想研究的可以自己看看,注册模板后你就可以使用了, CustomTemplate service = new CustomTemplate(); return service.Parse(Content, null, ViewBag, Guid.NewGuid().ToString()); 按这种方法就可以解析了,Razor.Parse方法是TemplateService类里面的一个虚方法,是支持自己重写的,所以在注册的时候你继承了这个TemplateService类,就是可以实现你想要的了! 看到官网上有很多提问为什么不能用@Html.Raw()等这些方法,其实你要是仔细看源码的话是可以支持的,只是换了个写法你可以直接用@Raw()来进行输出,就简单介绍这么多吧,其实RazorEngine还有很多功能的,但是目前以上几种完全够解析页面用了! 原文出自: http://soft.chinabyte.com/database/365/12771365.shtml http://www.cxyclub.cn/n/22804/ RazorEngine Razor知识集合: 代码生成就用Razor模板: http://www.cnblogs.com/hjblog/archive/2012/11/14/2769660.html Razor - 模板引擎 / 代码生成 - RazorEngine http://www.atove.com/Article/Details/0C9DDD08B36EA15445653A0879752C69#TMd_AutoId_14 MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎) http://www.qingruanit.net/blog/23930/note3712.html?m=true 基于.net搭建热插拔式web框架(RazorEngine实现) http://www.tuicool.com/articles/AVbQnyI C#模板引擎 RazorEngine3.7的简单使用 http://blog.csdn.net/somethingwhat/article/details/47189065
感知哈希算法——找出相似的图片: http://www.cnblogs.com/technology/archive/2012/07/12/Perceptual-Hash-Algorithm.html XsdGen:通过自定义Attribute与反射自动生成XSD http://www.cnblogs.com/technology/p/XsdGen.html
sql server update as_landingmodule set ModuleInterface=tb.ChannelInterface FROM (SELECT b.ModuleID,(select ChannelInterface From as_landingchannel where ChannelID=b.ChannelID) as ChannelInterface FROM (SELECT * FROM as_landingmodulerelation where ProductType='Orther') b inner join as_landingmodule as a on b.ModuleID=a.ModuleID) tb where tb.ModuleID=as_landingmodule.ModuleID; mysql update as_landingmodule inner join (SELECT b.ModuleID,(select ChannelInterface From as_landingchannel where ChannelID=b.ChannelID) as ChannelInterface FROM (SELECT * FROM as_landingmodulerelation where ProductType='Orther') b inner join as_landingmodule as a on b.ModuleID=a.ModuleID) tb set ModuleInterface=tb.ChannelInterface where tb.ModuleID=as_landingmodule.ModuleID;
HttpHandler与HttpModule的用处与区别 问题1:什么是HttpHandler? 问题2:什么是HttpModule? 问题3:什么时候应该使用HttpHandler什么时候使用HttpModule? 答案1:HttpHandler,Http请求的处理者,例如ScriptHandler、WebServiceHandler,IHttpHandler的实现都是为了处理某一类的请求。如ScriptHandler负责处理对脚本的请求。 答案2:HttpModule,Http模块。实际上就是那19个标准事件的处理者,或者说19个标准事件的订阅者,比如OutputCacheModule,SessionStateModule。详细可以到在这篇文章里面看到http://www.cnblogs.com/kissdodog/p/3527922.html。 一、HttpHandler的职责 1、由于HTTP请求有很多种请求类型,比如请求aspx、html、jpg等等。因此,仅仅由HttpApplication直接处理请求时很臃肿的,而且不利于扩展。因此Asp.net采用了抽象工厂模式来处理这些请求。Asp.net在web.config的架构中,允许我们制定某些请求映射到一个HttpHandlerFactory。
在应用Redis过程中经常需要查询些知识,博客园中这个朋友写的不错,转载收藏一下。 Redis 安装与简单示例 <第一篇> http://www.cnblogs.com/kissdodog/p/3570984.html Redis常用命令速查 <第二篇> http://www.cnblogs.com/kissdodog/p/3599047.html ServiceStack.Redis之IRedisClient<第三篇> http://www.cnblogs.com/kissdodog/p/3572084.html ServiceStack.Redis 之 IRedisTypedClient<第四篇> http://www.cnblogs.com/kissdodog/p/3606017.html http://www.cnblogs.com/kissdodog/p/3608503.html ServiceStack.Redis常用操作 - 事务、并发锁 Redis:在windows环境安装Redis http://www.cnblogs.com/happyframework/p/3197392.html
paip.解决 数据库mysql增加列 字段很慢添加字段很慢 环境如下: mysql5.6 数据仅仅3w alter table xxx add column yyy int default 0; 添加字段很慢,好几份中都没有好。。 原因以及解决 [SQL] alter table grejx_def add column flag12 int default 0; 受影响的行: 0 不是那种lock–copoy–rewrite的方式.effeic row sh 0 ,为甚还是这么慢的是?? Oracle 11g的快速加字段功能就是好啊.. 数据结构紊乱兰,只要不个table 优化给挂走ok兰。。 字谣0.3s走ok兰.. 作者 老哇的爪子 Attilax 艾龙, EMAIL:1466519819@qq.com 转载请注明来源: http://blog.csdn.net/attilax mysql数据库添加字段或者修改结构过程如下 由于mysql在线ddl(加字段、加索引等修改表结构之类的操作)过程如下: A.对表加锁(表此时只读) B.复制原表物理结构 C.修改表的物理结构 D.把原表数据导入中间表中,数据同步完后,锁定中间表,并删除原表 E.rename中间表为原表 F.刷新数据字典,并释放锁 添加字段很慢 alter table grejx_def add column flag int default 0; 大的数据哈的解决 停掉mysql服务器来修改表结构。然后进行滚动式更新 Facebook数千台MySQL服务器在过去增加个索引需要几个月的滚动升级(后来他们自己开发了后面提到的工具,只需要几天) 在加字段之前进行测验mysql是否复制表,以减低应用卡死的风险: 在命令结束之后看看显示“rows affected “的值。例如,这里您可能会看到在做不同类型的DDL操作: 拷贝表结构,然后插入少量的数据。去修改表结构。看影响的行。如果为0,则表示不会拷贝中间表的方式 关于online-schema-change 是percona推出的一个针对mysql在线ddl的工具 新的思路(手动执行mysql的过程) 1:手动的创建好修改后的表结构 NEW_TAB。(比如新增字段,修改表字段类型。删除表字段,可以一并一次性搞定) 对于MyISAM表,您可以通过把myisam_sort_buffer_size系统变量设置到一个较高的值,来加快重新创建索引(该操作是变更 过程中速度最慢的一部分)的速度。 2: 选择性的将旧表OLD_TAB数据插入到修改后的表。(这里需要注意的是海量数据的处理。可以将表记录按照主键分批进行插入处理,其实在如果分表处理的话,在业务代码中也是可以进行修改处理的,分而治之。) 3:rename表名称。 (这里需要注意的是RENAME过程中的锁表,可以在业务空闲的凌晨晚上进行处理)。