一、前方有坑 php在使用加减乘除等运算符计算浮点数的时候,经常会出现意想不到的结果,特别是关于财务数据方面的计算,给不少工程师惹了很多的麻烦。比如今天工作终于到的一个案例: $a = 2586; $b = 2585.98; var_dump($a-$b); 期望的结果是:float(0.02) 实际结果: float(0.019999999999982) 人生有坑,处处提防 二、防坑攻略: 1、通过乘100的方式转化为整数加减,然后在除以100转化回来…… 2、使用number_format转化成字符串,然后在使用(float)强转回来…… 3、php提供了高精度计算的函数库,实际上就是为了解决这个浮点数计算问题而生的。 主要函数有: bcadd — 将两个高精度数字相加 bccomp — 比较两个高精度数字,返回-1, 0, 1 bcdiv — 将两个高精度数字相除 bcmod — 求高精度数字余数 bcmul — 将两个高精度数字相乘 bcpow — 求高精度数字乘方 bcpowmod — 求高精度数字乘方求模,数论里非常常用 bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=” bcsqrt — 求高精度数字平方根 bcsub — 将两个高精度数字相减 前两种流氓的办法就不测试了,使用bcsub测试第三种两数相减的例子, 先看bcsub用法(来自官网) string bcsub ( string $left_operand , string $right_operand [, int $scale = int ] ) 参数 left_operand 字符串类型的左操作数. right_operand 字符串类型的右操作数. scale 此可选参数用于设置结果中小数点后的小数位数。也可通过使用 bcscale() 来设置全局默认的小数位数,用于所有函数。 返回值 返回减法之后结果为字符串类型. 测试代码: var_dump(bcsub($a,$b,2)); 结果 0.02 其他的函数请参考PHP官方网站 三、为啥有坑: php的bug?不是,这是所有语言基本上都会遇到的问题,所以基本上大部分语言都提供了精准计算的类库或函数库。 要搞明白这个原因, […]
View Details
1 2 3 4 5 6 7 8 9 10 |
吞吐率(Requests per second) 概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。 计算公式:总请求数 / 处理完成这些请求数所花费的时间,即 Request per second = Complete requests / Time taken for tests QPS(每秒查询数)、TPS(每秒事务数)是吞吐量的常用量化指标,另外还有HPS(每秒HTTP请求数)。 跟吞吐量有关的几个重要是:并发数、响应时间。 QPS(TPS),并发数、响应时间它们三者之间的关系是: QPS(TPS)= 并发数/平均响应时间 对于无并发的应用系统而言,吞吐量与响应时间成严格的反比关系,实际上此时吞吐量就是响应时间的倒数。前面已经说过,对于单用户的系统,响应时间(或者系统响应时间和应用延迟时间)可以很好地度量系统的性能,但对于并发系统,通常需要用吞吐量作为性能指标。 对于一个多用户的系统,如果只有一个用户使用时系统的平均响应时间是t,当有你n个用户使用时,每个用户看到的响应时间通常并不是n×t,而往往比n×t小很多(当然,在某些特殊情况下也可能比n×t大,甚至大很多)。 这是因为处理每个请求需要用到很多资源,由于每个请求的处理过程中有许多不走难以并发执行,这导致在具体的一个时间点,所占资源往往并不多。也就是说在处理单个请求时,在每个时间点都可能有许多资源被闲置,当处理多个请求时, 如果资源配置合理,每个用户看到的平均响应时间并不随用户数的增加而线性增加。实际上,不同系统的平均响应时间随用户数增加而增长的速度也不大相同,这也是采用吞吐量来度量并发系统的性能的主要原因。一般而言,吞吐量是一个比较通用的指标,两个具有不同用户数和用户使用模式的系统, 如果其最大吞吐量基本一致,则可以判断两个系统的处理能力基本一致。 |
1 2 |
并发连接数(The number of concurrent connections) 概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。 |
1 2 3 |
并发用户数(The number of concurrent users,Concurrency Level) 概念:要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。 并发用户数是指系统可以同时承载的正常使用系统功能的用户的数量。与吞吐量相比,并发用户数是一个更直观但也更笼统的性能指标。实际上,并发用户数是一个非常不准确的指标,因为用户不同的使用模式会导致不同用户在单位时间发出不同数量的请求。 一网站系统为例,假设用户只有注册后才能使用,但注册用户并不是每时每刻都在使用该网站,因此具体一个时刻只有部分注册用户同时在线,在线用户就在浏览网站时会花很多时间阅读网站上的信息,因而具体一个时刻只有部分在线用户同时向系统发出请求。 这样,对于网站系统我们会有三个关于用户数的统计数字:注册用户数、在线用户数和同时发请求用户数。由于注册用户可能长时间不登陆网站,使用注册用户数作为性能指标会造成很大的误差。而在线用户数和同事发请求用户数都可以作为性能指标。 相比而言,以在线用户作为性能指标更直观些,而以同时发请求用户数作为性能指标更准确些。 |
1 2 3 |
用户平均请求等待时间(Time per request) 计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即 Time per request = Time taken for tests /( Complete requests / Concurrency Level) |
1 2 3 4 5 |
服务器平均请求等待时间(Time per request: across all concurrent requests) 计算公式:处理完成所有请求数所花费的时间 / 总请求数,即 Time taken for / testsComplete requests 可以看到,它是吞吐率的倒数。 同时,它也=用户平均请求等待时间/并发用户数,即Time per request / Concurrency Level |
1 2 |
QPS每秒查询率(Query Per Second) 每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。对应fetches/sec,即每秒的响应请求数,也即是最大吞吐能力。 (看来是类似于TPS,只是应用于特定场景的吞吐量) |
1 2 3 |
响应时间(RT) 响应时间是指系统对请求作出响应的时间。直观上看,这个指标与人对软件性能的主观感受是非常一致的,因为它完整地记录了整个计算机系统处理请求的时间。由于一个系统通常会提供许多功能,而不同功能的处理逻辑也千差万别,因而不同功能的响应时间也不尽相同, 甚至同一功能在不同输入数据的情况下响应时间也不相同。所以,在讨论一个系统的响应时间时,人们通常是指该系统所有功能的平均时间或者所有功能的最大响应时间。当然,往往也需要对每个或每组功能讨论其平均响应时间和最大响应时间。 对于单机的没有并发操作的应用系统而言,人们普遍认为响应时间是一个合理且准确的性能指标。需要指出的是,响应时间的绝对值并不能直接反映软件的性能的高低,软件性能的高低实际上取决于用户对该响应时间的接受程度。对于一个游戏软件来说,响应时间小于100毫秒应该是不错的, 响应时间在1秒左右可能属于勉强可以接受,如果响应时间达到3秒就完全难以接受了。而对于编译系统来说,完整编译一个较大规模软件的源代码可能需要几十分钟甚至更长时间,但这些响应时间对于用户来说都是可以接受的。 |
安装ab测试工具
1 |
yum install httpd-tools -y |
ab工具帮助 ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
命令格式: ./ab [options] [http://]hostname[:port]/path 命令参数: -A:指定连接服务器的基本的认证凭据; -c:指定一次向服务器发出请求数; -C:添加cookie; -g:将测试结果输出为“gnuolot”文件; -h:显示帮助信息; -H:为请求追加一个额外的头; -i:使用“head”请求方式; -k:激活HTTP中的“keepAlive”特性; -n:指定测试会话使用的请求数; -p:指定包含数据的文件; -q:不显示进度百分比; -T:使用POST数据时,设置内容类型头; -v:设置详细模式等级; -w:以HTML表格方式打印结果; -x:以表格方式输出时,设置表格的属性; -X:使用指定的代理服务器发送请求; -y:以表格方式输出时,设置表格属性。 参数很多,一般我们用 -c表示并发数 -n 表示请求数即可 如果只用到一个Cookie,那么只需键入命令: ab -n 100 -C key=value http://test.com/ 如果需要多个Cookie,就直接设Header: ab -n 100 -H “Cookie: Key1=Value1; Key2=Value2” http://test.com/ |
使用举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
[root@c75 ~]# ab -n 1000 -c 1000 http://192.168.255.209/monitor This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.255.209 (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.14.0 Server Hostname: 192.168.255.209 Server Port: 80 Document Path: /monitor Document Length: 185 bytes Concurrency Level: 1000 //并发请求数 Time taken for tests: 2.252 seconds //整个测试持续的时间 Complete requests: 1000 //完成的请求数 Failed requests: 0 //失败的请求数 Write errors: 0 //写入失败数 Non-2xx responses: 1000 //非2xx状态请求数 Total transferred: 386000 bytes //传输的总字节数大小 HTML transferred: 185000 bytes //传输的总文档字节数大小 Requests per second: 444.05 [#/sec] (mean) //每秒处理的请求数 Time per request: 2252.008 [ms] (mean) //每个请求花费的平均时间 Time per request: 2.252 [ms] (mean, across all concurrent requests) Transfer rate: 167.39 [Kbytes/sec] received //转移率 Connection Times (ms) min mean[+/-sd] median max Connect: 6 40 14.2 36 69 //创建TCP连接到服务器或者代理服务器所花费的时间 Processing: 40 738 722.9 302 2138 //写入缓冲区消耗+链路消耗+服务端消耗 Waiting: 11 546 595.8 293 1930 //写入缓冲区消耗+链路消耗+服务端消耗+读取数据消耗 Total: 45 778 733.0 344 2207 //总花费时间 Percentage of the requests served within a certain time (ms) 50% 344 66% 752 75% 1668 80% 1799 90% 1957 95% 2073 98% 2161 99% 2191 100% 2207 (longest request) |
from:https://www.e-learn.cn/content/linux/1134148
View Details写在前面 在学习ab工具之前,我们需了解几个关于压力测试的概念 吞吐率(Requests per second) 概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。 计算公式:总请求数 / 处理完成这些请求数所花费的时间,即 Request per second = Complete requests / Time taken for tests 并发连接数(The number of concurrent connections) 概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。 并发用户数(The number of concurrent users,Concurrency Level) 概念:要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。 用户平均请求等待时间(Time per request) 计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即 Time per request = Time taken for tests /( Complete requests / Concurrency Level) 服务器平均请求等待时间(Time per request: across all concurrent requests) 计算公式:处理完成所有请求数所花费的时间 / 总请求数,即 Time taken for / testsComplete requests 可以看到,它是吞吐率的倒数。 同时,它也=用户平均请求等待时间/并发用户数,即 Time per request / Concurrency Level ab工具简介 ab全称为:apache bench 在官网上的解释如下: ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。 其他网站解释: ab是apache自带的压力测试工具。ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试。比如nginx、tomcat、IIS等。 下载ab工具 进入apache官网 http://httpd.apache.org/ 下载apache即可 启动ab工具 […]
View DetailsHitFilm 3 Express 适用平台:Windows/Mac OS HitFilm 3 Express可以说是目前市面上最好的免费视频剪辑软件,除了基础的视频剪辑功能外,你还可以用它来制作动画、2D或者3D建模、或者添加特效。该软件免费版本包含完整的视频剪辑功能、内建100个特效、动态跟踪等功能,当然你也可以通过内购下载额外的过场动画和特效。 DaVinci Resolve 12 适用平台:Windows/Mac OS DaVinci Resolve 12.5是一个将专业的视频剪辑功能和调色系统集于一身的软件,它支持不限分辨率的窗口缩放,可在现场、狭小工作室使用。和HitFilm 3 Express相比DaVinci在视频剪辑和动画制作方面并不出色,假如你更倾向调色后期那么DaVinci肯定是你的不二选择。 视频转换器 适用平台:Windows 视频转换器的主要功能是转换音视频的格式,以及合并分割软件,它采用高效的超线程转换技术,兼容多种主流移动设备格式;极大地提高了视频格式转换的效率,大多数视频转换器都束手无策的qlv、qsv格式视频它也可以轻松转换格式。 视频合并分割软件 视频合并分割软件也是一款支持视频合并分割的软件,与上面的视频转换器不同的是,它可以为视频添加转场效果,软件包含多种转场效果,可以满足大家制作炫酷的视频哦! Movie Maker 适用平台:Windows Movie Maker Live是windows附带的一个影视剪辑小软件,它功能比较简单,可以组合镜头,声音,加入镜头切换的特效,只要将镜头片段拖入就行,很简单,适合家用摄像后的一些小规模的处理,操作简单非常适合视频剪辑小白使用。 iMoive 适用平台:Mac OS iMovie是一款由苹果电脑编写的视频剪辑软件,之后于WWDC 2010推出了iOS版本。iMovie’11是目前最新的版本,新增功能有影片预告、全新音频编辑、一步特效、人物查找器、运动与新闻主题、全球首映等等,imovie免费且容易上手,不过你得花钱买一台昂贵的Mac。 Lightworks 适用平台:Windows, Mac OS, Linux 在HitFilm 3 Express上市之前Lightworks一直都是视频剪辑爱好者的第一选择,它在2011年的时候成为了一款开源软件并提供免费下载,唯一的缺点就是免费版最高只能导出720P的视频。 ivsEdits LE 适用平台:Windows LE是ivsEdits的免费版本,它支持处理4K级别的视频并且可以以无损的格式(AVI、MOV)导出,尽管免费版会有种种限制你仍然可以通过第三方插件完成你所需的操作。 Shotcut 适用平台:Windows, Mac, Linux 及其简洁、易上手的视频剪辑软件,开源、免费。适合初学者或者是不喜欢特别复杂操作的用户使用。 Avid Free DV 适用平台:Windows Avid Free DV是专业视频剪辑软件Avid video editor的免费版本,然而在AVE收购了Pinnacle后他们停止了对这款软件的维护,不过你仍然可以在百度上找到免费下载的版本。不过Avid Free DV不适合业余视频剪辑爱好者。
View Details借鉴博客:https://www.cnblogs.com/xkops/p/6169034.html 此博客里面有每个k8s配置文件的注释:https://blog.csdn.net/qq_35904833/article/details/78190257 啊西吧,啊西吧,根据上面的博客终于安装成功了。妈的,网上大部分博客安装k8s配置写得乱七八槽的,终于找到一篇条理清晰,安装详细的k8s安装博客啦,哈哈哈哈,不容易啊快三个星期了,从狗屁不懂搞这玩意。 下面写一写我自己的安装流程: 一、安装准备: 准备两台服务器(我用的是CentOS7系统):192.168.26.227,192.168.26.228 一主一从: master机:192.168.26.227 node机:192.168.26.228 简单说一下k8s: k8s是个什么玩意? 可以这样去理解:k8s全称:Kubernetes,它可以看作是一个分布式系统支撑平台。 我们为什么要用k8s集群? 故障自愈: k8s这个玩意可以监控容器运行,我们把项目放到容器里。由于一些外部内部原因服务器承受不住压力,如果主节点上的容器突然挂了,k8s立刻会自己将主机上的服务调度到另一个node机器上运行 应用更新: 更新项目上线时不用中断当前项目的运行。 还有一些自动扩容,缩容的概念就不讲了,我本人也没亲身体会用过,不好说。 k8s的全生命周期管理: 在k8s进行管理应用的时候,基本步骤是:创建集群,部署应用,发布应用,扩展应用,更新应用。 k8s的主要组件,以及它们主要是用来干什么的: etcd:一款开源软件。提供可靠的分布式数据存储服务,用于持久化存储K8s集群的配置和状态 apiservice:用户程序(如kubectl)、K8s其它组件之间通信的接口。K8s其它组件之间不直接通信,而是通过API server通信的。这一点在上图的连接中可以体现,例如,只有API server连接了etcd,即其它组件更新K8s集群的状态时,只能通过API server读写etcd中的数据。 Scheduler:排程组件,为用户应用的每一可部署组件分配工作结点。 controller-manager:执行集群级别的功能,如复制组件、追踪工作结点状态、处理结点失败等。Controller Manager组件是由多个控制器组成的,其中很多控制器是按K8s的资源类型划分的,如Replication Manager(管理ReplicationController 资源),ReplicaSet Controller,PersistentVolume controller。 kube-proxy:在应用组件间负载均衡网络流量。 kubelet:管理工作结点上的容器。 Contriner runtime Docker, rkt等实际运行容器的组件 上面都是些k8s集群所要用到的组件,具体这些组件都是用来干嘛的呢,我们来好好分析分析。 master主机上192.168.26.277必须要有的组件: etcd :提供分布式数据存储的数据库吧,用于持久化存储k8s集群的配置和状态 kube-apiserver:api service提供了http rest接口,是整个集群的入口,K8s其它组件之间不直接通信,而是通过API server通信的。(只有API server连接了etcd,即其它组件更新K8s集群的状态时,只能通过API server读写etcd中的数据) kube-scheduler:scheduler负责资源的调度 kube-controller-manager:整个集群的管理控制中心,此组件里面是由多个控制器组成的,如:Replication Manager(管理ReplicationController 资源),ReplicaSet Controller,PersistentVolume controller。主要作用用来复制组件、追踪工作结点状态、处理失败结点 node节点机上192.168.26.228必须要有的组件: flannel:好像是用来支持网络通信的吧 kube-proxy:用来负载均衡网络流量 kubelet:用来管理node节点机上的容器 docker:运行项目镜像容器的组件 2018年11月30日: 今天又看了一些博客,多了一些认识和理解,如下: k8s的整个集群运行原理:【重点核心知识很重要】 master主机上的kube-controller-manager是整个集群的控制管理中心,kube-controler-manager中的node controller模块 通过apiservice提供的监听接口,实时监控node机的状态信息。 当某个node机器宕机,controller-manager就会及时排除故障并自动修复。 node节点机上的kubelet进程每隔一段时间周期就会调用一次apiservice接口报告自身状态,apiservice接口接受到这些信息后将节点状态更新到ectd中。kubelet也通过apiservice的监听接口监听pod信息,如果监控到新的pod副本被调度绑定到本节点,则执行pod对应的容器的创建和启动,如果监听到pod对象被删除,则删除本节点对应的pod容器。(目前对pod、容器、镜像这些概念还不是很清晰,无法在大脑中构建这都是些什么玩意,先做个笔记记着吧) […]
View Details1 准备 下载 tomcat 首先在 tomcat 官网上下载 windows 版本的 tomcat 包。因为只有 windows 版本中才有用于安装或卸载 Tomcat 服务的 service.bat。 解压为文件夹,假设 tomcat 的解压路径为 ${TOMCAT_HOME} 通过命令行,进入 ${TOMCAT_HOME}/bin 2 安装 Tomcat 服务 输入命令:
1 |
service.bat install 服务名 |
这里我们可以把启动类型改为 “自动”,这样如果服务器重启,就会自动启动服务啦。 快速进入 “服务” 列表的方法:win+R 打开运行窗口,然后输入 services.msc 建议把服务的名称加上端口号,这样方便管理哦O(∩_∩)O~ 如果启动服务时报错,查看 tomcat 日志发现是 “不是有效的 Win32 应用程序” 引起的。这可能是操作系统的问题(比如 windows server 2007),这时只需下载一个 32 位的 windows 版的 tomcat 包即可解决。 3 卸载 Tomcat 服务 输入命令:
1 |
service.bat remove 服务名 |
是不是很简单呀O(∩_∩)O哈哈~ from:https://blog.csdn.net/deniro_li/article/details/79093390
View DetailsOctober CMS 的后台管理很简单,没有多余的功能。
首页部分是【仪表盘】显示了系统的基本信息。
内容管理系统:这里可以设置页面、部件、布局、内容块、资源和组件。
媒体:是用于管理系统中的各种媒体资源,包括图片、音频、视频、文档等。默认是存储在服务器本地的。我们可以上传这些内容到服务器,也可以建立更多的目录对这些资源进行分别存储。
设置:默认情况下设置里面没有太多的设置,默认包含邮件、日志以及系统和内容功能。我们可以在系统中进行管理员的管理,用于控制用户具有的权限。后面,我们将学习插件是如何工作的。
按照laravel开发环境的要求安装环境,必不可少的是composer了。
在命令行执行
composer create-project october/october octobermovie
上述命令完成后,进入对应的目录,这里执行
cd octobermovie
php artisan october:install
首先是对应的版本
1 2 3 4 5 6 |
Laravel <span class="hljs-number">5.1</span> composer <span class="hljs-built_in">require</span> encore/laravel-admin <span class="hljs-string">"1.1.*"</span> Laravel <span class="hljs-number">5.2</span> composer <span class="hljs-built_in">require</span> encore/laravel-admin <span class="hljs-string">"1.2.*"</span> Laravel <span class="hljs-number">5.3</span> composer <span class="hljs-built_in">require</span> encore/laravel-admin <span class="hljs-string">"1.3.*"</span> Laravel <span class="hljs-number">5.4</span> composer <span class="hljs-built_in">require</span> encore/laravel-admin <span class="hljs-string">"1.4.x-dev"</span> Laravel <span class="hljs-number">5.5</span> composer <span class="hljs-built_in">require</span> encore/laravel-admin <span class="hljs-string">"1.5.x-dev"</span> |
我们选用Laravel 5.5 首先安装laravel 5.5
1 2 |
composer create-project --prefer-dist laravel/laravel=<span class="hljs-string">'5.5.*'</span> laravel-admin |
2.然后进去laravel-admin文件中
1 2 |
<span class="hljs-built_in">cd</span> larabel-admin |
修改.env的数据库连接设置,然后进去config/database,修改mysql的’strict' => true,改为false(mysql5.7的需要改,5.7以下的不需要改) 运行这些命令来发布资产和配置
1 2 |
php artisan vendor:publish --provider=<span class="hljs-string">"Encore\Admin\AdminServiceProvider"</span> |
最后运行以下命令来完成安装
1 2 |
<span class="hljs-selector-tag">php</span> <span class="hljs-selector-tag">artisan</span> <span class="hljs-selector-tag">admin</span><span class="hljs-selector-pseudo">:install</span> |
配置laravel的nginx重写规则,在nginx配置下加入try_files $uri $uri/ /index.php?$query_string;
1 2 3 4 5 6 7 |
location / { root <span class="hljs-string">'/www/laravel-admin/public'</span>; <span class="hljs-comment"># 网站默认首页</span> index index.php index.html index.htm; try_files <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php?<span class="hljs-variable">$query_string</span>; } |
7.打开浏览器输入http://localhost/admin/,使用用户名admin和密码admin登录 作者:Feng_Yikai 链接:https://www.jianshu.com/p/1110a2cad516 来源:简书
View Details