在本文中,我们将为您详细介绍手握OPPOR11请服用双摄正确使用姿势的相关知识,此外,我们还会提供一些关于BigPipe的正确使用姿势、Dapper的正确使用姿势、Flexbox布局的正确使用姿势、F
在本文中,我们将为您详细介绍手握OPPO R11 请服用双摄正确使用姿势的相关知识,此外,我们还会提供一些关于BigPipe的正确使用姿势、Dapper的正确使用姿势、Flexbox 布局的正确使用姿势、Flexbox布局的正确使用姿势的有用信息。
本文目录一览:手握OPPO R11 请服用双摄正确使用姿势
OPPO R11算是最近发布的(和即将发布的)一系列国产机型中热度最高的一款了,自从6月16日这款手机开售之后,线上和线下的销售成绩都无比惹眼。
手机能卖这么好,明星代言效应是一方面;而OPPO抓稳核心用户群体的痛点则是另一方面。“绿厂”一直以来主打拍照手机,此前的R9s就在3000元以下价位拥有几乎最强的成像素质。这次的R11终于是用上了双摄,OPPO也专门为R11的双摄设计了一系列实用性很强的用法。
从硬件上的逻辑来说,目前市面上的双摄手机一般有景深双摄、黑白+彩色双摄和广角+长焦双摄这三种常用逻辑。OPPO R11的逻辑属于第三种,理论上这种双摄只能允许用户在两颗摄像头之间切换,为不同场景的成像提升相机的可用度——换句话说,这和单反相机换两颗焦距不同的定焦头没什么区别。
但在硬件逻辑之上,OPPO为R11的相机功能性下了不小的功夫,使得这两颗本不能协同成像的摄像头获得同时工作的能力。大家也许还记得R11发布前,OPPO为“与高通合作适配旗舰级ISP”一事造势,而上下游两家大厂商在软硬件方面的互通有无,带来的就是R11拍照上强大的软件支持。
那现在问题来了,从硬件本身的支持到软件上的玩法拓展,OPPO R11的双摄究竟能玩出什么来呢?别着急,我们从大家最常用(估计也是最关心)的人像模式看起。
说句实话,拍人看多了真的太俗套,OPPO R11拍人什么样子,我们之前的评测文章里早就有数了。今天我们就拿它来拍景,不同物体的复杂边缘在某些程度上对手机的软件算法要求其实比拍人更高。OPPO R11的人像模式入口级别非常高,进入相机直接左滑就开启了。
但要注意,只有屏幕下方的“景深效果”变黄了才能拍出浅景深成像,而在手机判定取景器内画面不适合做浅景深或做不出完美的浅景深时,这行字干脆就灰掉了,你拍也拍不出来。讲真,这比某些厂商拍不好还胡乱虚化的做派真的良心太多……
不吹牛逼的话,OPPO R11用广角+长焦双摄“强行充当”景深双摄,拍出来的照片有多接近单反呢?请看样张:
拍之前本来并不抱太大希望,但这组样张着实体现出OPPO R11惊人的表现。如果说初代的景深双摄通过识别物体边缘来判定是否做虚化,那么以OPPO R11为首的一系列产品就是实打实去识别焦平面——直接无视了不同物体复杂边缘对于虚化判定的误导性。这对硬件规格和软件算法的要求都非常高,但OPPO R11能够以很快的速度成片并获得近乎完美的观感,可以说已经相当过硬了。
至于说“用OPPO R11拍照时,开与不开人像模式究竟有多大差别”这个问题,我们不妨看一组十分直观的对比(时隔半年之后,小编的战车再次友情出镜):
开启人像模式
未开启人像模式
哦对,忘了说一句,OPPO R11的人像模式不仅会通过背景虚化来突出画面主体,还会用提高亮度的方法来把画面变得更加干净,可以说从虚化与亮度两方面全面模仿了单反的镜头大光圈效果。
一组对比没看爽?没关系,咱们再看一组:
开启人像模式
未开启人像模式
面对这样简单粗暴的对比,做什么样张分析都显得多余了。昨天有人在微博上询问小编我“要去OPPO做销售了,问下R11这款产品有什么特色卖点吗”,我倒觉得,好的产品不需要背那么多的营销话术,有一系列这样直观的对比和展示足矣。
刚才讲的人像模式其实是OPPO R11通过软件层面实现的功能,而广角+长焦双摄最基础的玩法就是切换摄像头,这点大家千万不要忘记。打开相机后直接点按快门左边的倍数按钮,你就可以随时实现2X变焦。
广角样张
长焦样张
OPPO R11的广角摄像头拥有1600万像素,长焦摄像头则拥有2000万像素;但为了实现准确无误的2X“光学”变焦,OPPO会选取长焦摄像头中间的1600万像素并裁切边缘,实际成像自然和普通状态下一样是1600万像素的。有趣的细节是,OPPO R11的长焦摄像头在拍摄时会有白平衡轻微偏暖的现象出现;毕竟传感器型号规格完全不同,要做到色彩和宽容度表现都完全一致,很显然是难度极高的。
那么又一个问题来了,如果我不希望OPPO R11自动给我裁切一个标准的2X变焦,就任性想看2000万像素摄像头的原始成像,该怎么办呢?办法肯定是有的,就是需要多一步操作。打开相机通过快门旁边的选项卡找到专业模式,然后点按屏幕左上角的双摄标志,把左侧的镜头设置为黄色高亮显示(即上图中的状态),你就可以获得2000万像素的照片了。
2000万像素样张
不得不说,白天光照充足情况下,一颗注重极限解析力的2000万像素摄像头可以解决很多问题,比如上面样张中的细节还原表现,就是市面上绝大多数手机望尘莫及的。
——是的,这就是强大的OPPO R11,不管你喜欢与否,它都悄然成为了3000元价位的又一款拍照神器。成功继承了R9s的衣钵还加上了双摄,只要你掌握了上述的几点玩法,这样的OPPO R11绝不会让你失望。
BigPipe的正确使用姿势
BigPipe目标:前后端分离,提高页面渲染速度
BigPipe解决的问题:
1、下载堵塞
2、服务端下载浪费
一般的网页加载是直接通过访问服务器,发送请求,收到返回数据,然后渲染
一般堵塞模型:
后端渲染页面→网络延迟→浏览器端页面渲染,所有的数据一次性渲染
BigPipe思路,分块加载,一次请求,多次返回
1、浏览器发送一次请求;
2、服务端收到请求后,开始处理请求;
3、服务器端按预先写好的控制流程,开始分块渲染HTML;
4、如果渲染完了向浏览器端发送数据;
5、浏览器端收到分块数据后开始渲染
BigPipe堵塞模型(类似于CPU分级流水)
pagelet 1 | 服务器端计算 网络传输 浏览器渲染
|
pagelet 2 | 服务器端计算 网络传输 浏览器渲染
|
pagelet 3 | 服务器端计算 网络传输 浏览器渲染
_____________|________________________________________________________________
分级传输极大提高了首页渲染效率
二、BigPipe VS Ajax
BigPipe: 1、发送一个请求后多次返回数据
2、浏览器和服务器工作并行执行
3、只有一个请求,对服务器压力少
AJAX: 1、发送一个请求后只返回一次数据
2、浏览器和服务器工作顺序执行
3、有多个请求,对服务器压力大
Dapper的正确使用姿势
原文: Dapper的正确使用姿势本文demo适用于MySQL
Dapper优势和缺点
优点
高性能、易排查、易运维、灵活可控
缺点
和EF相比,手写sql当修改表结构不易发现bug。
习惯了EF后再来使用Dapper,会很难适应那种没有了强类型的安全感。不过可以用单元测和心细来避免。
数据库连接
问题:IDbConnection需不需要手动Open打开连接
答案:有时候需要有时候不需要
Dapper连接可分两种:主动管理(自己管理连接的打开和关闭)和自动管理(自动管理连接的打开和关闭)
//短短三行代码即实现了dapper连接的主动管理和自动管理
bool wasClosed = cnn.State == ConnectionState.Closed;//判断连接是否为关闭状态
...
if (wasClosed) cnn.Open();
...
if (wasClosed) cnn.Close();
源码位置 https://github.com/StackExchange/Dapper/blob/master/Dapper/SqlMapper.cs#L530
Note:ADO.NET默认是启用连接池的 Pooling = true,连接池中最大连接数,默认为100
在使用Dapper的过程中,你有可能遇到过连接池超过最大限制。那问题是怎么来的呢?
如果主动管理或者自动管理连接都不会有问题。就怕你管理一半,打开不关闭:
//循环执行两百次左右就可以重现连接池超过最大限制
DBContext dBContext2 = new DBContext();
dBContext2.DbConnection.Open();
解决办法相信不用我说了。
Note:在使用事务的时候需要手动打开连接,请不要忘记在finally里面Close。
增删改查的优化
批量新增
//1、可通过匿名对象集合进行参数化数据新增。(性能优化参考3)
DbConnection.Execute(sqlStr, ListEntity);
//2、【sql拼接可大大优化执行效率】在values后面带上多有要插入的值。(如果数据太大可分批插入,如1000条一提交)
insert into tt (a,b,c,d) values (50,1,''1'',''1''), (51,2,''1'',''2'');
//3、参数化防sql注入
var sql = insert into tt (a,b,c,d) values (@a1,@b1,@c1,@d1), (@a2,@b2,@c2,@d2);
DynamicParameters dynamicParameters = new DynamicParameters();
dynamicParameters.Add("a1","value");
dynamicParameters.Add("b1","value");
dynamicParameters.Add("c1","value");
dynamicParameters.Add("a2","value");
dynamicParameters.Add("b2","value");
dynamicParameters.Add("c2","value");
dynamicParameters.Add("d2","value");
DbConnection.ExecuteScalar<int>(sql, dynamicParameters)
批量修改
//1、可通过匿名对象集合进行参数化数据修改。(需要修改的值都不一样的情况下,性能优化参考4)
DbConnection.Execute(sqlStr, ListEntity);
//2、如果需要修改的值都是一样,只是条件不一样。(使用SQL语句中的IN语法)
DbConnection.Execute("UPDATE tt SET aa = @aa where bb in @bb;", new { aa, bb });
//3、快速批量修改(此方法非常适合`新增或修改`数据的场景,可通过建联合唯一索引来实现新增或修改的区分。【组合字段不能为空,否则为空 不做唯一,有重复空数据】)
insert into test_tbl (id,dr) values (1,''2''),(2,''3''),...(x,''y'') on duplicate key update dr=values(dr);
//4、参数化防sql注入
var sql = insert into test_tbl (id,dr) values (@id1,@dr1),(@id2,@dr2),...(@idn,@drn) on duplicate key update dr=values(dr);
DynamicParameters dynamicParameters = new DynamicParameters();
dynamicParameters.Add("id1","value");
dynamicParameters.Add("dr1","value");
dynamicParameters.Add("id2","value");
dynamicParameters.Add("dr2","value");
...
dynamicParameters.Add("idn","value");
dynamicParameters.Add("drn","value");
DbConnection.ExecuteScalar<int>(sql, dynamicParameters)
批量删除
同理,也可以使用参数化和IN语法
查询第一条数据
dBContext.DbConnection.QueryFirstOrDefault<ItemFCLPO>("SELECT * from itemfcl_temp limit 1;"); //正确
dBContext.DbConnection.QueryFirstOrDefault<ItemFCLPO>("SELECT * from itemfcl_temp;"); //错误
dBContext.DbConnection.Query<ItemFCLPO>("SELECT * from itemfcl_temp;").FirstOrDefault(); //错误
dBContext.DbConnection.Query<ItemFCLPO>("SELECT * from itemfcl_temp;").ToList().FirstOrDefault();//错误
If扩展方法
使用过Mybatis的同学都知道,在xml里面写if、else还是蛮好用的。虽然我还是不喜欢在xml里面写sql。
那么在Dapper里面是不是也能简便操作,答案是肯定的。这就得庆幸C#牛逼的语法了。
public static class StringExtension
{
public static string If(this string str, bool condition)
{
return condition ? str : string.Empty;
}
}
然后我们的sql就可以这样拼接了
left join MaintenanceTemplates it on it.Id = m.MaintenanceTemplateId
where m.IsDeleted = 0
{" and m.Code = @KeyWord ".If(!string.IsNullOrWhiteSpace(input.KeyWord))}
{" and m.ProjectId = @ProjectId ".If(input.ProjectId.HasValue)}
{" and a.ProductId = @ProductId ".If(input.ProductId.HasValue)}
比起以前又臭又长的if判断,个人感觉好多了。
Note:Dapper不会因为传多了参数而报错,所以放心使用If。
工作单元
使用EF的时候很方便做事务处理,而在Dapper中貌似就没那么优雅了。
我们每次在事务逻辑开始前都需要BeginTransaction
开启,事务结束后都需要CommitTransaction
提交。代码看起来也就稍显混乱。
如果我们通过特性标记的方式,在标记了UnitOfWork
特性的方法自动开启和提交事务那就完美了。如下:
[UnitOfWork]
public virtual void Test()
{
//执行业务逻辑
}
当然,这是可行的。通过AOP拦截,在方法执行前开启事务,在方法执行后提交事务就可以了。
实现如下:
需要Nuget包Autofac.Extensions.DependencyInjection
Autofac.Extras.DynamicProxy
[UnitOfWork]
public virtual void DelUser()
{
var sql = "select * from UserTemp";
var userList = dBContext.DbConnection.Query<object>(sql);
var sql2 = $@"INSERT into UserTemp VALUES(0,''{DateTime.Now.ToString()}'',''sql2执行成功'')";
dBContext.DbConnection.Execute(sql2);
throw new Exception("主动报错");//验证事务 是否有效
var sq3 = $@"INSERT into UserTemp VALUES(0,''{DateTime.Now.ToString()}'',''sq3执行成功'')";
dBContext.DbConnection.Execute(sq3);
}
public class UnitOfWorkIInterceptor : IInterceptor
{
private DBContext dBContext;
public UnitOfWorkIInterceptor(DBContext dBContext)
{
this.dBContext = dBContext;
}
public void Intercept(IInvocation invocation)
{
MethodInfo methodInfo = invocation.MethodInvocationTarget;
if (methodInfo == null)
methodInfo = invocation.Method;
UnitOfWorkAttribute transaction = methodInfo.GetCustomAttributes<UnitOfWorkAttribute>(true).FirstOrDefault();
//如果标记了 [UnitOfWork],并且不在事务嵌套中。
if (transaction != null && dBContext.Committed)
{
//开启事务
dBContext.BeginTransaction();
try
{
//事务包裹 查询语句
//https://github.com/mysql-net/MySqlConnector/issues/405
invocation.Proceed();
//提交事务
dBContext.CommitTransaction();
}
catch (Exception ex)
{
//回滚
dBContext.RollBackTransaction();
throw;
}
}
else
{
//如果没有标记[UnitOfWork],直接执行方法
invocation.Proceed();
}
}
}
完整的测试源码,会在文末提供。
SQL监控
使用EF的同学应该很多人都知道MiniProfiler
,我在前些年分享EF的时候有做过简单介绍。
那么我们在执行Dapper的时候是不是也可以对生成的sql做检测和性能监控。
答案是肯定的。Git地址
MiniProfiler监控套件还真不是一般的强。EF、MongoDB、MySql、Redis、SqlServer统统支持。
接下来我们实现对Dapper监控,导入Nuget包MiniProfiler.AspNetCore
public class ActionFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var profiler = MiniProfiler.StartNew("StartNew");
using (profiler.Step("Level1"))
{
//执行Action
await next();
}
WriteLog(profiler);
}
/// <summary>
/// sql跟踪
/// 下载:MiniProfiler.AspNetCore
/// </summary>
/// <param name="profiler"></param>
private void WriteLog(MiniProfiler profiler)
{
if (profiler?.Root != null)
{
var root = profiler.Root;
if (root.HasChildren)
{
root.Children.ForEach(chil =>
{
if (chil.CustomTimings?.Count > 0)
{
foreach (var customTiming in chil.CustomTimings)
{
var all_sql = new List<string>();
var err_sql = new List<string>();
var all_log = new List<string>();
int i = 1;
customTiming.Value?.ForEach(value =>
{
if (value.ExecuteType != "OpenAsync")
all_sql.Add(value.CommandString);
if (value.Errored)
err_sql.Add(value.CommandString);
var log = $@"【{customTiming.Key}{i++}】{value.CommandString} Execute time :{value.DurationMilliseconds} ms,Start offset :{value.StartMilliseconds} ms,Errored :{value.Errored}";
all_log.Add(log);
});
//TODO 日志记录
//if (err_sql.Any())
// Logger.Error(new Exception("sql异常"), "异常sql:\r\n" + string.Join("\r\n", err_sql), sql: string.Join("\r\n\r\n", err_sql));
//Logger.Debug(string.Join("\r\n", all_log), sql: string.Join("\r\n\r\n", all_sql));
}
}
});
}
}
}
}
运行效果:
Demo源码
完整的Demo源码:https://github.com/zhaopeiym/BlogDemoCode/tree/master/Dapper_Demo/DapperDemo
结束
最后给大家推荐一个开源项目quartzui:https://github.com/zhaopeiym/quartzui
基于Quartz.NET 3.0的web管理界面,开箱即用。也可以完美运行在树莓派上。
docker run -v /fileData/quartzuifile:/app/File --restart=unless-stopped --privileged=true --name quartzui -dp 5088:80 bennyzhao/quartzui:RaspberryPi
运行在普通PC或云主机上
docker run -v /fileData/quartzuifile:/app/File --restart=unless-stopped --privileged=true --name quartzui -dp 5088:80 bennyzhao/quartzui
新建QQ群工控物联:995475200
Flexbox 布局的正确使用姿势
总结
以上是小编为你收集整理的Flexbox 布局的正确使用姿势全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
Flexbox布局的正确使用姿势
总结
以上是小编为你收集整理的Flexbox布局的正确使用姿势全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
今天关于手握OPPO R11 请服用双摄正确使用姿势的讲解已经结束,谢谢您的阅读,如果想了解更多关于BigPipe的正确使用姿势、Dapper的正确使用姿势、Flexbox 布局的正确使用姿势、Flexbox布局的正确使用姿势的相关知识,请在本站搜索。
本文标签: