课程笔记
异步跟多线程并不是一回事,异步就是与硬盘读写有关,性能比多线程稍微高一点、
多线程的调用方法是BeginInvoke();且只能是只有一个委托目标。非多播
异步多线程的三大特性:
1.同步卡界面,主线程比如ui线程被占用,多线程UI线程空闲,只是起到一个通知的作用,
具体计算任务交给子线程执行。
2.同步慢,因为只有一个线程干活,异步快是因为多个线程并发计算,这里也会消耗更多资
源,不是线程越多越好,(1.资源有限、2.线程调度耗资源、3.不稳定)
3.多线程是无序的,不可预测,启动顺讯不确定,消耗时间不确定,结束顺序不确定。不要
试图控制执行的顺序
Thread是前台线程,启动后必须执行完才会退出。 线程启动的要比委托BeginInvock()要快
一点。委托多线程:是后台线程,程序进程关了,线程全部强制关闭。一般都用后台线程
停止线程:靠的不是外部力量,比如线程的注销方法。而是靠自身,外部设置个信号量。内
部判断是否true还是false而是否继续执行
委托事件:观察者模式。反射:工厂模式。aop:装饰模式,代理模式,
多线程的使用方法有哪几种:
委托同步Invock():
异步beginInvock():
Async:
Thread:
ThreadPool线程池:控制创建和销毁、控制数量。
Task:方便带返回值、等待、回调。简单
Parallal:Task再次封装,并行计算,优化主线程逻辑,主线程也可以参与计算,能控制数
量,缺点就是只能等着。
ThreadCore:
加密算法:
des:对称可逆加密(也就是解密跟加密的密钥是一样的。缺点:密钥是共享的保存一般信
息)速度稍快
RSA:非对称加密(一组一堆,两个密钥,一个加密钥,解密钥。优点:保证安全性!)速
度稍慢
加密钥、解密钥 钥匙的功能划分
公钥 私钥 公开程度划分
加密钥公开,解密钥揣兜里。特点:保证内容只有我看的到,防止外传。就算传给别人了别
人没有解密钥也解不了密解密钥公开,加密钥揣兜里。特点:保证数据不能篡改,一定来自于我。就算你改了我数据那么,别人拿到解密钥就解不了密了。
AOP面向切面编程与OOP是互补的,更好的去面向对象:利用Attribute特性:可以在不破坏类型封装的前提下,为对象增加额外的信息,执行额外的操作。每个类只要考虑好自身的业务,其他的公共逻辑就放到特性中去处理,比如LoginFilter AOP利用装饰者模式静态的方式,给需要执行的类方法块前后都切入公共逻辑代码比如验证
、日志,异常。方法执行前、后。也可以使用.NET Remoting/RemlProry实现动态代理 代理模式 Proxy UnityAOP
EF查询的时候尽量用延迟查询。不要着急ToList();延迟查询返回的就是IQueryList接口,即时查询得到的是IEnumberList接口。
特别是注意要分页的一定要做‘延迟查询’,包括排序什么的,不要先Tolist()后再筛选Skip分页!
ToList()一定是要放到最后!!
如果是联表查询,你不去操作主表的外键属性,ef也不会去主动查外键的表内容。除非在查
询的时候调用dbContext.SD_SYSLOG.Include("SD_USER")就会一次性全部把针对sd_user的
外键内容model查出来
0.默认-延迟加载机制
1.主动加载:
在查询前 dbcontext.Configuration.LazyLoadingEnabled=false;//不延迟加载,不会再次
查询了,不ToList()还是会查询出来。包括多表查询的子表,关联字表属性都是为null的
2.显示加载:
在查询的时候调用dbContext.SD_SYSLOG.Include("SD_USER")就会一次性全部把针对
sd_user的外键内容model查出来
3.指定加载:
指定加载的某个实体。循环加载出来的集合后,调用dbcontet.Entry<SD_SYSLOG>
(t_sd_syslog).Collection(c=>c.SD_USER).Load();//集合显示加载
如果是一对一的话就是Reference(c=>c.SD_USER).Load()//单个属性用
多表查询:如果没有设置外键关系也可以用Linq语句 join方式来查,
如果要做多次请求的事务就用using(TransactionScope trans=new TransactionScope)
{trans.Complete();//最后需要提交事务}
需求:新增
CodeFirst:以代码为中心,如果代码里有的连接字符串、模型,数据库没有,那么就自动
创建数据库和表。
dbContext是什么?:
1.数据库的映射,包含全部的表
2.管理数据库连接,一个实例一个连接
3.SaveChange()是以事务形式来操作的。 本地缓存属性,查询数据后。是先放入本地数据
库,修改、删除本地属性,savechange的时候是一次性保存本地属性的全部变化。
比如在using方法体里的dbContext操作了数据后,在另一个using里全新的dbContext后是操
作不了以前操作的对象的,但是可以sdContext.SD_USER.Attach(t_sd_user)用Attach方法
把以前操作缓存过的对象附加到当前全新的dbContext上
如果在Attach附加之前把对象的属性值改了。之后再附加的话再用新的dbContext来
SaveChange保存是没用的。要想保存成功就得把对象设置为修改状态!
dbContext.Entry<SD_USERS>(u).State = EntityState.Modified;
------------------------------------------------------------------------
表名利用特性 [Table(“反射数据库表名”)]
属性利用[Column("新字段名")]
IOC:控制反转(原本上端直接指定使用的对象换成由第三方装配。)
IOC是目标,实现方式有两种:1.依赖查找,2.依赖注入
DI:依赖注入 是实现控制反转的一种手段! 都是利用特性,又分三种都是接口(1.属性注
入[Dependency],2.构造函数注入[InjectionConstructor],默认找参数最多的构造函数!
3.方法注入[InjectionMethond])
容器单例,线程单例(可用在定时调度里),
DIP:依赖倒置原则(上层模块不应该依赖于下层模块,二者应该通过抽象来依赖。比如UI
层不应该直接声明创建其他层的具体业务细节类对象)
多层架构,BLL层Service类应该按照业务逻辑对应,不应该跟表对应!!
var 不是类型,var声明的变量在赋值的那一刻,就已经决定了它是什么类型。
dynamic在运行的时候才会去确定具体的类型,可以简化反射调用方法什么的
MVC框架里的View文件夹里的Web.config里配置的是页面默认引用的命名空间!
Global.asax文件是//网站启动第一时间执行,而且只执行一次 /// 可以做单例 变量,比
如注册IOC
注册区域,过滤器,路由,组件,组件则是App_Start/BundleConfig.cs 配置映射,Script
名字和,具体有哪些js、css文件。在cshtml页面可直接使用@Styles.Render
("~/Content/css") 获取引用配置好的所有js、css文件。
mvc与ioc的整合:利用MVC的初始化,在Global.asax初始化文件设置控制器初始化工厂,重
写DefaultController创建控制器方法,利用Unity方式来创建控制器,通过读取配置文件自
动选择参数最多的构造函数依赖注入。想用哪个服务就写在控制器的构造函数赋值!!
return view的时候也会自动释放,所以也不用using
Request.QueryString["xx"];获取的是url地址上的参数,
Request.Form["xx"];,Request["xx"];,Request.Params["xx"]获取的是表单Form提交的
name参数。
App_Start文件夹下的FiterConfig类里添加的特性属于整个项目默认添加此特性,比如添加
异常处理特性、登录权限处理。
特性需要继承相应的抽象类
mvc 检测特性流程, 作用(可以在action前后写上时间监控性能再存日志。)
1.OnAuthorization //可检查用户登录
2.OnActionExecuting //执行阶段
3.Action //执行Action方法体,不算特性
4.OnActionExecuted//已执行 http缓存就在这里,缓存后客户端下次就不会调服务器了
5.OnResultExecuting//render前
6.Render //渲染体吧,不算特性 过程就是把执行好了的html信息写到Response里面去输出
7.OnresultExecuted//render后
OnException异常特性,
一般的过滤器执行顺序
IAuthorizationFilter->OnAuthorization(授权)
IActionFilter ->OnActionExecuting(行为)
Action
IActionFilter ->OnActionExecuted(行为)
IResultFilter ->OnResultExecuting(结果)
View
IResultFilter ->OnResultExecuted(结果)
*IExceptionFilter ->OnException(异常)
数据库设计、案例分析、读写分离
三大范式:
- 确保每一列原子性
读写分离:把80%读的业务放在一个数据库,20%的写的业务放在某一个数据库里。
查询压力就分散了。主数据库就只承载20%压力。
从数据库可以有多个,通过发布/订阅 。快照、日志的方式同步到从数据库,单会有点延迟,尤其是大数据量
分库分表:
1.垂直分库(按业务划分成不同的数据库,比如用户库、游戏前台库、后台库、金币库、物流、仓库。多台服务器承载。只有业务关联不强的时候才能拆分)
2.水平分库:(按数据分成不同的库,多台服务器承载:比如链家网按地区来,华南区、华东区、西南区。)
垂直分表:比如url、imgurl数据多、多个字段稳定,不作为查询条件的字段些分出新一张表,给一个外键关联
水平分表:数据多,根据业务特点拆分 订单表:按照
Type拆分
时间拆分(Histor/多个表,按月来,一个月一张表,如果要查统计总数据就只有定时统计,可以汇总一个表来统计,降低体验)
表分区(不常用效率不是很好):一个表设计的时候就制定规则,ID在1万以内存在某个硬盘物理位置,1万-2万存其他物理位置
Radis五大数据结构:
1:String也就是简单的键值对。
2:HashTable散列结构,(“key”,“变量”,”value”),如果要修改的话就用这种
3:Sets集合应该也跟键值对差不多,但有去重、,查询交集,并集,差集。对于一个KEY多个Value的,比如一个好友和多个好友,共同好友,推荐好友。
4:ZSet 有序集合(sorted sets)排序的Set,指定一个数字进去排序,比如统计排行榜之类的可以用。
5:List 就是队列!!先进先出,也可以进程通信,一个往里面写,一个往里面读。
Radis的异步队列:主程序接收输入任务(例:购买)把数据存入队列,在另外的多开线程或应用里循环检查队列是否有新数据然后作处理。
SOA微服务分布式服务,也可以用队列来做,
HTTP协议:
协议头,主机名,请求路径,组成URL
貓是页面里的下拉下滑章节连接