• 2013年工作中遇到的20个问题:181-200


    每个人在工作中遇到的问题,很多都是类似的。了解别人遇到的问题,自己遇到的时候就可以很快地解决它。
    很多人不屑于这种“细节问题”,但我想说,掌握这些细节问题一次可能只能帮你节省1s的时间,但是这个细节使用频率非常高,
    1年可以节省不少时间的。如果按1秒*20次*300天=100分钟。


    181.MySQL数据库是否区分大小写。

    方法1:设置字符集校对collate
    通过查询资料发现需要设置collate(校对) 。
     collate规则:

     *_bin: binary case sensitive collation,也就是说是区分大小写的
     *_cs: case sensitive collation,区分大小写
     *_ci: case insensitive collation,不区分大小写
     
     方法2:设置字段的字符集校对

    1.可以将查询条件用binary()括起来。  比如:     select  * from TableA  where  columnA like binary('aaa');

    2.可以修改该字段的collation 为 binary

    比如:

    ALTER TABLE User MODIFY COLUMN name VARCHAR(255) COLLATE utf8_general_ci DEFAULT NULL;

    方法3:使用MySQL的lowwer函数和Java的toLowerCase方法。

    Java变量myname = myname.toLowerCase()
    SQL语句
    select * from user where lower(name) like '%myname%';

     参考资料:http://my.oschina.net/xiangtao/blog/33983
     http://blog.csdn.net/lawmansoft/article/details/7217712

    182.整数相加的溢出问题。
    我本来想写一个通用求和方法sum(int… array);
    想到可能会发生溢出,所以我需要判断是否溢出。

    参考资料:http://blog.csdn.net/ljg888/article/details/8035276

    方法1
    19./*Determine whether arguments can be added without overflow */  
    20.int taddOK(int x, int y){  
    21.    int sum = x + y;      
    22.    int negOverflow = x < 0 && y < 0 && sum >= 0;  
    23.    int posOverflow = x >= 0 && y >= 0 && sum <= 0;  
    24.  
    25.    return !negOverflow && !posOverflow;  
    26.}  

    方法2
    Goolge-Guava库/guava-libraries/guava/src/com/google/common/math/IntMath.java有如下方法

     public static int checkedAdd(int a, int b) {
        long result = (long) a + b;
        checkNoOverflow(result == (int) result);
        return (int) result;
      }
     
      用long保存int相加的临时结果,再强制转换为int,判断2个int是否相等。


    183.jQuery在项目中最好只使用1个版本的,比如1.9。
       jQueryUI版本要一致,不要搞2套主题,麻烦死了。
       使用jQueryUI时,最好把所有相关的js、css、image都放进项目中。
       如果每使用1个组件,就增加相关资源,容易出现问题。维护麻烦。
       
    184.浮点数等符合类型进行运算。
     Float one;
     Float two;
     
     if(one != null && two != null){
       result = one – two;
     }
     
     在调试这个问题的过程中,遇到了另外2个问题。
     
     A.服务器端安装了2个安全补丁,导致我这边的Eclipse不能远程调试程序了,端口无法访问。巨坑啊!
     
     B.Eclipse定位异常信息的具体位置。
     
     Exception in thread "main" java.lang.NullPointerException
        at com.miaozhen.cms.controller.CampaignGroupController.ttt(CampaignGroupController.java:254)
        at com.miaozhen.cms.controller.CampaignGroupController.main(CampaignGroupController.java:248)

        
        应该是上面的“ttt”的位置,这些细节很重要。
     
     185.使用jQueryUI 对话框组件的时候,div最好设置为隐藏。
     要不然可能会出现浏览器兼容性问题。
     
     <div id="dialog-confirm" title="Delete the campaign group?" style="display:none;">
            <p>
                <span class="ui-icon ui-icon-alert"
                    style="float: left; margin: 0 7px 20px 0;"></span> Are you sure?
            </p>
        </div>
        
    186.jQueryUI datepicker日历组件。
     为了给该组件增加1个“clear”按钮,我们修改close的文本为clear,然后给它增加事件。
     遇到的问题是,最小值和最大值 范围 选择时,遇到了bug,不好解决。
     
     换成My97Datepicker.
     
     还是专业的更好啊!!!
     
    187.JUnit单元测试的参数顺序问题。
     void junit.framework.Assert.assertEquals(String expected, String actual)
    Asserts that two Strings are equal.

    第1个参数是“期待的”,第2个参数才是 实际的值。
    很长时间以来,我都搞错了顺序,今天才发现。

    188.Spring 读取属性配置文件。
    <!– Properties文件读取配置,*.properties –>
        <context:property-placeholder location="classpath*:*.properties" />
        
        总是提示"${jdbc.url}"无法解析。
        
        不起作用的配置
        <context:property-placeholder location="classpath:*.properties" />

     
        <bean id="propertyConfigurer"
            class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:*.properties</value>
                </list>
            </property>
        </bean>
        
        正确的方法,把上面的2种的“classpath:*.properties”改为"classpath*:*.properties"就可以了。
        
        说明我弄的是maven项目,分成src/main/java和src/main/resource 2个Source Folder。
        
        我的理解是:2个Source Folder都在classpath下,classpath*可以包含2个,这样就能找到
        src/main/resource路径下的jdbc.properties等属性配置文件了
        classpath*相关参考:http://blog.csdn.net/kkdelta/article/details/5507799
        
    189.多个产品同步用户的问题。
        User有2个标识字段 isChanged是否已经变更
        updateTime,更新时间
        
        增量同步:同步某个时间点后变更的。
        全量同步:如果指“同步所有变更的”,是有问题的。一个产品同步user后,isChanged已经被修改了。
        其它产品就不能同步了。
        
        最终的定义:不要isChanged字段,只保留updateTime
        
        其它产品同步用户时,带1个时间戳,或者带1个特殊标志,则同步所有的。
        (不再存在用户是否变更这一说法)

    190.数据同步接口的主动同步与被动同步。

    主动同步:程序定时,发送URL请求,同步另外一个系统的数据。
    被动同步:拥有数据的系统,当数据发生了变化时,回调需要同步数据的项目的接口。

    191.Commons Fileupload组件可以用来方便地实现文件上传。
        功能还挺多的。
        http://commons.apache.org/proper/commons-fileupload/
        
        今天才知道,SpringMVC上传文件,底层使用的是commons-fileupload。
        SpringMVC也会偷懒,避免了重复造轮子。

    192.英语词汇要统一。
       StartTime和BeginTime都表示开始,StopTime和EndTime都可以表示结束时间。
       
       要么都用StartTime和StopTime,要么都用BeginTime和EndTime。
       类似的还有增加,使用Add或者Create,修改Modify或者Update。
       

    193.表格的排序和图形标志要一致。
       表格初始化的时候,结果集是按照id降序排列的,而图形标志却为非排序状态。


    194.将My97Datepicker接收的日期是'2013-08-22'这种格式,后台需要转化为java.util.Date。
    一不小心,日期的格式设置成了“YYYY-MM-HH”。

    public static Date parseDate(String date) {
            if(StringUtils.isEmpty(date)){
                return null;
            }
            
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date d = null;
            try {
                d = format.parse(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return d;
        }

    结论:重新实现一次很基本的功能,也可能出错。
    使用以前的代码,经过检验的代码还是比较靠谱的。
    单元测试仍然很有必要。

    195.笔记本的Win7系统大半年没有更新了,比较卡,重装了系统。
    遇到几个问题,网卡驱动没有安装,只好使用以前下载的惠普驱动。
    发现不起作用。

    最终:在惠普官网上,下载了好几个驱动,某一个成功了。

    备份驱动、资料、数据库数据 都很必要。

    196.更改eclipse中maven默认本地库repository的位置。
    更换系统前,我把Maven的配置 .m2文件夹备份到了非系统盘目录,
    现在要把Eclipse中Maven的位置修改为现在的位置,避免以后换系统再次备份,
    避免现在重新下载库和影响到现在的项目。

    Perferences-Maven-UserSetting,先设置maven的settings.xml
    的位置,然后reindex。(首先修改settings.xml的文件)

     <settings 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/xsd/settings-1.0.0.xsd">
      <localRepository>
        E:MavenRepository
      </localRepository>
    </settings>

    参考资料:http://blog.sina.com.cn/s/blog_52ef937201019waa.html

    http://blog.chinaunix.net/uid-714081-id-2678568.html

    197.Mybatis SQL语句优化,使用子查询代替联表。
    <!– 性能很低,已经废弃 –>
        <!– 超级管理员 没有权限限制,普通用户有2种情况 –>
        <select id="list2" parameterType="campaign" resultType="campaign">
            select distinct mc.*,mp.startTime,mp.endTime from st_monitor_campaign
            mc
            <if test="userId != null">,st_monitor_campaign_permission mcp
            </if>
            ,st_media_plan mp
            where
            …
            <!– 用户有权限,或者是自己或子用户创建的 –>
            <if test="userId != null">
                and (
                ( mc.MCampaignId = mcp.MCampaignId
                and permission = 1
                and
                userId =
                #{userId} ) or (mc.CreatedUserId in (${userIdList}) ))
            </if>
            
            (3种权限情况,只有1种情况需要连接st_monitor_campaign_permission表)
            优化后(mc.CreatedUserId in (${userIdList})这个地方避免了连接permission表,而且是全表扫描)
            使用mysql explain命令查看sql语句的各种详细细节,对sql优化很有帮助
            
          select distinct mc.*,mp.startTime,mp.endTime from st_monitor_campaign
            mc,st_media_plan mp
            where
            …
            <!– 用户有权限,或者是自己或子用户创建的 –>
            <if test="userId != null">
                and (
                ( mc.MCampaignId in (select mcp.MCampaignId
                from st_monitor_campaign_permission mcp
                where permission = 1
                and
                userId =
                #{userId}) ) or (mc.CreatedUserId in (${userIdList}) ))
            </if>
            
            从这个例子,可以看出Mybatis的好处。sql优化比较方便,不需要重新编译,不需要修改接口。
            
    198.Window系统的电脑连接投影仪
       Win+P,快捷键,直接出现连接到投影仪 选项–仅计算机、复制、扩展、仅投影仪。
       或者 在桌面->右键 屏幕分辨率->连接到投影仪->仅计算机、复制、扩展、仅投影仪。
       
       复制 是最好的选择,电脑和投影仪画面完全一致,即投影仪的界面是 电脑的“副本”。
       而扩展则需要把电脑中的画面 拖进某个地方,投影仪才能看到。具体不好描述。
       
       建议:优先使用复制,其次才是投影仪。

    199.java -Dfile.encoding设置解决程序运行乱码问题。
    Java默认使用的是系统的编码,比如 Win7中文系统默认就使用GBK,读文件时默认按照GBK格式读取。
    通过设置java -Dfile.encoding,可以按照自己定义的编码来读取文件。

    200.慎用全局变量。
    Spring中的Service,单例的。
    class UserService{

        @Autowired
        private CampaignGroupDAO campaignGroupDAO;
        
     private List<Integer> allSonUserIds = new ArrayList<Integer>();
     
     //获得1个用户的所有子用户
    public List<Integer> getSonUserIds(int userId) {
            List<Integer> userIds = userDAO.getSonUserIds(userId);
            if(!userIds.isEmpty()){
                for (Integer id : userIds) {
                    allSonUserIds.add(id);
                    getSonUserIds(id);
                }
            }
            return allSonUserIds;
        }
    }

    错误的写法2
    public List<Integer> getSonUserIds(int userId) {
            //记录所有的子用户的Id
            List<Integer> allSonUserIds = new ArrayList<Integer>();
            List<Integer> userIds = userDAO.getSonUserIds(userId);
            if(!userIds.isEmpty()){
                for (Integer id : userIds) {
                    allSonUserIds.add(id);
                    getSonUserIds(id);
                }
            }
            return allSonUserIds;
        }
    说明:这段代码不是我写的啊,别喷我。o(︶︿︶)o

    个人看法:使用迭代
    public List<Integer> getSonUserIds(int userId) {
            //维护所有的
               List<Integer> allList = new ArrayList<Integer>();
                
            //维护一个“队列”
            List<Integer> allSonUserIds = new ArrayList<Integer>();
            allSonUserIds.add(userId);
            allList.add(userId);
            
            for(Integer userId :allSonUserIds){
             List list= userDAO.getSonUserIds(userId);
             //修改当前队列
             allSonUserIds.addAll(list);
             //删除已经遍历过的元素
             allSonUserIds.remove(userId);
            
             //维护所有的用户id
             allList.addAll(list);
            }
            
            return allList;
        }

        使用迭代的代码似乎也存在这个问题,即迭代中删除元素导致的问题,
        我在“2013年工作中遇到的20个问题:1-20”第16个有描述,使用
        for(Iterator iterator =p.iterator();iterator.next();){
     if(){
       iterator.remove();
     }
    }
     这种方式不会有问题,而for循环有问题
     ######################################################
    for(int index=0;index<p.size();index++){—不再正确,因为index也发生了变化


     。
     
     现在的问题是for-each循环是否正确呢??
      allSonUserIds.remove(userId); 这种方式删除元素,效率也比较地。
     
      最好还是使用Iterator进行遍历和删除。
     
     另外一个问题:
          //维护一个“队列”
            List<Integer> allSonUserIds = new ArrayList<Integer>();
        
        维护队列还是使用Queue比较好,push和pop也很合适。
        
        和公司大牛谈到这个问题,让我想起了大二写遍历二叉树算法,使用迭代而非递归实现时,
    当时用的就是队列。

       问题故而知新!!!

    相关阅读

    工作问题 http://blog.csdn.net/FansUnion/article/category/1334371

    原文参见http://fansunion.cn/articles/2313
  • 相关阅读:
    《大道至简》读后感
    第一周学习总结-Java
    c++与java的几个不同点
    单调队列 滑动窗口模型
    计算空间
    关于dp初始化问题
    康托展开小结-
    Vm-Ubuntu下配置Qt开发环境
    C++学习013多态
    C++学习012友元
  • 原文地址:https://www.cnblogs.com/qitian1/p/6463632.html
Copyright © 2020-2023  润新知