• 由深圳限外引起的一点思考(附限外摄像头分布点)

    在深圳这个一直以开放出名的城市居然也搞起了限外(排外),不得不让人对ZF的管理能力只是出这种最简单粗暴的政策产生怀疑。实际效果是限行后以前没打算买车的都参加到摇号买车了,以前不在深圳开的粤B车也开回来深圳了。另外如果真的是想限制新车增长,全部指标摇号就可以了,想不明白还要增加竞拍(按每期3000个竞拍指标,均价5万来算,一期的竞拍收入是1.5亿)。

    其实想说的是,如果大家都欣然接受这种现象,那接下来就可能会出现“单双号限行”,甚至是“摇号出行”,“市内按区限行”,“上下班高峰期只允许公共交通和政府机关车辆行驶”等等。不要觉得不可能,以前我们觉得“限行限外”,“单双号限行”都是不可能,后来都一一“实现”了,有了开头自然会有其他的出来。但是在地球的另一边欧洲国家之间开车通行都没有太多限制,就像人家国家之间打电话都不算长途,我们市与市之间已经是长途。对于不开车的人来说,如果汽车都限行了,公共交通工具的压力就会倍增,到时候就不是要挤几趟地铁才能挤上去这么简单了。当然站在社会资源的角度是提倡大家尽量使用公共交通工具出行的,前提是这个城市的公共交通足够发达和公平,要知道有深圳“硅谷”之称的科技园却只有一条地铁通过,这样的资源分配怎么能让大家都用公共交通出行?

    在IT界里面也有关于封闭和开放的思辨:技术垄断、闭源、开源和黑客。技术垄断的代表是高通,闭源是微软和Oracle,开源是Github、Linux、MySQL、Google、Facebook和Alibaba,黑客是阿桑奇。总的趋势都是向着开源和自由方向发展。

     

    附:深圳限外车牌识别监控摄像头分布点(数据更新至2015年2月4日,后续可能有新增,欢迎留言补充)

     

    48 福田区  (高清) 梅观公路南坪立交南侧南行
    49 福田区  (高清) 梅观公路彩田路口北行
    50 福田区  (标清) 南坪快速路1.3公里东行
    51 福田区  (标清) 南坪快速路1.3公里西行
    52 福田区  (标清) 南坪快速路5.9公里东行
    53 福田区  (标清) 南坪快速路5.9公里西行
    54 福田区  (标清) 北环大道新洲立交东行
    55 福田区  (标清) 北环大道新洲立交西行
    56 福田区  (标清) 北环大道彩田立交东行
    57 福田区  (标清) 北环大道皇岗路口西行
    58 福田区  (标清) 滨河大道爱华南人行天桥东行
    59 福田区  (标清) 滨河大道爱华南人行天桥西行
    60 福田区  (标清) 滨河大道彩田立交东行
    61 福田区  (标清) 滨河大道福滨人行天桥西行
    62 福田区  (标清) 滨河大道红岭南人行天桥东行
    63 福田区  (标清) 滨河大道香蜜湖立交东行
    64 福田区  (标清) 红荔路福莲人行天桥东行
    65 福田区  (标清) 红荔路皇岗路口西行
    66 福田区  (标清) 上步中路百花人行天桥南行
    67 福田区  (标清) 上步中路同德人行天桥北行
    68 福田区  (标清) 深南大道彩田立交东行
    69 福田区  (标清) 深南大道广深高速桥东行
    70 福田区  (标清) 深南大道广深高速桥西行
    71 福田区  (标清) 深南大道皇岗立交西行
    72 福田区  (标清) 深南大道新洲立交东行
    73 福田区  (标清) 深南大道新洲立交西行
    74 福田区  (标清) 深南中路中航人行天桥东行
    75 福田区  (标清) 深南中路中航人行天桥西行
    76 福田区  (标清) 笋岗西路笔架山公园人行天桥西行
    77 福田区  (标清) 笋岗西路莲花立交东行
    78 福田区  (标清) 笋岗东路圆岭人行天桥东行
    79 福田区  (高清) 新洲路福新立交南行
    80 福田区  (高清) 北环大道侨香村人行天桥东行
    81 福田区  (高清) 北环大道侨香村人行天桥西行
    82 福田区  (高清) 福龙路横龙山隧道入口北行
    83 福田区  (高清) 福龙路横龙山隧道北行南坪出口
    84 福田区  (高清) 福龙路横龙山隧道出口南行
    85 福田区  (高清) 新洲路福新立交北行
    86 福田区  (高清) 福强路福强人行天桥东行
    87 福田区  (高清) 福强路福强人行天桥西行
    88 福田区  (高清) 福荣路新洲路口东侧东行
    89 福田区  (高清) 福荣路新洲路口东侧西行
    90 福田区  (高清) 彩田路新彩隧道管理中心人行天桥北行
    91 福田区  (高清) 彩田路皇岗立交北行
    92 福田区  (高清) 彩田路皇岗立交北侧北行
    93 福田区  (高清) 深南大道皇岗立交东侧西行
    94 福田区  (高清) 深南大道皇岗立交北行跨线桥西行
    95 福田区  (高清) 深南大道皇岗立交南行跨线桥西行
    96 罗湖区  (高清) 沿河路北斗人行天桥东行
    97 罗湖区  (标清) 深南东路蔡屋围人行天桥东行
    98 罗湖区  (标清) 深南东路蔡屋围人行天桥西行
    99 罗湖区  (标清) 笋岗东路松园北人行天桥西行
    100 罗湖区  (标清) 沿河路罗芳立交南行
    101 罗湖区  (标清) 罗沙路仙湖立交西行
    102 罗湖区  (标清) 罗沙路长岭人行天桥东行
    103 罗湖区  (标清) 罗沙路罗芳人行天桥西行
    104 罗湖区  (标清) 罗沙路罗芳人行天桥东行
    105 罗湖区  (高清) 延芳路罗沙边防通道桥北行
    106 罗湖区  (高清) 延芳路罗沙边防通道桥南行
    107 罗湖区  (高清) 罗沙路辅道仙湖立交西行
    108 南山区  (标清) 月亮湾大道深南立交北行
    109 南山区  (标清) 北环大道深南立交西行
    110 南山区  (标清) 北环大道沙河东立交东行
    111 南山区  (标清) 北环大道沙河东立交西行
    112 南山区  (标清) 滨海大道后海立交西行
    113 南山区  (标清) 滨海大道侨城东立交东行
    114 南山区  (高清) 滨海大道侨城东立交西行
    115 南山区  (标清) 滨海大道沙河东立交东行
    116 南山区  (高清) 滨海大道沙河东立交西行
    117 南山区  (标清) 南海大道学府人行天桥北行
    118 南山区  (标清) 南海大道学府人行天桥南行
    119 南山区  (标清) 深南大道南海立交东行
    120 南山区  (标清) 深南大道南海立交西行
    121 南山区  (标清) 深南大道沙河西立交西行
    122 南山区  (高清) 北环大道深云立交东行
    123 南山区  (高清) 北环大道深云立交西行
    124 南山区  (高清) 滨海大道沙河西路出口西行
    125 盐田区  (高清) 深盐二通道恩上立交西行
    126 盐田区  (高清) 深盐二通道恩上立交东行
    127 罗湖区 (高清) 东门路湖贝路口北行
    128 罗湖区 (高清) 东门路晒布路口南行
    129 福田区 (高清) 红荔路香蜜湖天桥东行
    130 福田区 (高清) 红荔路香蜜湖天桥西行
  • 网站异常发送异常代码到邮箱

    为了对用户的请求作统一处理,所以把Struct的Action封装成了一个AbstractAction。

    其中AbstractAction重写了Action类的execute方法,其中一个统一处理就是异常的处理。

    刚好最近想到了代码抛异常时就发邮件通知,这样既能立刻接收到异常的信息,也能对异常归档。

    刚开始打算直接用Exception的getCause()内容作为邮件内容发送,不过只有异常的原因,没有异常

    出现的定位信息:

    e.getCause()
    (java.lang.NullPointerException) java.lang.NullPointerException

    最后用到Exception的printStackTrace(PrintStream s)方法,并且采用了可变尺寸的线程池来发送邮件,主要是在以前构造的线程可用时将重用它们,代码如下:

    try {

    // code

    } catch (Exception e) {

    e.printStackTrace();

    logger.error(e.getCause());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    e.printStackTrace(new PrintStream(baos));

    String url = request.getRequestURL().toString() ;

    if(request.getQueryString()!=null){

    url+=”?” + request.getQueryString();

    }

    exception = “请求地址为:”+url+ “<br>” ;

    exception += “请求IP为:”+IPUtil.getIpAddr(request)+ “<br>” ;

    exception += baos.toString();

    //ex为AbstractAction类的属性

    //private ExecutorService ex = Executors.newCachedThreadPool();

    ex.execute(new Runnable() {

    @Override

    public void run() {

    // sendEmail(String addr, String title, String content)

    eMailService.sendEmail(“XXX@gmail.com”, “后台异常”,exception);

    }

    });

    }

    通过获取这些异常信息也可以发现某些对网站的异常访问,例如这次访问产生的异常:(下面代码用*取代了真实IP)

    请求地址为:http://******/front/indexNotLogin.do?action=viewAgreement&id=../../../../../../../../../../../../../sbin/../etc/./rc.d/../rc.d/.././passwd%00.htm 请求IP为:203.130.**.*** java.lang.reflect.InvocationTargetException at sun.reflect.GeneratedMethodAccessor239.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at

    这样就可以把203.130.**.***这个IP添加到黑名单了!

  • 科目二驾考

    今天终于过了科目二,虽然不是满分过,不过也是一次性通过..
    感觉在中国考驾照,弄得像高考一样紧张..
    这次跨省考试的四个小伙伴,只过了两个..上一批四个只过了一个..
    看来抗压能力很重要,所以把之前做的一些笔记写上来,方便要准备考科目二的童鞋参考(每个人的自身条件和车辆条件不一样,请作为模板参考,切勿硬套):

    1. 半坡停车启动:
    (1)上坡:上坡前先校正方向,尽量直行,上坡后车身与右边线间距为发动机盖右角刚好遮住右边线。
    (2)停车:通过左后视镜柄刚好看到中间黄线就停车。
    (3)启动:先松离合器到车身有点抖然后定住,慢慢松脚刹。
    2.侧位停车:
    (1)前进进入侧位停车时调整好与右边线距离,不要距离太大,否则倒车时前轮容易压线。
    (2)倒车时,从右倒视镜看到右后轮刚过侧位车库前横线,将方向盘往右打尽,倒车,直到左后视镜刚好看到后横线右直角,回正方向盘,直到左后轮刚好到左竖线(虚线),将方向盘往左打尽,直到发动机盖左角刚好越过左竖线(虚线)停车。

    3.倒车入库:
    (1)进入倒车库调整好与前横线距离很重要,距离合适倒车时不用修方向,距离为:进去的时候驾驶人对着第二个缺口和虚线第二个小段的交接处。
    (2)右转向入库:倒车到左倒视镜刚好遮住虚黄线时将方向盘往右打尽,慢慢倒车判断右后轮会不会压线,当入库快平衡后,快速回正方向盘,当倒后镜刚好完全挡住黄线就停车。
    (3)左转向出库:玻璃窗按钮到达黄虚线时开始打方向盘一圈+120度,驶出直角后,当倒后镜与虚黄线平衡则停车(发动机盖刚好遮住前面黄线)。
    (4)左转向入库:按左转向出库方向盘不动入库。
    (5)右转向出库:玻璃窗按钮超过黄虚线一点点时将方向盘往右打尽,出库快平衡时快速回正方向盘。
    4.直角转弯:贴近左边线行驶(发动机盖左角刚好有一点遮住左边线),行驶到驾驶室右门手柄刚好到横线位置,将方向盘往右打尽。
    5.连续转弯:
    尽量靠近右边线进入左湾:发动机盖左角刚到右边界,打左一圈加九十度,直到发动机盖左角刚到左边界,回正方向,直走一小段路,到发动机盖右角刚好到左边界,打右一圈加九十度。过程中以发动机盖左角与右边线是否平衡来判断方向打多了还是打小了,适当修正方向。

  • Ibatis列名无效

    最近在用ibatis连接Oracle,出现了几种列名无效的情况:

    — The error occurred in com/kingdee/youshang/basedata/mapper/ProductOnSale.xml.
    — The error occurred while applying a result map.
    — Check the ProductOnSale.ProductOnSaleResult.
    — Check the result mapping for the ‘id’ property.
    — Cause: java.sql.SQLException: 列名无效]; SQL was [] for task [SqlMapClient operation]

    将一些可能的原因列出来:

    一、SQL语句映射文件:

    1.查询语句返回的结果字段集不是所对应resultMap里面映射字段集的父集或相等,例如:

    resultMap 映射为:

    <resultMap class=”ProductOnSale” id=”ProductOnSaleResult”>
    <result column=”FID” javaType=”long” jdbcType=”BIGINT” property=”id”/>
    <result column=”FFUNDNAME” javaType=”string” jdbcType=”VARCHAR” property=”fundname”/>
    </resultMap>

     

    而SQL返回只有FFUNDNAME(没有FID):

    <select id=”findProducts” resultMap=”ProductOnSaleResult”>/*dialect*/
    SELECT FFUNDNAME FROM T_BS_PRODUCT_ON_SALE POS
    </select>

    2.resultMap配置里面的字段名前面加了表名:

    <resultMap id=”ProductOnSaleResult”>
    <result column=”POS.FID” javaType=”long” jdbcType=”BIGINT” property=”id”/>
    <result column=”POS.FFUNDNAME” javaType=”string” jdbcType=”VARCHAR” property=”fundname”/>
    </resultMap>

     

  • 网站开发人员面对的不仅是用户还有黑客

    网站被黑客攻击的很大原因是做的限制不够,但是做的限制过多也会造成用户体验不好。

    以前只是喜欢看黑客攻防的书,想不到这两天实战了。昨晚11点多,老大打电话来说网站短信验证码发送出现异常,问我在更新生产环境的时候有没有异常,让我确认一下是程序的问题还是外部的原因。记得没有修改过那一块的代码,但为了确定原因,马上打开了电脑然后远程控制到公司的办公电脑(出来工作后养成了一个小小的良好习惯就是下班的时候会把公司办公电脑的远程工具打开,这样网站有问题就可以立刻在家里远程操作)。

    首先检查了数据库记录,看到记录短信发送的数据表的数据真的一下子多了很多,仔细分析了表的数据发现不是程序问题,再用Chrome的调试功能发现了原来是一个手机短信验证接口被攻击了。因为短信量非常大,而且晚上基本上没有正常注册的用户,所以采取了暂停短息发送。然后顺便测试了一下一些其他网站,发现有些网站也有这个问题。

    第二天早上回到公司分析了访问日志表,总共有几百个肉鸡IP在攻击,而且一直持续不停。这几百个肉鸡通过攻击接口向不同的手机号码发送验证短信。之前只是做了隔60秒才能发送下一条信息的限制,没有限制一个手机号码一天接收的短信数目是因为短信通道有时候有问题,用户注册的时候需要请求好几次才能收到短信;而没有限制一个IP一天接收的短信数目是因为面向的用户主要是企业客户,一家企业往往只有一个对外的公网IP,而内部员工的数量可能不少。还是那句话“网站被攻击的很大原因是做的限制不够,但是做的限制过多也会造成用户体验不好”。经过讨论,得出几套方案:

    1.添加图片验证码。这个算是最简单和最有效的,不过对于用户体验来说,这个确实不好,因为用户已经习惯了发送手机验证码的时候只需要点击一个按钮。

    2.限制一天内向一个手机号码发送的短信数目。虽然可能会出现用户正常注册的时候需要请求几次才能收到短信,不过这个次数并不高,而且虽然面向的用户是企业用户,但手机号码是个人使用,限制发送的短信数目可行。然后自己赶紧的在后台代码添加了这个限制。

    3.将肉鸡IP拉入黑名单。这个可能会有小问题,因为是根据访问日志中访问接口达到一定数目来判断是否为肉鸡IP,有可能将有很多员工的公司的公网IP误认为是肉鸡IP(公司的IP刚开始就是被误以为是肉鸡IP)。不过把值定得合适,就会很少出现这种误杀,而且也会返回一个提示给用户“你的IP已被限制,请联系我们的客户”,这样即使是误杀,也可以手工处理。自己也赶紧在数据库新建了一张IP黑名单表,在代码里面做了这个黑名单过滤。没有直接使用iptables是因为这样的拦截是在系统级的,如果是误杀就不能将提示反馈给用户,用户可能完全不知道下一步要怎么操作。

    4.请求添加token。这个也能在一定程度上防止攻击,但是通过程序来完成的防御也会被绕过。

    (待续)

     

  • 密码保护:金蝶实习点滴

    这是一篇受密码保护的文章,您需要提供访问密码:

  • MySQL5.6在Windows7安装时停留在Attempting to start service的解决方法

    一.问题描述:

    之前在电脑安装过MySQL5.5,后来卸载了。到安装MySQL5.6就出现了到Configuration时总是停留在Attempting to start service的问题。google和百度和很久也没有解决,问题困扰了有两个月之久。安装出现的问题如下:

    二.尝试过的操作和结果:

    1.默认端口3306被占用?:在cmd下用了端口查看命令netstat -aon|findstr “3306”,没有发现端口被占用。

    2.服务已经存在?:在cmd用命令“sc delete MySQL56”删除了MySQL服务再重装还是不行。

    3.没有清理注册表?:用软件清除过,也手动清除过(运行Regedit,然后到“HKEY_LOCAL_MACHINE/SoftwareMicrosoft/Windows/CurrentVersion/Uninstall ”删除),重装的时候问题还是出现了。

    4.操作系统不能启动MySQL服务?:前段时间刚好安装了wamp,它自带的MySQL服务能启动,所以不是操作系统的问题。

    5.bug?:在MySQL的网站上面提交的bug中有这样的问题描述,不过觉得自己的不是,因为装回之前那个MySQL5.5的msi,也是同样的问题。

    三.解决方法:

    尝试过上面几种方法重装还是不成功后,在准备重装系统前想了下在系统中所有和MySQL有关的东西,最后把”C:\ProgramData“的MySQL文件夹删除了再重装就可以了(注:在windows中”C:\ProgramData“文件夹默认是隐藏的)。

    还有一个办法就是利用MySQL的installer进行卸载,运行installer后会显示三个选项:“Installer Updates”、“Add/Modify Products and Features”和“Remove MySQL Products”,选择“Remove MySQL Products”,这样会彻底卸载,重新安装就不会有问题了。

     

  • 博客之道——开启篇

    很早之前就开始写博客了,不过没有坚持下来,这次用上了WordPress,并且自己的域名还没有过期,会把写博客这项工作坚持下去。因为用文字和图片记录生活上的点点滴滴在自己看来是一种乐趣,所以在微博和微信上经常会刷同学们的屏。半年前用JSP+JavaBean+Servlet+MySQL写的那个博客也彻底弃用了,毕竟WordPress的用户体验很好。当初决定用Java写博客是因为JSP课程要做一个大实验,而自己觉得写一个博客挺有趣,因为可以在代码里面获得到很多有用的信息,例如访客的IP、从哪里转到这个博客、访问的时间、查询的字符串、浏览器类型和最感兴趣的模块等等,而这个JSP博客也实现了这些功能,只是把它部署到SAE上面,JVM的启动慢是一个问题,而且很多细节都没有处理好,所以就直接改用了WordPress。不过之前刚好有同学问到JSP+JavaBean+Servlet的设计流程是怎样的,就不想白白浪费了自己断断续续做了两个月的成果,把这个JSP博客放到了github上面(https://github.com/thatcat/jsp_blog/)。一些代码优化和数据库优化都没有做好优化,放上去只是让有需要的同学看看JSP+JavaBean+Servlet的设计流程是怎样的,不喜勿喷,哈哈。至于为什么不直接在CSDN或51CTO上面写博客,是因为比较喜欢直接操作数据库,特别是MySQL,而SAE提供了这方面的功能。