【Android】PA4D_CH7 文件、保存状态和首选项

本章主要知识点如下:

  • 了解Shared Preferences
  • 接口OnSharedPreferenceChangeListener, 每当添加、移除或者修改一个特定的Shared Preference 时候可以调用一个回调函数
  • 创建Preference Screen(首选项框架)
    • PreferenceActivity,  适用于API Level 11 (SDK3.0) 以前(xml 配置)
    • PreferenceFragment, 适用于API Level 11 (SKD3.0) 以后,兼容平板 (preserence-header配置)
    • Activity中根据当前版本号动态配置二者
    • Preference Screen中,  使用了ListPreference控件 , 默认保存的是String类型的值
    • 可以继承Preference Screen中的组件, 并且重写组件,实现各种功能,比如在设置中选择字体的颜色
  • 在Activity销毁或者隐藏以后,保存Fragment的状态
  • 添加静态文件作为资源
  • 使用Environment获取目录

【Android】PA4D_CH6 使用Internat资源

  1. android中,基本使用网络资源方式如下(同步)
    try {
          URL url = new URL(myFeed);
    
          // Create a new HTTP URL connection
          URLConnection connection = url.openConnection();
          HttpURLConnection httpConnection = (HttpURLConnection)connection;
    
          int responseCode = httpConnection.getResponseCode();
          if (responseCode == HttpURLConnection.HTTP_OK) {
            InputStream in = httpConnection.getInputStream();
            processStream(in);
          }
        }
        catch (MalformedURLException e) {
          Log.d(TAG, "Malformed URL Exception.", e);
        }
        catch (IOException e) {
          Log.d(TAG, "IO Exception.", e);
        }
    
  2. 于此同时,android中解析XML主要有3种,分别为DOM解析器、SAX解析器和PULL解析器。
    1. DOM解析器,DomBuilder,通过DocumentBuilderFactory获取。这两个类都是javax包中定义的,不同于j2SE的是,android中重写了后者,直接获取了apache harmony的实现,不幸的是,harmony的项目在2011年时候已经被apache放弃了。
    2. SAX解析器。SAX是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。 SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。
      SAXParserFactory factory=SAXParserFactory.newInstance();  
      SAXParser parser=factory.newSAXParser();  
      MyHandel handel=new MyHandel ();  //此处MyHandle继承自DefaultHandel
      parser.parse(inputStream, handel);
      
    3. PULL解析器。以下来自android training,google比较推荐使用这个解析器
      为什么要学习PULL解析器呢?因为PULL解析是在XML文档中寻找想要的标记,把需要的内容拉入内存,而不是把整个文档都拉入内存,这种方式比较适合手机等内存有限的小型的移动设备。

      We recommend XmlPullParser, which is an efficient and maintainable way to parse XML on Android. Historically Android has had two implementations of this interface:

SQL Server 2012 不支持创建连接服务器到 2000 版本,及其替代方案

翻译自“sqlwithmanoj”的博客

http://sqlwithmanoj.wordpress.com/tag/sqlncli10/

小伙伴们震惊了吧,“SQL Server 2012” 不支持通过连接服务器的方式连接到“SQL Server 2000”了。SQL Server 2012 采用了新版本的SQLNCL11(SQL Server Native Client 11)替代了以前的SQLNCL10,这个客户端只支持连接到2008R2,2008,2005版本的数据库。

笔者加一句:这个SQLNCL11不仅不能通过分布查询连接2000版本数据库,还原操作也不能进行,简而言之,不能读取2000版本的数据了。

问题是这样复现的:

  • 我将我的数据库升级从 2008R2 升级到了2012

  • 将从2008R2 服务器备份的数据库文件还原到了 2012服务器上

  • 在新服务器上执行任务时候,出现了这样的错误

错误信息:

OLE DB provider “SQLNCLI11″ for linked server “NorthWind2000″ returned message “Client unable to establish connection”.
Msg 22, Level 16, State 1, Line 0
SQL Server Native Client 11.0 does not support connections to SQL Server 2000 or earlier versions.
OLE DB provider “SQLNCLI11″ for linked server “NorthWind2000″ returned message “Invalid connection string attribute”.

由于我是升级了数据库,所以我把问题定位到了连接服务器的OLE DB(对象链接嵌入数据库)应用程序接口上,发现了这个SQLNCL11的版本,同时我的服务器上还有SQLNCL10版本。

所以我试着显示使用SQLNCL10去创建连接服务器,但还是出现了如下异常:

Msg 8522, Level 16, State 3, Line 1
Microsoft Distributed Transaction Coordinator (MS DTC) has stopped this transaction.

我贴出我创建连接服务器的脚本,如下:

USE [master]
GO</p>

<p>-- Existing LinkedServer [NorthWind2000]:
EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'MSSQL', @provider=N'SQLNCLI', @provstr=N'PROVIDER=SQLOLEDB;SERVER=NorthWind'</p>

<p>EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO

—>以下是替代的解决方案:

使用ODBC是一个比较好的方案,有两种实现方式

  1. 在操作系统中穿件一个ODBC Data Source (DSN),在SQLSERVER中只用这个DSN创建连接服务器。
  2. 创建连接服务器时候,直接使用DSN的连接字符串调用ODBC接口。

第一种方式:

首先创建ODBC数据源

  • 打开控制面板,进入管理工具,选择”数据源(ODBC)“

  • 在”ODBC数据源管理器“页签,选取”系统DSN“面板

  • 单击添加创建一个新的数据源

  • 选择”SQL Server“然后点击完成

笔者多嘴2:基本上各大数据库甚至excel都提供了相关接口,都可以连接

  • 在新建数据源页面,建议给数据源适当的命名(比如: NorthWind2000DSN),这个命名会在以后创建练级服务器时候使用到,这里就叫NorthWind,点击下一步

  • 选择验证方式,Windows验证或者Sqlserver都无所谓,进入下一步

  • 选择默认数据库,不选也无所谓,下一步

  • 点击完成,新的DSN就创建了

现在可以使用DSN创建连接服务器了,在@dadasrc参数中使用DSN名称,同时@provider参数中要填写”MSDASQL“.

以下是示例SQL

-- Drop Existing LinkedServer [NorthWind2000]:
EXEC master.dbo.sp_dropserver @server=N'NorthWind2000', @droplogins='droplogins'
GO</p>

<p>-- Re-create LinkedServer [NorthWind2000] by using the ODBC connection:
EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'MSDASQL', @provider=N'MSDASQL', @datasrc = N'NorthWind2000DSN', @location=N'System';</p>

<p>EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO

第二种方式:

直接使用DSN字符串也挺好,在@provstr参数中直接使用DSN连接字符串,请看:

-- Drop Existing LinkedServer [NorthWind2000]:
EXEC master.dbo.sp_dropserver @server=N'NorthWind2000', @droplogins='droplogins'
GO
-- Re-create LinkedServer [NorthWind2000] by using the ODBC connection:
EXEC master.dbo.sp_addlinkedserver @server = N'NorthWind2000', @srvproduct=N'', @provider=N'MSDASQL', @provstr=N'DRIVER={SQL Server};SERVER=NorthWind;Trusted_Connection=yes;'</p>

<p>EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'NorthWind2000',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO

使用这种方式可以实现在2012服务器上分布式查询2000版本数据库的数据。

这种方式看似可以直接替代以前的连接服务器,其实效率降低了,如果想实现更有效率的ETL操作,建议升级源数据库的版本,至少到SQL2005。

笔者多嘴3:据不完全统计,ODBC数据源查询效率约为使用SQLNCL查询的1/4。

Kettle 环境变量设置

  1. Java环境变量,可以调用所有的java中System.properties中的相关变量。
  2. 手动定义环境变量,可以通过“Set Variables”步骤进行设置,或者通过编辑作业属性中的Paramaters页签进行设置。
  3. 内部环境变量,Kettle自身的
    1. Internal.Kettle.Build.Date:2007/05/22 18:01:39 创建时间
    2. Internal.Kettle.Build.Version:2045
    3. Internal.Kettle.Version:2.5.0
    4. Internal.Transformation.Filename.Directory:D:\Kettle\samples 当前转换运行目录
    5. Internal.Transformation.Filename.Name:Denormaliser – 2 series of key-value pairs.ktr 当前运行转换文件名称
    6. Internal.Transformation.Name:Denormaliser – 2 series of key-value pairs sample 当前转换名称
    7. Internal.Transformation.Repository.Directory:/  资料库路径
    8. Internal.Job.Filename.Directory:/home/matt/jobs 作业目录
    9. Internal.Job.Filename.Name:Nested jobs.kjb 作业文件名
    10. Internal.Job.Name:Nested job test case 作业名
    11. Internal.Job.Repository.Directory:/ 作业资料库名
    12. Internal.Slave.Transformation.Number:0..<cluster size-1> (0,1,2,3 or 4) 集群模式下有,转化号码
    13. Internal.Cluster.Size:<cluster size> (5) 集训数量

