SqlServer注意事项总结,高级程序员必背!

来源:http://www.sh-fengwen.com 作者:气血双补 人气:60 发布时间:2019-09-07
摘要:本篇文章主要介绍SqlServer使用时的注意事项。 a.建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。使用场景比如最常见的AlertDialog,拿我们

本篇文章主要介绍SqlServer使用时的注意事项。

a.建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。使用场景比如最常见的AlertDialog,拿我们开发过程中举例,比如Camera开发过程中,可能需要设置一个初始化的相机配置,设置摄像头方向,闪光灯开闭,成像质量等等,这种场景下就可以使用建造者模式

想成为一个高级程序员,数据库的使用是必须要会的。而数据库的使用纯熟程度,也侧面反映了一个开发的水平。

装饰者模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。装饰者模式可以在不改变原有类结构的情况下曾强类的功能,比如Java中的BufferedInputStream 包装FileInputStream,举个开发中的例子,比如在我们现有网络框架上需要增加新的功能,那么再包装一层即可,装饰者模式解决了继承存在的一些问题,比如多层继承代码的臃肿,使代码逻辑更清晰观察者模式:代理模式:门面模式:单例模式:生产者消费者模式:

下面介绍SqlServer在使用和设计的过程中需要注意的事项。

这个通过对比来描述,比如面向对象和面向过程的对比,针对这两种思想的对比,还可以举个开发中的例子,比如播放器的实现,面向过程的实现方式就是将播放视频的这个功能分解成多个过程,比如,加载视频地址,获取视频信息,初始化解码器,选择合适的解码器进行解码,读取解码后的帧进行视频格式转换和音频重采样,然后读取帧进行播放,这是一个完整的过程,这个过程中不涉及类的概念,而面向对象最大的特点就是类,封装继承和多态是核心,同样的以播放器为例,一面向对象的方式来实现,将会针对每一个功能封装出一个对象,吧如说Muxer,获取视频信息,Decoder,解码,格式转换器,视频播放器,音频播放器等,每一个功能对应一个对象,由这个对象来完成对应的功能,并且遵循单一职责原则,一个对象只做它相关的事情

SqlServer注意事项

java中有三种创建线程的方式,或者说四种1.继承Thread类实现多线程2.实现Runnable接口3.实现Callable接口4.通过线程池

Sql事务启动语句

线程池的工作原理:线程池可以减少创建和销毁线程的次数,从而减少系统资源的消耗,当一个任务提交到线程池时a. 首先判断核心线程池中的线程是否已经满了,如果没满,则创建一个核心线程执行任务,否则进入下一步b. 判断工作队列是否已满,没有满则加入工作队列,否则执行下一步c. 判断线程数是否达到了最大值,如果不是,则创建非核心线程执行任务,否则执行饱和策略,默认抛出异常

开始事务:BEGIN TRANSACTION

Handler,Message,looper 和 MessageQueue 构成了安卓的消息机制,handler创建后可以通过 sendMessage 将消息加入消息队列,然后 looper不断的将消息从 MessageQueue 中取出来,回调到 Hander 的 handleMessage方法,从而实现线程的通信。

提交事务:COMMIT TRANSACTION

从两种情况来说,第一在UI线程创建Handler,此时我们不需要手动开启looper,因为在应用启动时,在ActivityThread的main方法中就创建了一个当前主线程的looper,并开启了消息队列,消息队列是一个无限循环,为什么无限循环不会ANR?因为可以说,应用的整个生命周期就是运行在这个消息循环中的,安卓是由事件驱动的,Looper.loop不断的接收处理事件,每一个点击触摸或者Activity每一个生命周期都是在Looper.loop的控制之下的,looper.loop一旦结束,应用程序的生命周期也就结束了。我们可以想想什么情况下会发生ANR,第一,事件没有得到处理,第二,事件正在处理,但是没有及时完成,而对事件进行处理的就是looper,所以只能说事件的处理如果阻塞会导致ANR,而不能说looper的无限循环会ANR

回滚事务:ROLLBACK TRANSACTION

另一种情况就是在子线程创建Handler,此时由于这个线程中没有默认开启的消息队列,所以我们需要手动调用looper.prepare(),并通过looper.loop开启消息

相关注意事项

主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。

保持事务简短,事务越短,越不可能造成阻塞。

1.非静态内部类的静态实例非静态内部类会持有外部类的引用,如果非静态内部类的实例是静态的,就会长期的维持着外部类的引用,组织被系统回收,解决办法是使用静态内部类

在事务中尽量避免使用循环while和游标,以及避免采用访问大量行的语句。

2.多线程相关的匿名内部类和非静态内部类匿名内部类同样会持有外部类的引用,如果在线程中执行耗时操作就有可能发生内存泄漏,导致外部类无法被回收,直到耗时任务结束,解决办法是在页面退出时结束线程中的任务

事务中不要要求用户输入。

3.Handler内存泄漏Handler导致的内存泄漏也可以被归纳为非静态内部类导致的,Handler内部message是被存储在MessageQueue中的,有些message不能马上被处理,存在的时间会很长,导致handler无法被回收,如果handler是非静态的,就会导致它的外部类无法被回收,解决办法是1.使用静态handler,外部类引用使用弱引用处理2.在退出页面时移除消息队列中的消息

在启动事务前完成所有的计算和查询等操作。

4.Context导致内存泄漏根据场景确定使用Activity的Context还是Application的Context,因为二者生命周期不同,对于不必须使用Activity的Context的场景,一律采用Application的Context,单例模式是最常见的发生此泄漏的场景,比如传入一个Activity的Context被静态类引用,导致无法回收