【迁移】[转载]getBoundClientRect函数详解

原文:http://www.cnblogs.com/2050/archive/2012/02/01/2335211.html

一、定义

getBoundingClientRect 函数是W3C组织在第一版本的W3C CSSOM View specification草案中确定的一个标准方法,在此之前,只有IE浏览器是支持该方法的,W3C在这次草案中把它扶正成为标准,足可以看出它并不简单。getBoundingClientRect 方法返回的是调用该方法的元素的TextRectangle对象,该对象具有top、left、right、bottom四个属性,分别代表该元素上、左、右、下四条边界相对于浏览器窗口左上角(注意,不是文档区域的左上角)的偏移像素值。

 

二、兼容性

getBoundingClientRect方法最先在IE5中出现,后来被W3C接纳成为标准。目前IE5.5+、Firefox 3.5+、Chrome 4+、Safari 4.0+、Opara 10.10+等浏览器均支持该方法,兼容性几乎完美。

在具体表现方面,Firefox6以前的版本使用getBoundingClientRect时不能获取到top和bottom这两个属性值,Firefox6及以后的版本和其他支持getBoundingClientRect方法的浏览器则top、left、right、bottom四个属性值均能获取到。需要说明的是由于某些版本的IE浏览器的<html>文档根元素默认是有2px边框的,所以这里需要特别处理一下,微软MSDN上说在IE5中会存在这样的情况,但据我实际测试,xp系统中IE6也存在这样的问题,奇怪的是,我在win7环境下用IETester测试的IE各版本都是正常的。但这并不是什么大问题,我们只要把得到的值减去html根元素(body也可考虑进来)的clientLeft或clientTop就能保持各浏览器一致啦。

 

三、用途

当getBoundingClientRect刚被w3c列为标准的时候,PPK还曾质疑过它是不是多此一举,因为已经存在类似的方法来获取元素的偏移位置,比如offsetLeft和offsetTop。但Jquery的作者John Resig马上阐明了getBoundingClientRect的用处。用传统的方法固然可以实现getBoundingClientRect同样的功能,但兼容各种浏览器以及各种不同的元素就会把你弄死,而且效率还非常低下。所以获取页面上某个元素相对于浏览器窗口的偏移量就成了getBoundingClientRect的用武之地了。而获取元素的偏移量能有什么用,我相信,你懂的~ ^_^

【迁移】数据库查询调优(SQL 2008)

  • 数据合并程序调优

关键词:系统问题定位  系统速度调优  消除java程序中循环的数据库操作

背景:程序主要功能是将业务数据定时的从数据库中进行提取,合并,并且导入到接口库中的一个java service程序。随着业务系统以及业务数据的增加,程序执行速度下降显著。由于是数据增加以后出现的这个问题,所以问题定位在数据库操作之上。

调优攻略:

  1. 查询历史执行日志,发现日志使用log4j打出了debug信息,其中包含每一步的操作时间,调查时间间隔比较长的几个步骤。
  2. 查询目标步骤涉及的表数据,发现目标表数据量都很大,有3张表数据达到千万。
  3. 查询其中一张表的全部打印日志,发现操作随着时间变慢,基本都是新增或更新数据的操作。
  4. 根据SQL,对抽取涉及到查询的列创建索引,发现速度基本没有变化。
  5. 由于有源码,查看源码逻辑,发现源码中对每条数据都先进行一次查询有没有的数据库操作,然后才进行一次增加或者更新操作。业务系统每天产生约1W条数据,那么光这一张表就会进行至少2W次操作,并且是在一张1000W大小的表上。
  6. 更改上面逻辑,将更新和新增统一变为先删除,后新增的操作。业务系统无论产生多少数据,只进行2次数据库操作。
  7. 问题解决。

后话:更改以后的操作受到了限制,如果源数据库和目标数据库不在同一台服务器,就会无法完成合并,即:SQL是跨数据库的。但是考虑了实际环境,两个库不可能分开,所以这么写了。

  • 查询统计调优

  关键词统计信息更新  索引创建  执行计划  性能监视器  查询跟踪器

  背景:之前一个统计分析子系统对数据仓库有大量的查询操作。某一天,用户提出某一个模块查询过慢,导致程序无法正常运行。

  服务器操作系统:winserver2003

  数据库:MSSQLServer 2008

调优攻略:

  1. 使用性能监视器进行监视,开始执行目标操作以后,观察计数器获取线索:
  2. Memory Page Faults/sec  每次执行都会保持很高的值
  3. Memory Page /sec 第一次执行会有值,以后则没有
  4. 说明这个SQL执行过程会进行大量数据的扫描。
  5. 使用SQL Server Profiler开始跟踪,模板选择TSQL,这样会过滤掉一些其他的操作,然后执行目标操作,对SQL进行捕获。
  6. 分析目标SQL,综合索引,查询的表数据量较大,800W左右,但是SQL没有不同,之前查询经过优化,对应分组和过滤的列上也创建有索引。
  7. 对近期客户数据进行比对,发现目标表数据增加了部分,总量的1/20左右,不会对查询造成过大影响。
  8. 偶尔发现查询更改作为参数的查询日期会得出不同的查询速度。分析执行计划,发现执行计划不同。
  9. 查看目标表对应索引的统计信息,发现统计信息不完整,是抽样1.5%得出,只有200行左右。
  10. 目标表每日有合并操作,操作内容是截断表和新增数据,这个操作会引发更新统计信息的操作。
  11. 在合并过程中增加全量更新统计信息操作解决。

深入剖析:

  问题本质: 过时或者抽样率过小的统计信息会导致效率低下的执行计划.

  truncate操作以后表的统计信息会过时, 新的统计信息收集会在第一次查询时候进行收集,收集信息策略如下:

  数据库设置了参数AUTO_CREATE_STATISTICS, 统计信息会自动进行更新具体更新阈值Recompilation threshold (RT)如下:

      1. Permanent table 永久表, 数据量 = n
        • If n <= 500, RT = 500.
        • If n > 500, RT = 500 + 0.20 * n.
      1. Temporary table 临时数据库表 , 数据量=n
        • If n < 6, RT = 6.
        • If 6 <= n <= 500, RT = 500.
        • If n > 500, RT = 500 + 0.20 * n.
      1. Table variable 表变量不进行统计

查看原文

  对于数据量比较大的表, 自动更新策略会比较缩水,以下是微软的原文:

  “ 当 AUTO_UPDATE_STATISTICS 数据库选项设置为 ON(默认值)时,查询优化器会在表中的数据发生变化时自动定期更新这些统计信息。每当查询执行计划中使用的统计信息没有通过针对当前统计信息的测试时就会启动统计信息更新。 采样是在各个数据页上随机进行的,取自表或统计信息所需列的最小非聚集索引。 从磁盘读取一个数据页后,该数据页上的所有行都被用来更新统计信息。常规情况是:在大约有 20% 的数据行发生变化时更新统计信息。但是,查询优化器始终确保采样的行数尽量少。对于小于 8 MB 的表,则始终进行完整扫描来收集统计信息。”

这也就是为什么数据的统计信息始终只有很少的原因。

查看原文

ps: 创建索引时候自动创建的统计信息抽样率为100%

ps2: 无论使用什么手动办法更新statistics, 如果不明文指定FULLSCAN, 那么数据库始终使用抽样的方式进行信息收集。(_)

调优感想:

  1. 统计信息的查看方式有很多