避免同一事务中交错读取和更新。可以使用表变量预先存储数据。即存储过程中查询与更新使用两个事务实现。

5.静态View导致泄漏使用静态View可以避免每次启动Activity都去读取并渲染View,但是静态View会持有Activity的引用,导致无法回收,解决办法是在Activity销毁的时候将静态View设置为null(View一旦被加载到界面中将会持有一个Context对象的引用,在这个例子中,这个context对象是我们的Activity,声明一个静态变量引用这个View,也就引用了activity)

超时会让事务不执行回滚,超时后如果客户端关闭连接sqlserver自动回滚事务。如果不关闭,将造成数据丢失,而其他事务将在这个未关闭的连接上执行,造成资源锁定,甚至服务器停止响应。

6.WebView导致的内存泄漏WebView只要使用一次,内存就不会被释放,所以WebView都存在内存泄漏的问题,通常的解决办法是为WebView单开一个进程,使用AIDL进行通信,根据业务需求在合适的时机释放掉

避免超时后还可打开事务 SET XACT_ABORT ON统计信息可以优化查询速度,统计信息准确可以避免查询扫描,直接进行索引查找。

7.资源对象未关闭导致如Cursor,File等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为null

sp_updatestats可以更新统计信息到最新。

8.集合中的对象未清理集合用于保存对象,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的

低内存会导致未被客户端连接的查询计划被清除。

9.Bitmap导致内存泄漏bitmap是比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的bitmap对象

修改表结构,修改索引后,查询计划会被清除,可以再修改后运行几遍查询。

10.监听器未关闭很多需要register和unregister的系统服务要在合适的时候进行unregister,手动添加的listener也需要及时移除

DDL DML交错和查询内部SET选项将重新编译查询计划。

1.使用更加轻量的数据结构:如使用ArrayMap/SparseArray替代HashMap,HashMap更耗内存,因为它需要额外的实例对象来记录Mapping操作,SparseArray更加高效,因为它避免了Key Value的自动装箱,和装箱后的解箱操作

order by 影响查询速度。

2.便面枚举的使用,可以用静态常量或者注解@IntDef替代

where中使用函数则会调用筛选器进行扫描,扫描表要尽量避免。

3.Bitmap优化:a.尺寸压缩:通过InSampleSize设置合适的缩放b.颜色质量:设置合适的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差异c.inBitmap:使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小,但复用存在一些限制,具体体现在:在Android 4.4之前只能重用相同大小的Bitmap的内存,而Android 4.4及以后版本则只要后来的Bitmap比之前的小即可。使用inBitmap参数前,每创建一个Bitmap对象都会分配一块内存供其使用,而使用了inBitmap参数后,多个Bitmap可以复用一块内存,这样可以提高性能

updlock和holdlock同时使用可以在早期锁定后面需要更新的资源,维护资源完整性,避免冲突。

4.StringBuilder替代String: 在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”

如果不需要使用临时表的统计信息来进行大数据查询,表变量是更好的选择。

5.避免在类似onDraw这样的方法中创建对象,因为它会迅速占用大量内存,引起频繁的GC甚至内存抖动

事务使用注意事项

6.减少内存泄漏也是一种避免OOM的方法

设置事务隔离级别(未提交读,读脏),相当于(NOLOCK) 的语句:

启动模式

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Standard 模式:Activity 可以有多个实例,每次启动 Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例

隔离级别描述如下:

SingleTop模式:当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例

1.READ UNCOMMITTED

SingleTask模式:如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈

READ UNCOMMITTED:未提交读,读脏数据。

SingleInstance模式:singleInstance 模式也是单例的,但和singleTask不同,singleTask 只是任务栈内单例,系统里是可以有多个singleTask Activity实例的,而 singleInstance Activity 在整个系统里只有一个实例,启动一singleInstanceActivity 时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity

默认的读操作:需要请求共享锁,允许其他事物读锁定的数据但不允许修改。

生命周期

READ UNCOMMITTED:读操作不申请锁,允许读取未提交的修改,也就是允许读脏数据,读操作不会影响写操作请求排他锁。

onCreate onStart onResume onPause onStop onDestroy

2.READ COMMITTED

两个 Activity 跳转的生命周期1.启动AonCreate - onStart - onResume

READ COMMITTED(已提交读)是SQL SERVER默认的隔离级别,可以避免读取未提交的数据,隔离级别比READ UNCOMMITTED未提交读的级别更高;

2.在A中启动BActivityA onPauseActivityB onCreateActivityB onStartActivityB onResumeActivityA onStop

该隔离级别读操作之前首先申请并获得共享锁,允许其他读操作读取该锁定的数据,但是写操作必须等待锁释放,一般读操作读取完就会立刻释放共享锁。

3.从B中返回AActivityB onPauseActivityA onRestartActivityA onStartActivityA onResumeActivityB onStopActivityB onDestroy

3.REPEATABLE READ

4.继续返回ActivityA onPauseActivityA onStopActivityA onDestroy

REPEATABLE READ(可重复读):保证在一个事务中的两个读操作之间,其他的事务不能修改当前事务读取的数据,该级别事务获取数据前必须先获得共享锁同时获得的共享锁不立即释放一直保持共享锁至事务完成,所以此隔离级别查询完并提交事务很重要。

按下home键之后,然后切换回来,会调用onRestart从本Activity跳转到另一个Activity之后,按back键返回原来Activity,会调用onRestart从本Activity切换到其他的应用,然后再从其他应用切换回来,会调用onRestart();

本文由美高梅游戏平台网站发布于气血双补,转载请注明出处:SqlServer注意事项总结,高级程序员必背!

关键词:

上一篇:没有了

下一篇:没有了

最火资讯