更多用法

  1.  也可以查询动态视图
  1.  

    更多动态视图用法

    1. 查看统计信息时候要注意,数据库忙的时候,会使用抽样的方式来进行统计信息,此时的统计信息虽然无可厚非,但是对于数据量比较大的表,单靠索引存活,那么很可能导致严重的查询问题。
    2. 这种问题的典型例子就是对于同样的SQL不同的参数,执行计划不同
    3. 解决办法暂时只是想到了定时进行数据库的统计信息更新,另外,选择TRUNCATE操作一定要慎重。

     通过存储过程

     

    或者通过T-SQL

     

    常用的系统存储过程说明

    sp_who    (sp_who2)报告有关当前 SQL Server 用户和进程的快照信息,包括当前正在执行的语句以及该语句是否被阻塞。

    sp_lock    报告有关锁的快照信息,包括对象 ID、索引 ID、锁的类型以及锁应用于的类型或资源。

    sp_spaceused    显示对表(或整个数据库)所用的当前磁盘空间量的估计。

    sp_monitor    显示统计信息,包括 CPU 使用率、I/O 使用率以及自上次执行 sp_monitor 以来的空闲时间。

    常用的动态管理视图说明

    常规服务器动态管理对象包括:

    dm_db_*:数据库和数据库对象

    dm_exec_*:执行用户代码和关联的连接

    dm_os_*:内存、锁定和时间安排

    dm_tran_*:事务和隔离

    dm_io_*:网络和磁盘的输入/输出

    以下举几个比较重要的动态视图。

    查看原文

    sys.dm_exec_query_stats DMV 提供缓存查询计划的汇总性能统计信息,包括有关物理和逻辑读/写以及查询执行次数的详细信息。它包含从实际 SQL 的父 SQL 中提取实际 SQL 所使用的偏移量。此 DMV 已联接到sys.dm_exec_sql_text DMF,后者包含与 I/O 有关的 SQL 批处理的信息。

    示例1:查询最费IO的查询

     

    示例2:查询最费CPU的查询

     

    示例3:使用 CLR(包括存储过程、函数和触发器)的语句

     

    示例4:最常执行的SQL

     

    示例5:受阻塞影响的查询

     

    sys.dm_db_missing_index_group_stats DMV 记录了 SQL 尝试使用特定缺失索引的次数。sys.dm_db_missing_index_details DMV 详细显示缺失索引的结构,例如查询所需的列。这两个 DMV 通过sys.dm_db_missing_index_groups DMV 联系在一起。缺失索引的开销(总开销列)的计算方法是,用户平均总开销与用户平均影响的积,再乘以用户搜寻次数与用户扫描次数的和。

     以下脚本来确定开销最高的缺失索引。此查询的结果(按“总开销”排序)显示最重要缺失索引的成本以及有关数据库/架构/表和缺失索引中所需列的信息。特别是,此脚本可确定哪些列在相等和不相等 SQL 语句中使用。另外,它还报告应将哪些其他列用作缺失索引中的包含性列。使用包含性列可以在不从基础页获取数据的情况下满足更多的覆盖查询,因而使用的 I/O 操作更少,从而提高性能。

    示例6:高开销的缺失索引

     

    sys.dm_exec_requests DMV中读取正在运行的请求,以及这个请求的句柄(sql_handle),通过句柄,可以从sys.dm_exec_sql_textDMF得到请求的具体内容。同时,通过(SPID)联接sys.processes这个表,可以得到运行语句的用户、数据库、及应用程序名。

    示例7:查询正在执行的SQL

【迁移】java 文件定位

java中,定位class的方式,总共有以下几种

  • XXX.class.getResource(String resourceName)
  • XXX.class.getClassLoader().getResource(String resourceName)
  • Thread.currentThread().getContextClassLoader().getResource()
  • XXX.class.getProtectionDomain().getCodeSource().getLocation() –只能获取类的路径
  • System.getProperty(“user.dir”)–只能获取java的启动目录

下面对各种方式进行评析

  1. 调用class类本身的getResource方法,入口有参数名称前面是否有“\”是有很大区别的
  2. 调用classLoader的getResource方法,入口参数不能有有“\”

RMIJdbc使用中的问题

最近项目里用到了rmijdbc,使用过程中发现了两个问题

  1. jdbc-odbc读取备注类型(meno)字段,混合数字的长文本容易出现阶段的现象
  2. rmi客户端连接执行查询时,会开启大量端口。大部分端口都只用一次就放弃不用,操作系统就会将端口设置为“TIME_WAIT”的状态

Continue reading “RMIJdbc使用中的问题”