Toast特点 没有焦点(即不干扰用户其他操作),显示时间较短,会自动消失
Toast使用场景 Toast一般使用在用户信息合法性校验、关闭应用时的提示等场合。
同对话框一样,Toast一般在事件监听器中使用(即当特定事件触发时,显示Toast消息)。
Toast使用基本流程 创建Toast(三个参数分别为上下文环境、提示文本、显示时间)设置Toast基本属性显示Toast //创建Toast Toast toastTip = Toast.makeText(MainActivity.this, "文本", Toast.LENGTH_LONG); //设置Toast属性(这里设置显示位置) toastTip.setGravity(Gravity.CENTER, 0, 0); //显示Toast toastTip.show(); 点击按钮,显示Toast提示框,效果如图:
当然写成一行也可以哦(不要忘记show)
Toast.makeText(MainActivity.this, "文本",Toast.LENGTH_LONG).show();
参考资料
EDG赢了!含泪将复旦教授讲的Python,整整630集,现在免费交公粮,分享给大家!_哔哩哔哩_bilibili
正文
Welcome to Python.org
python是解释型,面向对象的语言。大蟒蛇。
在写VC++及标准C程序时,我们常用sprint函数来将数值转换为字符串。可在Keil C中使用这个函数时就要注意了。请看下面例程:
/*main.c Designed by Bill Liu Version 0.0 Modified last by Bill Liu on 12/19/2021 */ #include "main.h" ui8 tem; ui16 tem1; float tem2; void main() { STCIO_InitPortsBits(P0|P1|P2|P3|P4, 0xFF, BI_IO); P3 = 0xFF; P0 = 0xFF; UartS1_Init(VBAUD_8BITS,G1,T2,9600); STCIO_InitP3Bit(SCT_BIT1, PP_OUT); SundBuzzerx10ms(50); Delay10xms(50, FSCLK); SundBuzzerx10ms(50); tem = 123; tem1 = 123; tem2 = 123; while(1) { memset(mstr,0,strlen(mstr)); sprintf(mstr,"%d\r\n", tem); UartS1_SendString(mstr); memset(mstr,0,strlen(mstr)); sprintf(mstr,"%d\r\n", tem1); UartS1_SendString(mstr); memset(mstr,0,strlen(mstr)); sprintf(mstr,"%d\r\n", tem2); UartS1_SendString(mstr); Delay10xms(200, FSCLK); } } //End of main() //********************************************* void SundBuzzerx10ms(ui8 x) { BUZZER = 0; Delay10xms(x, FSCLK); BUZZER = 1; } //End of SundBuzzerx10ms(ui8 x) 看下在串口助手上的输出结果:
过滤器filter是数组对象的一个方法,该方法不会改变原数组。该数组有两个参数第一个是函数并且数组中每个元素都会执行这个函数,这个函数共有三个参数第一个为必填当前元素的值,第二个为可选,当前元素的索引值。第三个可选,当前元素属于的数组对象。第二个是回调函数对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"。
下面通过代码实践一下filter的一些作用。‘
<script> let arr=[1,2,3,4,5,6,7,8]; arr.filter(function(value,index,arr){ console.log("当前值"+value) console.log("当前值"+index) console.log("当前所属对象"+arr) }) </script> 上面的代码分别打印的是:
当前值1
当前值0
当前所属对象1,2,3,4,5,6,7,8
当前值2
当前值1
当前所属对象1,2,3,4,5,6,7,8
当前值3
当前值2
当前所属对象1,2,3,4,5,6,7,8
当前值4
当前值3
当前所属对象1,2,3,4,5,6,7,8
当前值5
当前值4
当前所属对象1,2,3,4,5,6,7,8
当前值6
当前值5
当前所属对象1,2,3,4,5,6,7,8
当前值7
当前值6
当前所属对象1,2,3,4,5,6,7,8
当前值8
当前值7
当前所属对象1,2,3,4,5,6,7,8
上面分别打印的是值于索引和该索引数组的所有值
我们可以对其修改一下值看一下是否会改变原数组:
let arr=[1,2,3,4,5,6,7,8]; let arr1= arr.filter(function(value,index,arr){ arr[index]=value++ console.log(arr) return arr[index] }) console.log(arr1) console.log(arr) 通过打印出来发现是不会改变原数组arr的。
接下来我们实践一下第二个参数的作用。第二个参数说的是对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"
我们可以打印一下this看一下
let arr=[1,2,3,4,5,6,7,8]; let obj={ name:'123', age:12, sum:100 } let arr1= arr.
一款Android识别的APP 写这个app的初衷是最近这一两年一直针对OCR识别在学习研究 背景:由于https://github.com/rmtheis/android-ocr 该项目由于作者已经不再维护,迫于无奈,引用作者的项目基础继续开发。采用google的tesseract开源框架。什么是tesseract:
Tesseract最初由惠普实验室支持,用于电子版文字识别,1996年被移植到Windows上,1998年进行了C++化,在2005年Tesseract由惠普公司宣布开源。2006年到现在,由Google公司维护开发。一款图像识别的框架。由于项目多年未再维护更新导致Android高版本权限问题 进入APP直接崩溃。故增加Android6.0以后的动态权限功能,使得兼容已知所有版本,使用方便。部分代码: 权限部分 AndroidManifest.xml 中必不可少的权限,摄像头、网络、写入本地化存储
<uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 增加一个欢迎界面处理Android6.0以后动态申请权限逻辑 package edu.sfsu.cs.orange.ocr; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import edu.sfsu.cs.orange.ocr.utils.PermissionHelper; public class WelcomeActivity extends Activity { /********** is above android 6.0 request permission*******************************************************/ static final int PERMISSION_REQUEST_CODE = 5; private String[] permissions= new String[]{Manifest.permission.CAMERA, Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if(PermissionHelper.
最近弄了个ARDUINO开发板玩,发现RGB565的颜色代码转换很不习惯,查了不少资料,发现在我们的计算机中图像是以RGB888格式显示图像的,24位图每个像素保存了32bit的数据,即RGB888+Alpha,Alpha就是半透明填充字节。
但是在很多单板机里面是使用RGB565显示图像的,网上很多调色板工具和程序都是用RGB888格式,很少有RGB565的。
因此,自己弄了个简单的RGB565和RGB888颜色代码转换的工具。
基本原理:
一.RGB888->RGB565
方法只要提取相应单色高位即可(R5 G6 B5),但会导致低位的缺失,影响精度,而且无法恢复。
二.RGB565->RGB888
方法只要补充相应单色低位即可(R3 G2 B3)。在图像转换中会使用一些算法来补充,这里不涉及图像转换,仅颜色码的转换。
RGB888用unsigned int 32位字节存储
0 0 0 0 0 0 0 0R7R6R5R4R3R2R1R0G7G6G5G4G3G2G1G0B7B6B5B4B3B2B1B0 RGB565用unsigned short 16位字节存储 R7R6R5R4R3G7G6G5G4G3G2B7B6B5B4B3 程序实现:
基本的tkinter使用,python 3.7
核心程序就是通过位移取得RGB565的R,G,B三色值。简单的使用Label显示色块,三个颜色的滑块可以自由拉动。
#!/usr/bin/env python # -*- coding: UTF-8 -*- from tkinter import * import re window = Tk() window.title("RGB888 转换 RGB565") window.geometry('450x300+300+250') def scalecommand(color): #print(s1.get(),s2.get(),s3.get()) b=s3.get() g=s2.get() r=s1.get() R = r & 0xF8 G = g & 0xFc B = b & 0xF8 rgb565 = (R << 8) | (G << 3) | (B >> 3) rgb888 = (r << 16) | (g << 8) | b rgb888_text = 'RGB888: '+ "
参考文章:UnityWebGl与Web前端Html通信,互通消息_boyZhenGui的博客-CSDN博客 1.创建.jslib文件 在unity的Plugins文件夹下,创建.jslib文件(可先创建txt,然后将txt打开,另存为.jslib),名字随意。例如: Test.jslib
Test.jslib内容如下:(Hello名字在unity中使用,TestSend名字在Web中使用。)
mergeInto(LibraryManager.library, { Hello: function (str) { TestSend("Hello, world!"); }, }); 2.unity C# 创建关联脚本 脚本需要引入命名空间:using System.Runtime.InteropServices;
using System.Runtime.InteropServices; using UnityEngine; public class Test : MonoBehaviour { //声明和jslib文件关联的Hello()方法 [DllImport("__Internal")] private static extern void Hello(); void Start() { //调用测试,在unity脚本任意地方,调用hello方法都可以。 Hello(); } } 3.打包,并修改index.html 选中Webgl平台,打包修改index.html
在html代码的中添加如下代码:
function TestSend(s) { alert(s); } 方法名TestSend与.jslib文件function内方法名相同,参数数量相同。
4.打开更改后的网页(也用火狐浏览器,直接在本地打开) 即可发现进入场景后,执行了Start()中的Hellow方法,从而调用了web中新定义的TestSend()方法。弹出alert对话框。
5.如需传递字符串,jslib代码修改如下:
mergeInto(LibraryManager.library, { Hello: function (str) { TestSend(Pointer_stringify(str)); }, }); 传递其他数据结构,请查看上方官方手册。
Web前端调用Unity方法 1.在Unity脚本中创建public方法 public void GetFromWeb(string str) { Debug.
依赖
using System.Web; 设置Cookie 1.新建Cookie对象 HttpCookie cookie = new HttpCookie("UserInfo"); “UserInfo”是这个Cookie的名称
2.设置Cookie有效时间 cookie.Expires = DateTime.Now.AddDays(15); 3.设置Cookie属性与值
cookie.Values["UserName"] = "萌狼蓝天"; “UserName”是UserInfo的熟悉,“萌狼蓝天”是该属性对应的值
为了避免中文乱码,应该对值进行URL编码(使用时需要URL解码)
cookie.Values["UserName"] = HttpUtility.UrlEncode("萌狼蓝天"); 获取Cookie 1.获取Cookie对象 HttpCookie cookie = Request.Cookies["UserInfo"]; UserInfo 是设置的Cookie名
2.获取Cookie值 HttpCookie cookie = Request.Cookies["UserInfo"]; lblUserName.Text = cookie.Values["UserName"] UserName是UserInfo的属性
为了避免中文乱码问题,应在设置时使用URL编码,则获取时,需使用URL解码
lblUserName.Text = HttpUtility.UrlDecode(cookie.Values["UserName"]); 判断是否存在某个Cookie //取cookie HttpCookie cookie = Request.Cookies["UserInfo"]; //判断Cookie是否为空 if (cookie != null) { //如果不为空,说明有Cookie,此时跳转到userticket.aspx Response.Redirect("userticket.aspx", false); }
文章目录 前言一、查看当前log4j版本二、升级log4j版本 前言 log4j发生了巨大漏洞,可以在远程直接在服务器上执行多种操作,被戏称log4shell,众多公司面临解决log4j漏洞问题,本文主要介绍log4j升级版本相关 一、查看当前log4j版本 首先需要确认下当前项目是否引入了log4j?引入的log4j版本是多少?有些项目可能没有直接引入,但引入的其他组件中使用了log4j,所以需要仔细排查一下! 这里,我们可以使用IDEA编译器带的maven show dependencies功能来分析。 以Springboot+maven项目为例
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> 项目中使用了spring-boot-starter-log4j2,但是无法看到版本信息,这个时候怎么办? 可以在IDEA找到项目的pom.xml文件,右键找到show dependencies。打开后如下,找到对应的log4j的依赖图:
可以看到log4j是否被依赖,且可以查看版本。
二、升级log4j版本 如果你还不是2.15.0版本,如果和是我一样是使用了springboot的log4j的stater,可以直接通过如下指定properties的方式就可以了。
<properties> <java.version>1.8</java.version> <log4j2.version>2.15.0</log4j2.version> </properties> 如果不是,可以直接在pom文件中找到对应的jar包引入,然后修改版本号即可。
最后,可以通过IDEA的show dependencies查看版本信息,或者通过External Libraries查看。
如图,在通过Jmeter请求接口时,返回了415状态码,在响应数据中提示"Unsupported Media Type"
http 415状态码是指的对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。
所以就要去看请求头中的content-type填写是否正确
请求头中的Content-Type的值是"application/x-www-form-urlencoded"但是返回的响应头中为"application/json",所以显然返回415状态码是由于请求头不匹配导致的,修改请求中的content-type就行了
在线程组中新增一个Http信息头管理器,添加Content-Type=application/json,然后再发送请求,就不会报415啦
鉴于网络上有很多用yolov3算法训练自己的数据集的教程都失效的情况下,我决定自己写一篇。在最新版的pytorch环境下训练。
首先要准备好我们自己的数据集(也就是图片),然后用我们的标注工具进行标注
1、标注工具(labelimg)
Labelimg是一款开源的数据标注工具,可以标注三种格式。
1 VOC标签格式,保存为xml文件。
2 yolo标签格式,保存为txt文件。
3 createML标签格式,保存为json格式。
下载就不多说了,用命令行或者官网下载都可以(我是用命令行安装的)
pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple 2、标注前的准备
首先这里需要准备我们需要打标注的数据集。这里我建议新建一个名为VOC2007的文件夹,里面创建一个名为JPEGImages的文件夹存放我们需要打标签的图片文件;再创建一个名为Annotations存放标注的标签文件;最后创建一个名为 predefined_classes.txt 的txt文件来存放所要标注的类别名称。
VOC2007的目录结构为:
├── VOC2007
│├── JPEGImages 存放需要打标签的图片文件
│├── Annotations 存放标注的标签文件
│├── predefined_classes.txt 定义自己要标注的所有类别(这个文件可有可无,但是在我们定义类别比较多的时候,最好有这个创建一个这样的txt文件来存放类别)
2、对数据集进行标注
首先在JPEGImages这个文件夹放置待标注的图片,这里是六类图片,这里我用的飞机蒙皮的缺陷图片。分别是fadongjihuahen、mengpiwuzi、biaomianyiwu、mengpikongdong、mengpiliewen、mengpidiaoqi。
然后再 predefined_classes.txt 这个txt文档里面输入定义的类别种类;如下图所示。
然后从终端进入到刚刚创建的这个VOC2007路径
输入如下的命令打开labelimg。这个命令的意思是打开labelimg工具;打开JPEGImage文件夹,初始化predefined_classes.txt里面定义的类。
labelimg JPEGImages predefined_classes.txt 运行如上的命令就会打开这个工具;如下。 大家自行查找一下这个软件怎么用,不细讲了
标签打完以后可以去Annotations 文件下看到标签文件已经保存在这个目录下。
3、安装yolov3
下面就要下载编译yolov3了,yolov3的版本很多,我推荐大家下载我这个版本,其他版本会出现各种问题
git clone https://github.com/ultralytics/yolov3.git cd yolov3 pip install -r requirements.txt 这几行代码就把yolov3和相关依赖下载好了。
由github上的官方教程可以知道训练coco128数据用的下面这行代码
python train.py --img 640 --batch 16 --epochs 5 --data coco128.yaml --weights yolov3.
从零开始Cubemx配置STM32搭载freeRTOS以及lwip实现网络通信 引言CubeMX配置以太网以及LWIP实现一个回环功能(裸机)ETH配置LWIP配置 CubeMX配置以太网以及LWIP实现一个回环功能(freeRTOS)结论 引言 看见名字自己就笑了,标题的长度已经快赶上日本轻小说了,正好最近在追无职转生。
说回正题,上篇文章介绍了如何从零开始使用CubeMX生成一个带有freeRTOS操作系统的程序,嵌入式进阶指南以及必备知识学习路线,朋友们可以去看一下,这篇文章我将开始重头戏,如何在STM32F407上移植lwip实现TCP通信,最终实现一个httpd服务器。
自己写的另外两篇文章
从零开始Cubemx配置STM32搭载freeRTOS实现多路ADC(一)
从零开始使用CubeMX配置STM32使用lwip实现httpd服务器(三)
CubeMX配置STM32实现httpd服务器CGI功能并使用网页控制STM32单片机(四)
CubeMX配置以太网以及LWIP实现一个回环功能(裸机) 实现这个功能需要配置2部分,一部分的EHT也就是以太网的配置,另一部分是lwip协议栈的配置
ETH配置 ETH的配置主要有三个器件,单片机,物理网卡(在本文中我们使用的是LAN8720A芯片)以及网口。在这里面最重要的是物理网卡,单片机ETH的配置主要以物理网卡为主,与其电路连接有关系。LAN8720A的知识主要看这一篇文章 https://blog.csdn.net/sinat_20265495/article/details/79628283?spm=1001.2014.3001.5506
现在开始使用Cubemx配置ETH,在Connectivity选择中选择ETH
MII(Medium Independent Interface)是IEEE802.3u规定的一种介质无关接口,主要作用是连接介质访问控制层(MAC)子层与物理层(PH-Y)之间的标准以太网接口,负责MAC和PHY之间的通信。由于MII需要多达16根信号线,由此产生的I/O口需求及功耗较大,有必要对MII引脚数进行简化,因此提出了RMII(Reduced Medium Independent Interface,精简的介质无关接口),即简化了的MII。更详细的看这篇文章 https://blog.csdn.net/fun_tion/article/details/70270632
采用MII接口,PYH的时钟频率要求25M,不需要与MAC层时钟一致。
采用RMII接口,PYH的时钟频率要求50M,需与MAC层时钟一致,通常从MAC层获取该时钟源。
现在一般都用RMII模式
LWIP配置 接下来生成代码就可以了
在主函数中,添加这两个函数
实现回环代码,新建一个tcpecho.c文件,代码
#include "tcpecho.h" #include "lwip/netif.h" #include "lwip/ip.h" #include "lwip/tcp.h" #include "lwip/init.h" #include "netif/etharp.h" #include "lwip/udp.h" #include "lwip/pbuf.h" #include <stdio.h> #include <string.h> static err_t tcpecho_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (p != NULL) { /* 更新窗口*/ tcp_recved(tpcb, p->tot_len); /* 返回接收到的数据*/ tcp_write(tpcb, p->payload, p->tot_len, 1); memset(p->payload, 0 , p->tot_len); pbuf_free(p); } else if (err == ERR_OK) { return tcp_close(tpcb); } return ERR_OK; } static err_t tcpecho_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { tcp_recv(newpcb, tcpecho_recv); return ERR_OK; } void TCP_Echo_Init(void) { struct tcp_pcb *pcb = NULL; /* 创建一个TCP控制块 */ pcb = tcp_new(); /* 绑定TCP控制块 */ tcp_bind(pcb, IP_ADDR_ANY, TCP_ECHO_PORT); /* 进入监听状态 */ pcb = tcp_listen(pcb); /* 处理连接 */ tcp_accept(pcb, tcpecho_accept); } 这样裸机就成功了,可以ping成功
安装包阿里云链接:
https://www.aliyundrive.com/s/TYhvsCt7ayY
按顺序进行安装
sudo dpkg -i containerd.io_1.2.6-3_amd64.deb sudo dpkg -i docker-ce-cli_19.03.6_3-0_ubuntu-disco_amd64.deb sudo dpkg -i docker-ce_19.03.6_3-0_ubuntu-disco_amd64.deb 重启Docker
service docker restart 拉取镜像测试是否成功
docker pull hello-world 如果没网就导入一个镜像试试 先找一个有网的导出一个镜像 导出镜像: docker save -o 保存的文件名.tar 镜像名 然后通过U盘放入这个无网的电脑 导入镜像: docker load < 保存的文件名.tar 参考链接: https://blog.csdn.net/qq_42346414/article/details/89413328
https://blog.csdn.net/weixin_47948585/article/details/118960220
因为互联网公司是不直接靠技术赚钱的,使用何种技术对实现直接赚钱的业务来说都是次要的,往往是技术惯性决定技术选型。
国内信息技术发展偏科严重,软件行业毁于盗版和缺少政府扶持,互联网行业靠低技术门槛和资本运作吸收了大量社会资源和行业精英,主导了行业的发展。因此,国内软件行业缺失了发展机会,也使得.net平台在一个其擅长的领域缺乏积累。
1、在国内技术圈氛围就是很浮躁的,喜欢跟风、喜欢一窝蜂,人家用JAVA,我们就用JAVA;人家用k8s,我们也用k8s;人家用linux,我们也用linux,总之人家的东西比我们家先进,所以我们一定要跟上。拿k8s来说,其实很多传统企业根本没有用,也就是几家互联网大厂对它情有独钟;像Java spring我不能说不好,只能说我不习惯,Java相比C#语言逻辑有点啰嗦, 代码的维护成本并不低,而且你需要雇佣很资深的Java开发人员,薪水自然是水涨船高。其实很多所谓的架构师、IT经理考虑的不是迁移成本、运维成本,而是怎么找点事做,这样才能体现出自己的价值,大体可以总结为四个字“无中生有”。
2、.Net的开发效率相比Java太高了,效率高了自然就拉低了就业率,招的人少嘛!毕竟你用Java10个人能干的活使用.Net招5个人就可以干完了,还不用加班,自然不受待见。
如果回头看看以前的webform,再看看现在的低代码,现在的低代码不是以前.net 玩剩下的吗?很多人说拖控件太快,性能不高,10年前哪有现在的大数据,几个公司有海量的业务量。
3、国外.Net名气高,是因为欧美的人力成本高,国内我们人多啊,有一个idea毕竟招一个.Net程序员就可以开干了。
4、当然了,以前.Net是不开源的,代码也是看不到的,这个与微软有关,不多说了,可以去了解下,很多人以前搞.Net 后来就转其他语言了,转JAVA的占多数,.Net转JAVA后黑.Net的人也多,至于为什么,有爱就有恨。
5、其实与.Netcore开源有点晚也有关,市场份额被以JAVA为首的占了去,.Net只剩下传统行业市场的一些份额了,还有就是.Net技术体系更新太快,很多人跟不上自然就被淘汰了,像.Net core现在已经出到6了,java还在使用Jdk为8的版本。TG:li9047
先说一下防抖特性:即在固定的时间内触发事件过多则会不停的刷新那个时间,比如我要在3秒后执行一个时间,当我们不停的去触发这个时间,这等待的3秒会被不停的刷新为3秒,只有当我们点击后不在进行触发该事件得操作,该事件才会被执行
节流的特性:其实节流的特性和我们的防抖差不多,只是节流的特性是,在一个固定的时间内,不管我们触发多少次的时间,他都只会执行一次。比方说就是在3秒内我们触发很多的事件,在这个期间内,他都只会执行一次的事件操作。
它们相同的特性我觉得就是把我们很高频率的操作变为一个低频率的操作
接下来我们可以看一下代码上是的区别
先看防抖代码:
function fn(fun){//fun是我们等会传进来的实参,所执行的函数体 let timer;//定义一个变量来积存计时器 return function(){ clearTimeout(timer);//每次调用都会先关闭计时器 timer=setTimeout(fun,1000)//1秒后调用这函数体 } } let i=0; function body(){//等会传进去的函数 console.log(i++) } document.getElementById('div').onmousemove=fn(body)//高频触发所调用的函数 通过上面的代码就简单的完成一个防抖函数的小demo如果需要优化的话,需要自行优化
接下来看看节流的代码:
function fn(fun){ let timer; return function(){ if(!timer){//必定执行一次 timer=setTimeout(function(){ timer=null//在定时器执行完毕,取空代表后续的可以执行 fun(); },1000) } } } let i=0; function body(){ console.log(i++) } document.getElementById('div').onmousemove=fn(body) 上面代码是我通过视频所写的,一个节流的小demo,使用的话对其进行小改就行。
总结一下上面的所有东
防抖:在一个计时器内,触发事件如果多次触发,则计时时间会被重置。
节流:持续触发事件,隔一段事件,只执行一次
Java 入门(基础概念与常识)
Java 语法
基本数据类型
方法(函数)
2. Java 面向对象
=============
类和对象
面向对象三大特征
修饰符
接口和抽象类
其它重要知识点
3. Java 核心技术
=============
集合
异常
多线程
文件与 I\O 流

(二). 容器
=======
1. ArrayList
=============
ArrayList简介
ArrayList核心源码
ArrayList源码分析
ArrayList经典Demo
2. LinkedList
==============
简介
内部结构分析
LinkedList源码分析
LinkedList类常用方法测试
3. HashMap
===========
HashMap 简介
底层数据结构分析
HashMap源码分析
get方法
resize方法
HashMap常用方法测试
(三). 并发
=======
1. 并发容器
========
JDK 提供的并发容器总结
ConcurrentHashMap
CopyOnWriteArrayList
ConcurrentLinkedQueue
BlockingQueue
文章目录 编译辅助工具1.脚本介绍2.原理介绍 编译辅助工具 1.脚本介绍 这个脚本的主要目的如下:
命令行自动编译程序杀掉程序启动程序更新代码支持命令行字体颜色高亮 可以帮我节省几分钟的时间。剩下的这几分钟时间,可以让我思考刚才修改的代码有没有问题。
还有一些配置通过脚本config.json配置
PS D:\code>.\compile.py -h usage: compile.py [-h] [-u] [-pre] [-k] [-s] [-c] [-a COMPILEARGS] [-p CONFIGPATH] Tools for auto update code and compile project optional arguments: -h, --help show this help message and exit -u, --update update code by svn or git -pre, --precompileaction build code previous action,for example Qt qrc file. -k, --kill kill target process -s, --start start target process -c, --compile compile project -a COMPILEARGS, --compileargs COMPILEARGS compile project with args, for example:"
是这个亚子的,突然发现支付宝接口调不了了,之前没有接触过支付方面的接口调用,通过学习今天终于把问题给解决啦,记录一下,是关于支付宝的公钥证书过期的问题如下图
从图中的返回错误来看问题已经很明显了。
但是没接触过的话就不知道从哪个地方入手解决
首先打开支付宝开放平台https://open.alipay.com/dev
登录你要使用的支付宝的账户
然后直接看官网的这个文档
https://opendocs.alipay.com/common/02kdnh
基本上没有问题
AjaxResult deviceAlarmList = tDengineRemote.getDeviceAlarmList(exception); Object rows = deviceAlarmList.get("rows"); List tbPointExceptions = JSONArray.parseArray(JSONArray.toJSON(rows).toString(),TbPointException.class);
备注:rows 是一个大的对象,里边封装了许多实体类对象,大家可以当成一个list对象,
原来直接通过json的tojavaList会报转化错误,经过测试发现,如上写法,不会报错!
最近有问题需要进行抓包,但是安装好wireshark后无捕获过滤器/找不到重要的接口列表,找不到本地网卡,wireshark无法使用。
为解决上述问题,在命令行/管理员身份命令行输入命令 net start npf,居然显示:
服务名无效。
原因:
缺少用于网络封包抓取的工具 winpcap
解决办法:下载安装 安装WinPcap
安装后重新操作:打开wireshark—>捕获—>刷新接口列表,正常显示所有网卡了。
如果还不行,在命令行,输入net start npf,然后重启wireshark(可以尝试使用管理员权限重启)。
ARM ubuntu18.04安装kafka 1.jdk安装 kafka消息队列依赖于jdk,ARM ubuntu18.04需要先安装jdk。本教程安装的是jdk1.8,jdk安装主要参考银河麒麟 安装 jdk_wqqqianqian的博客-CSDN博客_银河麒麟安装jdk,其中下载jdk时,请下载 jdk-8u311-linux-aarch64.tar.gz ,只要是带aarch64的就可以,aarch64代表arm平台。
2.卡夫卡安装 下载地址:Index of /dist/zookeeper/stable (apache.org)
下载名称为:apache-zookeeper-3.6.3-bin.tar.gz 的文件。bin.tar.gz代表是已经编译过的,可以直接运行。
启动参考地址:Kafka 中文文档 - ApacheCN
启动指令前面请加 sh,例如:sh bin/kafka-server-start.sh
启动过程可能会出现以下问题:
(1)报xxxxxxxxxxx bin/kafka-run-class.sh Permission denied,kafka-run-class.sh权限问题
解决方案:sudo chmod bin/kafka-run-class.sh ,为kafka-run-class.sh赋予权限
(2)报Error: VM option ‘UseG1GC’ is experimental and must be enabled via -XX:+UnlockExperimental。
解决方案:参考地址:kafka启动失败:Error: VM option ‘UseG1GC‘ is experimental and must be enabled via -XX:+UnlockExperimental_一只赤脚行走的猪的博客-CSDN博客
优化之前,页面加载完数据之后的首次渲染,会一次提交问题区、回答区、广告组件区三个部分的渲染任务,由于这三个区域涉及的内容量比较大,基本都会超过一屏,甚至两屏以上,另外各个区域也都包含一些图文内容,加上本身耗时较高的广告组件。整体页面内容渲染速度很差。并且,因为存在直播信息横条等单独异步请求加载的数据内容渲染,也容易造成 setData 操作在小程序渲染线程中拥塞现象的发生。
所以,从小程序 FMP 的统计规则来看,目前的数据渲染逻辑,
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
显然并不是最优的。
既然 FMP 主要统计的是用户第一眼可以看到的首屏位置内容,那么我们是不是可以换个思路来完成我们的内容渲染工作。
在确保数据接口性能已经符合常规标准的情况下,我们可以使用更聪明的渲染策略。
优化方案 为了解决上述问题,我们构思了一套分屏式内容渲染策略,意在让用户能最快速度的先看到一部分关键内容,再分阶段渲染剩下需要被渲染的数据,而那些不需要被自动渲染的数据,可以改成由用户某种行为(比如滑动页面)触发加载和渲染。
优化后的问答页渲染示意图 PS:广告组件本身为异步组件,第二次 setData 会触发广告组件渲染,而广告组件内部自行发起异步内容的加载。
优化后的问答页渲染逻辑,整体上被拆分为四个阶段:
核心内容快速渲染阶段。该阶段为 FMP 主要检测的数据渲染时长,所以在这个阶段,我们需要让页面的内容和元素,足够装满一屏。核心内容补全渲染阶段。该阶段将核心内容中存在的耗时内容,比如图片、视频以及小程序 native 组件等内容渲染上屏(注:关于渲染比较耗时的组件,目前已知视频 video 、所有小程序 native 组件,都不适宜放在第一阶段直接渲染,图片 image 如果条件允许,也尽量不放在第一屏)。后续内容渲染阶段。该阶段将本次接口返回的需要渲染的数据全部上屏。其他非主要异步数据渲染阶段(图例中的直播信息横条)。将另外一个接口的数据渲染上屏。 PS:如果存在核心内容渲染完成后依旧无法撑满一屏的情况,可以考虑设置整体页面 min-height:100vh ,或者页面下方放置占位元素,来达到撑满一屏的效果。
优化成果 该优化版于2020年8月4日上午11点左右全量上线,在手百中逐步放量。 FMP 指标在8月5日和6日两天快速下降,7日逐步稳定。总计优化 FMP 指标 540ms 。
从数据表现来看,优化效果非常明显。
并且,问答页作为宝宝知道小程序 pv 最大的落地页,占据总 pv 的 60% 左右,另外还有 40% 的其他页面需要我们持续优化,未来数据表现还有不小的优化空间。
工具建设 工欲善其事必先利其器。后续我们还需要优化其他入口页面的性能,以及为后续开发高性能页面做持续的技术储备,所以我们将开发中遇到的和性能有关的问题做了一些抽象,通过打造基础操作的工具类库,从底层上来解决或者规避问题。
上文中有提到,同时发起多个 setData 操作,极易造成小程序渲染线程的拥塞,导致渲染效率受到影响,降低小程序内容上屏的效率。实际开发中,我们如果要避免同时发起多个 setData ,必然会带来额外的逻辑思考成本和代码结构调整的成本,也容易因为调整,降低代码的可读性和可维护性。为了兼顾渲染性能的需要和代码结构的可读性,以及代码观感,我们专门设计了一个内容渲染任务管理器。
DataSetter
DataSetter 目前已经集成在团队内部的小程序工程脚手架中,通过 AdvancedPage 创建的小程序 Page 实例,即可支持通过该管理器开放的 api 接口,向小程序的渲染线程提交数据渲染任务。
Ubuntu18.04安装QT5.15的避坑步骤 前言一、安装Ubuntu18.04系统二、安装编译工具链三、安装开发包——Linux/X11平台插件所需四、Ubuntu18.04升级GLIBC至2.28五、复制动态库文件libbz2.so.1六、下载运行QT Online Installer总结 前言 QT官网的文档中说明,QT5.15的Linux平台要求是Ubuntu18.04。
作者是第一次在Ubuntu18.04系统下安装QT5.15,安装过程中出现了一些问题。通过在网上查找大量资料,终于安装成功。
现将问题和解决方法记录下来,希望看到此文档的同仁能够轻松避坑。
一、安装Ubuntu18.04系统 QT支持很多体系架构的操作系统,但是同样对于操作系统平台有配置要求。对于Linux操作系统而言,其中一种就是Ubuntu18.04。1
安装Ubuntu18.04很简单。作者参考教科书2中的做法,采用VisualBox作为虚拟机。具体步骤参考另一篇博文。
二、安装编译工具链 适用于 Linux 的 Qt 安装程序假定主机操作系统提供 C++ 编译器、调试器、make 和其他开发工具。此外,构建图形 Qt 应用程序需要安装 OpenGL 库和头文件。大多数 Linux 发行版默认情况下不会安装所有这些,需要配置开发环境。
**失败教训:**作者第一次安装QT的时候就没有注意,导致在运行QT installer的时候报错。 如果参考了官方的文档,其实这一步很简单,只需要使用以下命令:
sudo apt-get update sudo apt-get install build-essential libgl1-mesa-dev sudo apt-get install libopengl0 sudo apt-get install bison sudo apt-get install gawk The Qt installers for Linux assume that a C++ compiler, debugger, make, and other development tools are provided by the host operating system.
目录
一、概述
1.1、数据文件
1.2、存储结构分类
二、物理存储结构
2.1、操作系统数据块
2.2、数据文件
三、逻辑存储结构
3.1、表空间
3.2、段
3.3、区
3.4、块
在开始介绍数据文件之前,我们先先回顾下数据库包含哪些文件?
有参数文件、控制文件、数据文件、重做日志文件、归档日志文件、跟踪文件、口令文件、警告文件等。具体介绍请查看:Oracle体系结构篇之数据库
一、概述 1.1、数据文件 数据文件是指存储数据库中数据的文件,这些“xxxx.dbf”存储着系统数据、数据字典数据、索引数据以及用户存储的数据,所以这部分也是数据库最核心的部分。数据文件大小是灵活的,可以通过设置让它自动扩展,避免了数据量过大但是数据文件空间有限这种状况; 数据文件是专属于一个数据库的,也专属于一个表空间的,但是一个表空间却可以拥有多个数据文件。
1.2、存储结构分类 数据文件按照存储结构可以分为物理存储结构和逻辑逻辑结构。
二、物理存储结构 这个就很好理解了,就是保存在磁盘空间上的数据,以文件的形式组织在一起,是一些能看得见,实际存在的东西,大白话就是一类文件组成了Oracle的数据文件的物理存储结构。
2.1、操作系统数据块 操作系统数据块是文件系统所使用的最小分配单元。数据库就是搭建在操作系统数据块基础上。
2.2、数据文件 保存Oracle数据的操作系统文件,用户可以在操作系统中浏览到数据库的数据文件。数据库创建时会创建对应数据文件,数据文件中保存着数据字典和用户数据等信息。
可以在数据库中查看数据文件信息:
SELECT * FROM DBA_DATA_FILES;
三、逻辑存储结构 在oracle数据库中,对数据库操作会涉及逻辑存储结构,它是从逻辑角度分析数据库的构成,描述的是数据库内部数据的组织与管理方式,与操作系统没有关系。主要包括表空间、段、区和数据块,所有的结构都是一对多的关系,一个数据库可以拥有多个表空间,一个表空间拥有多个段等等。
3.1、表空间 Oracle 数据库是由若干个表空间构成的。任何数据库对象在存储时都必须存储在某个表空间中。表空间对应于若干个磁盘文件,即表空间是由一个或多个磁盘文件 构成的。表空间相当于操作系统中的文件夹,也是数据库逻辑结构与物理文件之间的一个映 射。每个数据库至少有一个表空间,表空间的大小等于所有从属于它的数据文件大小的总和。
可在数据库中查看表空间信息
SELECT * FROM DBA_TABLESPACES;
常用表空间:
1)SYSTEM 系统表空间
SYSTEM表空间包含数据字典,是数据库的大脑,没有SYSTEM表空间,数据库就无法运转。数据字典表存储在编号为 1 的数据文件中。
所有和 PL/SQL 程序结构(包括过程(procedure),函数(function),包(package),及触发器(trigger))有关的数据都被保存在 SYSTEM 表空间中。如果数据库中用户定义的程序结构很多,那么管理员必须为之在 SYSTEM 表空间中提供足够的空间。
SYSTEM表空间特性:
不能脱机offline不能置为只读read only不能重命名不能删除 2)SYSAUX 表空间
Sysaux 主要作用就是减轻system表空间的压力,部分的程序与工具放在sysaux表空间中。
在Oracle 10g 版本中,引入了SYSTEM表空间的一个辅助表空间: SYSAUX表空间。
SYSAUX 表空间存放一些其他的metadata组件,如OEM,Streams 等会默认存放在SYSAUX表空间里。这样也能降低SYSTEM表空间的负载。 因此SYSAUX 表空间也是在在DB 创建或者升级时自动创建的。 如果在手工使用SQL创建DB时没有指定SYSAUX tablespace,那么创建语句会报错。 无法执行。
单USB Type-C接口,同时具有HDMI/USB扩展和直流供电,USB Type-C接口桌面式显示器的典型形态,整个显示器通过DC接口输入类似24V/3A的大功率电源,出了满足本身的功率需求,还可以为通过USB Type-C接口接入到显示器的手机或者笔记本电脑提供PD快充。LDR6290,Type-c桌面显示器方案(90W充电+数据传输+视频传输 办公娱乐一体桌面显示器)。
这种显示器设计架构,既可用于便携式显示器,也可用于台式显示器。对于便携显示器市场,双全功能USB-C接口,毫无疑问是消费者的最佳选择。因为便携显示器插拔接口的操作会比较频繁,如果需要区分两个外观完全相同的接口的功能,消费者会不胜其烦。即便是对于台式显示器,考虑到未来所有电源适配器都将统一到USB-C接口,提前布局为通过USB-C接口供电,也是产品规划中非常有前瞻性的策略。Type-c桌面显示器方案(90W充电+数据传输+视频传输 办公娱乐一体桌面显示器)
LDR6290,单USB Type-C接口桌面显示器专用解决方案,主要框架如下:
首先从Date上面来看,通过与LDR6290 CC PIN的协议通讯,USB Type-C接口输入DP信号与Date信号,给到单USB Type-C接口桌面显示器的相关功能模块,实现音视频显示与USB3.0/2.0的功能。Type-c桌面显示器方案(90W充电+数据传输+视频传输 办公娱乐一体桌面显示器)
再从Power上面来看,DC接口的22V-32V的电源输入,经过DC-DC芯片,从USB Type-C接口输出5V-9V-12V-15V-20V的电压,当然这个电压输出多少,决定于插入单USB Type-C接口桌面显示器的手机或者显示器跟LDR6290的CC协议通讯,再由LDR6290控制DC-DC芯片的FB产生。Type-c桌面显示器方案(90W充电+数据传输+视频传输 办公娱乐一体桌面显示器)
博主的技术交流群:722058911
问题背景:在分类网络中,往往需要突出前景,弱化背景,往往有一个操作是减去均值。
解决办法:(供参考,我是这么解决的)
求自己数据集的均值和方差
def compute_mean_std(your_dataset): """compute the mean and std of your dataset Args: your_training_dataset or your_test_dataset witch derived from class torch.utils.data Returns: a tuple contains mean, std value of entire dataset """ data_r = numpy.dstack([your_dataset[i][1][:, :, 0] for i in range(len(your_dataset))]) data_g = numpy.dstack([your_dataset[i][1][:, :, 1] for i in range(len(your_dataset))]) data_b = numpy.dstack([your_dataset[i][1][:, :, 2] for i in range(len(your_dataset))]) mean = numpy.mean(data_r), numpy.mean(data_g), numpy.mean(data_b) std = numpy.std(data_r), numpy.
如何提高研发效能 只有深入研发活动的本质,才能提高效能 提高研发效能,需要深入了解研发活动的本质,从纷乱的表象和层出不同的方法中,看到隐藏的模型,找到根本原因,然后从这些原则触发,具体问题具体分析,找到合适的方法。这种做的原因是,软件研发很灵活,在实践的时候总会见到不一样的状况。越是灵活的东西,就越需要理解其本质,这样才能做到随机应变。
有一个基本原则是“不要阻塞开发人员”。比如说,本地构建脚本的运行速度要足够块。开发人员在自己的开发机器上写完代码之后,都要运行这个脚本进行构建,把新做的改动在自己的开发机器沙盒环境上运行起来,以方便做一些检测。这个操作非常频繁,所以如何它的运行时间太长,就会阻塞开发。因此,确保这个脚本的快速运行就是内部工具团队的一个超高优先级的任务。我们对每次脚本的运行进行埋点跟踪,当运行时间超过了1.5min之后,我们就会停下手里的工作,想尽一切方法给这个本地构建加速。
为什么要有这个原则呢?因为开发流程的顺畅是生产优质软件的关键因素,只有这样才能最大程度的释放开发者的创造性和积极性。
那软件开发的本质到底是什么呢?
软件开发本质上就是一条超级灵活的流水线。这个流水线从产品需求出发,经过开发、测试、发布、运维等环节,每一个环节的产出流动到下一个环节进行处理,最后交付给用户。
另外,这条流水线的每个环节都还可以细分。比如,本地开发环境可以细分为下面几个部分:
这种流水线工作方式,在传统的制造业中很普遍,也已经有了很多经验和成功实践。最典型的就是汽车生产中使用的丰田生产体系(Toyota Production System,TPS)。所以,我们可以参考传统制造行业的经验来提高效能。
事实上,瀑布模型就类似于传统流水线的处理方法:它强调每个环节之间界限分明,尽量清晰的定义每一个环节的输入和输出,保证每一个环节产出的质量。但是和传统制造业相比,软件开发又具有超强的灵活性,体现在一下四个方面:
(1)最终产品目标的灵活性。传统流水线的目标确定,而互联网产品的最终形态通常是在不断迭代中逐步明确,相当于一个移动的标靶。尤其是最近几年,这一灵活性愈发明细。比如,在精益开发实践中,尝尝使用MVP(最小可行性产品,Minimal Viable Product)来不断验证产品假设,经过不断调整最终形成产品
(2)节点之间关系的灵活性,比如流水线上的多个节点可以相互融合。DevOps就是在模糊节点之间的边界,甚至有一些实践会直接去掉某些环节,或者融入到其他环节中。
(3)每个节点的灵活性。每一个生产环节都会不断涌现出新的生产方式 / 方法。比如测试,最近十多年就产生了测试驱动开发、Dogfood(狗粮测试)、测试前移等方法;最近又出现的测试右移,开始强调在生产环境中进行测试。
(4)每个节点上的开发人员的灵活性。跟传统制造业不同,流水线上的每一个工作人员,也就是开发者,都有很强的灵活性,主要表现在对一个相同的功能,可以选择很多不同的方式、不同的工具来实现。
基于这些特点,我们可以从以下四个方面去提高研发效能。
(1)优化流程。 主要针对特点 1 和 2,也就是最终产品目标的灵活性和节点间关系的灵活性,进行优化。具体来说:
针对最终产品目标的灵活性,主要是提高流程的灵活性,让它能聚集最终产品的用户价值,以终为始的指导工作,击中移动的标靶。针对节点之间关系的灵活性,主要是聚集流水线的顺畅,以保证用户价值受到的阻力最小 (2)团队工程实践。主是针对特点 3,也就是每个节点的灵活性进行优化,聚集每一个生产环节的工程实践进行提高
(3)个人工程实践。主是针对特点 4,也就是每个节点上开发人员的灵活性,来提高个人研发效能。争取让每个开发人员都能适时地关注业务,以终为始,同时从方法和工具上提高开发效率
(4)文化和管理。任何流程、实践的引入和推广,都必须有合理的管理方法来支撑。同时,文化是一个团队工作的基本价值观和潜规则。只有建立好文化,才能让团队持续学习,从而应对新的挑战。所以,要提高效能,我们还需要文化和管理这个引擎。
优化流程、团队工程实践、个人工程实践以及文化和管理,就是我们提高研发效能需要关注的四个方面,也就是我们所说的研发效能模型。
| long | 8 | 0 |
| int | 4 | 0 |
| short | 2 | 0 |
| byte(位) | 1 | 0 |
| char | 1 | \u0000 |
| boolean | 1 | false |
| float | 4 | 0.0 |
| double | 8 | 0.0 |
引用数据类型
| 数据类型 | 中文名称 | 默认值 |
| :-: | :-: | :-: |
2、kotlin相比于Java好处是什么?kotlin对空指针异常是如何处理的?let、with、apply的适用场景?
3、Java异常机制、Error能捕获到吗?
4、我项目中账号密码是保存在本地的,怎么去保证安全?
**算法1:**给一个数组,找出数组中第k大的元素
思路一:排序
思路二:优先级队列
思路三:使用数据结构堆
**算法2:**手写快速排序
今日头条三面 自我介绍。你的项目中用了kotlin,能说一下kotlin相比于Java好处是什么吗?
你的项目中用了LiveData,能说一下它的原理吗?(源码没看过,简单说了一下观察者模式)
http协议请求头都包括哪些内容?
计算机网络、操作系统、数据结构有系统学习过吗?
后端、web前端、iOS方面有接触过吗?(学过MySQL和一点点Spring)
你看过哪些Android源码?刚刚你提到了Handler,它是用来干嘛的?为什么要有Handler,自己写一个
线程间通信的代码不行吗?你提到了消息队列,它的作用是什么?消息队列和Handler一定要一起使用吗?
算法题 (1)用二分法在排序数组中找到绝对值最小的元素
(2)螺旋输出二维矩阵中的元素(不一定是方阵)
能实习多久?什么时候毕业?什么时候能开始实习?
反问
(1)大厂对于新技术的看法?敏不敏感?(大厂会第一时间学习新技术,但是真正用在项目中需要时间)
(2)鸿蒙的出现会不会抢了Android开发者的饭碗?(不会,移动端之间转行很容易)
腾讯-腾讯游戏
腾讯面试涉及到的范围也很广,甚至问到了C++,也具有一定挑战性的,腾讯面试过程中的感觉就是很多我不太熟悉的知识点都被问到了,甚至是不知道的知识点,但整体面试官给人的体验还不错,一般会提前打电话沟通面试时间。
腾讯一面 50分钟(腾讯会议视频面试)
自我介绍,顺便展示了自己的项目,展示中出现了一个bug(尴尬),面试官问为什么会出现这个bug, 出现bug你会采用什么方式解决(查看log)?如果是企业级应用修复bug,你会怎么做?项目是你自己写的吗?
写了多久?
有用过Java集合类吗(说了ArrayList、LinkedList、HashMap)?说一下它们各自特点和内部的原理?
Java中加锁的方式(sychronize和lock)?它们有什么不同?如果是高并发的场景,选哪个比较好,为什么?
http协议和tcp协议相关
你项目中用了kotlin,能说一下kotlin相比于Java的优势吗?
你的项目中用了kotlin协程,能说一下协程的概念吗?协程底层实现原理有看过吗?
说一下Android事件分发的过程?
View的测量、布局和绘制流程?自定义View需要重写哪些方法?自定义ViewGroup需要重写哪些方法?
区别是什么?为什么有区别?
你有写过自定义控件吗(说了一个树木生长的动画)?怎么实现的?
你项目中用的是okhttp+retrofit,为什么要用okhttp不用官方的httpUrlConnection?okhttp的好处是什么?
retrofit是干什么的?retrofit和rxjava一起用的好处是什么?
提问环节:
(1)您对Google推出的jetpack compose怎么看?(面试官没了解过)
(2)部门用Java还是kotlin?(新业务用kotlin,老的代码用Java维护,并不冲突)
(3)部门加班情况怎样?(早10点→晚8点,挺轻松)
(4)工作情况怎样,会不会天天开会?(一周开一次技术会)面试官又问了我天天几点去实验室,几点走
(5)能转正吗?(面试官也不清楚)
腾讯二面 电话面,20分钟
自我介绍
mvvm架构相比于mvp架构的优点是什么
你比较熟悉jetpack的什么组件,它用了什么设计模式?
你对电子竞技的前景怎么看?
你项目中用了kotlin,kotlin相比于Java优势有哪些?
提问
腾讯三面 腾讯会议视频面试(20min)
用腾讯会议的共享屏幕功能,花了10分钟给面试官介绍项目(模拟器现场演示app的一些业务功能)
你并不是计算机科班出身的,你对本专业就业方向怎么看?你打算把Android开发作为以后的就业方向吗?
你做项目时候感觉对自己最大的提升是什么?
后续在Android方面你打算学习哪些东西?(说了NDK和flutter)
你觉得kotlin相比于Java的优势有哪些?
项目是你自己写的吗?用户量有多少?有没有考虑过版本兼容性相关的问题?项目出现问题你该如何解决?
项目准备用到实际生活中吗?开发完之后你是怎么测试的?
之前有没有过实习经历?
总结:面试官说我的项目经历挺丰富的,但是缺乏深度,需要去公司中体验一下企业级别的项目来提升自己的技术。
美团
–
遍历带children的数组,并返回他们的id 1.个人习惯为通用型方法放在utils文件中
1.utils.js中
//遍历children的数组,返回所有的id(数组) //arr为入参,key为你想根据的key 如果为 export function getTreeIds(arr, key) { let result = [] if (!isArray(arr)) { return result } else { arr.forEach(item => { result.push(item[key]) if (item.children) { getTreeIds(item.children, key) } }) return result } } import { getTreeIds} from '@/utils/utils' //arr为树型结构数组 let List = getTreeIds(arr)
web前端应该如何学习,需要做什么准备吗?前端开发行业已经发展到了一个高速发展时代,在过去的几年内,简单的HTML、CSS、JavaScript做出来的静态网页已经不能满足现在用户的需求,而企业也是需要综合开发技能较强的开发工程师,开发手段也是丰富多样的。
现在有越来越多的小伙伴选择学习前端开发技术知识,但是在网上有很多消极的看法对想学习前端开发者造成了无形的阻力,其实随着前端开发技术的不断更新发展,企业为了发展需求,所招聘的前端开发工程师大多数是在3-5的中级前端开发工程师,而并非是初级前端开发工程师,从而可以看出前端开发行业并没有达到饱和的状态。
想要从初级工程师成长为中级或高级开发工程师,还是需要不断的系统学习庞杂,框架、库、插件等,那小伙伴该如何学习呢?
1.基础知识的积累
首先小伙伴要了解什么是前端基础?不外乎HTML、CSS,JavaScript,其中特别是JavaScript,在一定程度上小伙伴对前端基础知识的掌握程度是体现在对JavaScript的掌握程度,而且JavaScript脚本语言运用是非常广泛的,小伙伴在参加高级或中级前端开发工程师面试中,面试官对JavaScript知识的考核也是必不可少的。
2.项目实战案例的练习
小伙伴在积累基础知识的过程中,不要忽略了项目实战案例的练习,小伙伴可以通过不同难度项目案例练习,来加深了解前端开发技术知识,同时可以锻炼小伙伴的动手能力和解决问题的能力。
3.主动学习
小伙伴想要学好前端开发技术知识,还需要自己主动的学习。一个优秀的前端开发者是拥有深厚的知识积累,而这些知识的来源是他们不断的学习得来的,即使在工作中遇到再棘手的问题,也会通过所学习的知识得到答案,这样在面试中才能脱颖而出,获得丰厚的薪水。
小伙伴在学习前端开发技术知识过程中,应该不断的努力自主学习,找到适合自己的学习方式。
web前端即为网站的前端开发,前端开发是创建Web页面或app等前端界面呈现给用户的过程。 web前端开发通过HTML,CSS及JavaScript以及衍生出来的各种技术、框架、解决方案,来实现互联网产品的用户界面交互。
1.根据项目或者产品需求负责实现PC端及移动页面的设计和开发、调试等工作,高效、高质地完成代码编写,确保符合前端代码规范;
2、与后端开发团队紧密配合,完成接口对接,确保前后端有效交互共同完成项目或者产品;
3、综合运用客户端和服务器端构建与优化方案、模块化开发等手段,提升开发效率和系统性能;
4、持续优化前端应用,改善用户交互以及视觉,保证前端网页的兼容性以及页面响应速度并负责前端代码的维护,
5、了解并结合业务需求,设计满足用户需要、符合用户习惯、运用大数据分析能力、体现大数据特色的系统。
6.与设计师、产品工程师紧密工作在一起,实现产品前端ui和交互方面的开发需求,确保不同平台、设备上具有优秀的用户体验;
前端学习想要达到可以找工作的程度还是比较简单的,但是想要通过学习找到高工资的工作可就不容易了,如果只是想要找个普通的工作只要学了前端的基础知识,主流框架实现一定的兼容展示功能,在就是做几个前端 Web项目就可以,但是你要是去一些大公司,或者找一个比较好的工作的话那么只进行这些前端学习是不够的。
所以想找到一个“好工作”,唯一的办法就是好好学习,只有充实自己才有可能找到更好的工作有更好的未来和同时才能把握更多的机会。
想要通过千锋重庆web前端的学习找到一个不错的工作而不只是可以工作的程度,那么我们就需要更加努力的去学习,掌握更多的前端相关知识。
学习前端想要更多的面试机会和更高的成功率,必须具备以下的东西:
第一阶段:HTML + CSS核心
前端初级语法,HTML常用标签、盒模型、CSS选择器集群、伪元素/伪类、浮动/定位、CSS3动画、CSS3过渡、CC3渐变、经典布局方案、2d/3d变换等。
第二阶段:JavaScript核心 + 高级
变量/内存、数据类型、条件语句、循环语句、函数/对象/数组、DOM/BOM对象、闭包/原型/作用域、JavaScript算法、JavaScript设计模式、高级函数/函数柯里化等内容。
第三阶段:jQuery框架 + Less + BootStrap
熟练掌握前端主流框架jQuery、BootStrap,了解jQuery优缺点、Less语法特点、Less同Stylus,Sass区别、BootStrap组件应用等内容。
第四阶段:NodeJs + 工程化
ECMAScript6新特性、JavaScript异步编程、Promise深入剖析、Promise源码实现、git/npm、axios/axios源码等相关内容。
第五阶段:Vue技术栈 + webApp + 项目部署
Vue核心基础、Vue指令/表达式/实例、Vue组件通信、Vue生命周期详解
Vue-router路由、Vuex状态管理 等相关内容。
第六阶段;React技术栈 + 工程化
React核心基、ReactJSX语法、React组件、React组件通信、React-router-dom路由、Redux等内容。
第七阶段:小程序技术栈 +服务器端框架
小程序核心语法、小程序路由、小程序生命周期、小程序WXML语法(遍历,条件判断等)、自定义组件、自定义模板等。
122. 买卖股票的最佳时机 II 给定一个数组 prices ,其中 prices[i] 是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
分析:
只要今天的值比昨天低 就贪。 class Solution { public: int maxProfit(vector<int>& prices) { int ans = 0; for (int i = 1; i < prices.
11
查看文件或者目录是否存在,经常用到-d,-e,-f,其中区别如下
-e filename 如果 filename存在,则为真
-d filename 如果 filename为目录,则为真
-f filename 如果 filename为常规文件,则为真
-L filename 如果 filename为符号链接,则为真
-r filename 如果 filename可读,则为真
-w filename 如果 filename可写,则为真
-x filename 如果 filename可执行,则为真
-s filename 如果文件长度不为0,则为真
-h filename 如果文件是软链接,则为真
filename1 -nt filename2 如果 filename1比 filename2新,则为真。
filename1 -ot filename2 如果 filename1比 filename2旧,则为真。
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
-a 与 and
-o 或 or
! 非
-z 字串为空/
导语 " 花草树木 皆有呈名
热爱自然,从认识自然开始 "
现在的植物爱好者,遇到不认得的植物。怎么办呢?源码基地在我主页(PC端)往期的源码都在,找我免费分享哈!
前几天去逛商场,一进商城一一一一门口的花店吸引了我的注意:摆放在店门口的各色鲜花植物花卉真的特别好看!
忍不住进门逛了一圈,发现我真的不认识,种类太多,对花卉的品种了解颇少。
回来之后找到了2款简单好用的植物识别APP一一一❀伴侣跟形色蛮好用的!
闲着也是闲着:默默用Python编写了一款简单的植物识别系统给大家正好la~
正文 1)环境安装 本文用到的环境:Python3.7 Pycharm社区版 模块:PyQt5。
2)主程序 import sys from PyQt5.QtWidgets import(QWidget,QApplication,QGridLayout,QLabel, QLineEdit,QTextEdit,QPushButton,QFrame,QFileDialog) from PyQt5.QtGui import QPixmap #导入baiduAPI调用模块 import request class AIGUI(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): #关于表格类的相关初始化代码 #setSpacing 就是设置每个控件的外边框 grid=QGridLayout() grid.setSpacing(10) #各个控件 #1号控件 explain=QLabel('请选择您要识别的图片') #2号 单号文本框 self.imgUrl=QLineEdit() #3号,按钮 self.select=QPushButton("选择图片") #为按钮添加一个事件处理函数 self.select.clicked.connect(self.openfile) #4号,图片框 self.imgLab=QLabel("11.png") self.imgLab.setFrameShape(QFrame.Box) #imgLab.setFrameShadow(QFrame.Raised) self.imgLab.setLineWidth(1) #imgLab.setPixmap(QPixmap("")) #5号,多行 self.info=QTextEdit() #将控件进行合理布局 grid.addWidget(explain,1,0) grid.addWidget(self.imgUrl,1,1) grid.addWidget(self.select,1,2) grid.addWidget(self.imgLab,2,0,5,3) grid.addWidget(self.info,1,3,6,1) #窗口最后的设置 self.setLayout(grid) self.
前言: 嵌入式开发过程中,我们会使用一些脚本工具辅助我们的工作,例如shel或者python、lua等,今天给大家分享一下,我在工作中用到的lua脚本交互使用。
作者:良知犹存
转载授权以及围观:欢迎关注微信公众号:羽林君
或者添加作者个人微信:become_me
情节介绍: 工作中, 因为我们的传感器需要出厂标定,所以我们需要有一个配置文件进行保存我们的传感器参数,这个文件支持读取和修改,实现这个功能有很多种方式,常规就是使用一个普通文件进行读写。
但是我考虑到,我们数据的复杂性,以及文件注释的描述,我选择了xml文件进行数据的保存,但是xml文件操作的库我又不想去自己写也不想去外部添加使用,本来就是一个小功能,没必要再去新增额外链接,使用别的xml操作库,所以我就盯上了我们激光slam建图算法里面用到的lua脚本,这个lua脚本的包本身以及在内核里面添加并在其他进程使用了,我只需要在我这边编译选项加 -llua动态链过去就可以多个进程一起使用了。
除了方便,也考虑到lua是一个轻量级的脚本,支持交互调用,比如说我们可以通过代码内部执行调用lua脚本函数,也可以在lua执行代码注册进去的函数。这个比shell和python有很多优势,shell只能在它脚本生成的终端去执行以及python也是类似,无法进行双方的函数交互调用。而lua可以交互调用,所以很方便。
lua介绍 Lua ,是巴西里约热内卢天主教大学里的一个研究小组于 1993 年开发的。是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua 特性
轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。
可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。
支持面向过程(procedure-oriented)编程和函数式编程(functional programming);
自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;
语言内置模式匹配;闭包(closure);函数也可以看做一个值;提供多线程(协同进程,并非操作系统所支持的线程)支持;
通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承和重载等。
Lua 应用场景
游戏开发、独立应用脚本、Web 应用脚本、扩展和数据库插件如:MySQL Proxy 和 MySQL WorkBench、安全系统,如入侵检测系统。
lua交互原理基础知识 lua和c++是通过一个虚拟栈来交互的。
c++调用lua实际上是:由c++先把数据放入栈中,由lua去栈中取数据,然后返回数据对应的值到栈顶,再由栈顶返回c++。
lua调c++也一样:先编写自己的c模块,然后注册函数到lua解释器中,然后由lua去调用这个模块的函数。
因为在我们设备上本来就有lua库,所以我开发时候直接就在CMakeLists.txt文件里面增加了 -llua,但是最开始在自己pc验证的时候,本机是没有相应的lua包的,还是下载了官网lua的源码进行编译之后,放到我的电脑指定目录进行操作验证的。
lua源码下载 去官网 http://www.lua.org/download.html 下载
make
make install
编译好的文件放到了以下三个目录
/usr/local/bin 解释器目录/usr/local/include 头文件目录/usr/local/lib 动态链接库目录 在后面我们进行本机测试代码时候,就可以加上绝对目录,进行头文件搜索和动态库链接了。
下面是我的一个demo测试的Makefile文件内容,其中就用了头文件目录和动态链接库目录。
OBJS = test_cpp_lua.o CFLAGS = -Wall -g -std=c++11 CC = gcc CPP = g++ INCLUDES +=-I /usr/local/include LIBS += -L /usr/local/lib -llua -ldl #LIBS = -ldl -llua target:${OBJS} # g++ -o target test_cpp_lua.
JDBC基础超详细(二)(PreparedStatement与Statement的区别,避免mysql注入)
源码奉上,大家和我一起操作,印象更加深刻
import java.sql.*; public class Javatell { public static void main(String []args){ Connection connection=null; Statement statement=null; ResultSet resultSet=null; //注册驱动 try { try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } //获取链接 String url="jdbc:mysql://localhost:3306/user"; String user="root"; String password="200101"; connection=DriverManager.getConnection(url,user,password); //获取数据库操作对象 statement=connection.createStatement(); //定义插入语句 String insertSql="insert into user_information values (4,'你好','123456')"; //定义更新语句 String updateSql="update user_information set user_name='王五' where user_name='李四'"; //定义删除语句 String deleteSql="delete from user_information where user_name='张三' "; //定义查询语句 String selectSql="select * from user_information "
目录 本教程优势环境步骤 本教程优势 1.亲测有效
2.操作简单,不用修改Makefile文件
3.官方wiki
环境 宿主机器:Ubuntu 20.04
目标机:树莓派4B armv7l
交叉编译链:gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf
步骤 1.下载源码
2.解压并进入源码根目录
3.运行配置脚本 指定参数,生成Makefile
参数解释:
./Configure --prefix=/home/yarnell/workspace/openssl-OpenSSL_1_0_2q/build/install --openssldir=/home/yarnell/workspace/openssl-OpenSSL_1_0_2q/build/config shared linux-generic32 --cross-compile-prefix=arm-linux-gnueabihf- # 参数解释(官方wiki:https://wiki.openssl.org/index.php/Compilation_and_Installation) --prefix:安装绝对路径 -openssldir:配置文件安装绝对路径 shared:生成动态链接库 --cross-compile-prefix:交叉编译器路径 4.编译
make 5.安装
make install
周六闲来无事,想到之前很容易对aspose.cell v21.4完成破解研究(见博客),但是对aspose.words没有完成破解分析。 这次换个思路,基于License进行class文件分析。
一:从官网下载 下载地址:Java Word Processor API | Aspose.Words for Java;
或者使用maven方式进行jar包下载:
<!-- maven配置 --> <repositories> <repository> <id>AsposeJavaAPI</id> <name>Aspose Java API</name> <url>https://repository.aspose.com/repo/</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.aspose</groupId> <artifactId>aspose-words</artifactId> <version>21.12</version> <type>pom</type> </dependency> </dependencies> 需注意:从官网下载的jar包为实时混淆,混淆的class名各不相同,因此本博客列出关键方法,但是方法名不保证一致。 二:License安装 见Licensing and Subscription | Documentation
关键代码:
com.aspose.words.License license = new com.aspose.words.License(); license.setLicense("path:\\Aspose.Words.Java.lic"); 给出License示例:
<License> <Data> <LicensedTo>Aspose Scotland Team</LicensedTo> <EmailTo>billy.lundie@aspose.com</EmailTo> <LicenseType>Developer OEM</LicenseType> <LicenseNote>Limited to 1 developer, unlimited physical locations</LicenseNote> <OrderID>140408052324</OrderID> <UserID>94236</UserID> <OEM>This is a redistributable license</OEM> <Products> <Product>Aspose.
git clone 整个仓库后使用,以下命令就可以取得该 tag 对应的代码了。
git checkout tag_name 但是,这时候 git 可能会提示你当前处于一个“detached HEAD" 状态。
因为 tag 相当于是一个快照,是不能更改它的代码的。
如果要在 tag 代码的基础上做修改,你需要一个分支:
git checkout -b branch_name tag_name 这样会从 tag 创建一个分支,然后就和普通的 git 操作一样了。
原文链接:https://blog.csdn.net/DinnerHowe/article/details/79082769
新版Android一直是谷歌I/O的重要组成部分,2019年也不例外。谷歌正在使安全、数字健康和创新成为Android Q的重要组成部分——但我们没有预料到谷歌在Android Q中构建了多少新的可访问性选项,作为其将移动技术带给尽可能多的人的努力的一部分。
通过人工智能的可访问性是贯穿整个主题的一个主要主题,但这一点从来没有比Android Q更明显。谷歌希望利用移动技术尽可能地丰富包括残疾人在内的更多人的生活。铁杆粉丝可能还记得谷歌几个月前推出了一款名为Live Transcribe的应用程序。这款应用就是这样做的——它会在附近监听语音,并将其转录到你的设备屏幕上。
谷歌在实时字幕上更进一步。只需轻轻一点,你的设备就能识别语音,并将其直接转录到屏幕上,而无需更换应用程序。内置在Android Q中,实时字幕将很容易通过音量摇杆访问,实时字幕使用谷歌的语音识别功能将字幕放到任何视频上——即使通常不会有字幕。最重要的是,对实时字幕的处理完全是在设备上完成的,因此不需要向云发送任何额外的数据,从而最大限度地减少移动数据的使用,并提高安全性。
现场转播是另一个要素,旨在帮助聋人谁需要在电话中发言,但无法通过任何其他方式。通过语音识别和文本到语音的转换,Live Relay充当了你和电话之间的中间人,记录通话内容,并向电话另一端的人发送语音信息。
Android Q也支持可折叠屏幕,以及对5G连接的本机支持。一个系统范围内的黑暗主题——一个期待已久的特性——也得到了证实。你也可以期待新操作系统在安全和隐私方面的提升。给用户控制权是谷歌的新移动操作系统的一个主题,用户很快就会得到内置的更强大的家长控制,以及注意力隐藏模式。
下一代谷歌助手即将问世如果没有谷歌助手,就不会有谷歌I/O的感觉。但我们得到的不仅仅是一些新功能或功能——相反,谷歌使用了2019年I/O的基调,让我们对它所谓的下一代谷歌助手有了一个很长的了解。
今年最大的变化之一是幕后,但同样令人印象深刻。谷歌一直在努力改变谷歌助手的工作方式,使其更快地做出反应,而它做到这一点的方法是将其缩小,并对所有的人工智能进行更改的处理是在设备上进行的,而不是被发送到云上进行处理。不再需要将数据发送到云上不仅使它更安全,还意味着它的数据效率更高。只有500MB,在更便宜的设备上也更容易使用。
但这仅仅是个开始。下一代谷歌Assistant将能够处理更多的任务,处理问题和答案的速度将提高10倍。继续对话意味着你不必一直说“嘿,谷歌”,助手甚至可以把其他应用程序的数据拉到当前任务前的气泡中——所以你不需要导航。
谷歌在线双工移动谷歌Duplex是去年I/O最大的创新之一,现在它不仅能处理电话。新的和改进的复式公寓可以填写你在网上找到的预订表格,包括租车的表格。和手机版的Duplex一样,它会要求你在预订完成之前确认它的选择,这样你就能确定它预订的东西是正确的。不过,它应该是准确的,因为它会从你的Gmail和之前的预订中提取信息,以了解你的偏好。今年晚些时候,网络上的Duplex将会出现。
驱动方式最后,谷歌正在扩大其在车内的供应。谷歌Assistant的新驾驶模式大概是为了补充新的Android Auto。通过说“让我们开车吧”启动它,仪表板会立即突出显示推荐的和个人行为的选择。它还将完全由语音控制,所以你永远不必把手从方向盘上拿开。
###NEST HUB MAX
抓住你的谷歌家庭迷你,因为谷歌家庭智能范围正在改变。谷歌将智能家居业务纳入Nest旗下。这意味着谷歌家庭集线器将成为Nest集线器——但更重要的是,谷歌还引入了家庭中的新成员Nest集线器Max。它本质上是Nest Hub的一个更大版本,内置一个摄像头和一个更大的显示屏。
Nest Hub Max将使用Duo进行视频通话,因此它可以呼叫安卓(Android)和iOS手机,如果你移动,智能摄像头就会跟随你的移动。安全性仍然是谷歌关注的焦点,因此如果您不知道集线器Max记录的是什么,那么它将永远不会记录。一个小的绿色LED总是会显示它的记录,而且它也很容易完全关闭摄像机。
就像其他谷歌家庭单元有语音匹配一样,Nest Hub Max将能够通过面部匹配识别你。Face Match允许Hub Max识别您,并在知道您在附近时显示个性化信息。如果它不认识人脸,它会立即通知你可能有陌生人在你家。
Nest Hub Max将以229美元的价格推出,而最初的Nest Hub也将降价至129美元。
将相机带到谷歌搜索,并改进了谷歌镜头
谷歌的首席执行官桑达尔·皮查伊(Sundar Pichai)在开幕致辞中强调了谷歌为其最古老、最常用的产品——谷歌搜索引擎添加了什么。很快,你就可以打开播客,更直接地从谷歌的搜索结果中打开——但最令人兴奋的是,你还可以在兼容AR的移动设备上直接从谷歌的图像搜索中访问AR内容。
谷歌也在改进谷歌镜头。谷歌Lens的新软件将能够自动突出餐馆菜单上的热门菜品,甚至向你展示它的样子,以及谷歌地图上的相关评论。它还能根据你的收据计算出适当的小费。谷歌也在考虑向谷歌镜头添加更多的AR内容,包括支持的烹饪书中的实时AR食谱。
谷歌Lens已经具备翻译文本的能力有一段时间了,但是谷歌还增加了将翻译文本读给您听的功能。对于视力受损的人尤其有用,这个功能已经在十多种语言中运行,包括英语、法语、西班牙语等等。该软件也被调整为非常小,所以它将适用于各种入门级手机,最便宜的35美元。
最后文末放上一个技术交流群:Android IOC架构设计
群内有许多技术大牛,有任何问题,欢迎广大网友一起来交流,群内还不定期免费分享高阶Android学习视频资料和面试资料包~
再推荐一篇文章:“寒冬未过”,阿里P9架构分享Android必备技术点,让你offer拿到手软!
“寒冬未过”,阿里P9架构分享Android必备技术点,让你offer拿到手软!]( )**
先上图,带你回到童年时光:
效果分析 子布局按照圆形顺序放置且平分角度
子布局旋转、支持手势滑动旋转、快速滑动抬手继续旋转、自动旋转
支持X轴旋转
支持前后缩放子布局(起始角度为前,相对位置为后,最前面最大,反而越小)
多个布局叠加时前面遮挡后面
效果难点问题 Flutter如何实现控件布局达到3D效果?Flutter如何实现子控件旋转、自动旋转、手势滑动时关联子控件旋转滚动?快速滑动抬手继续旋转滚动?Flutter如何实现多个布局叠加时前面遮挡后面? 1.子布局按照圆形顺序放置且平分角度 如上图所示:
如上图所示(参考系:最下方为0度,逆时针旋转角度增加)
第一个点 解:根据已知条件列方程式 x2=width/2+sin(a)*R y2=height/2+cos(a)*R 第二个点 解:根据已知条件列方程式① ① x=width/2-sin(b)*R y=height/2-cos(b)*R 因为b=a-180,所以带入①方程得: ② x=width/2-sin(a-180)*R y=height/2-cos(a-180)*R 又因为sin(k*360+a)=sin(a),所以②方式可以修改为: ③ x=width/2-sin(180+a)*R y=height/2-cos(180+a)*R 又又因为 sin(180+a)=-sin(a),cos(180+a)=-cosa 带入③方程式得: ④ x=width/2+sin(a)*R y=height/2+cos(a)*R 由上面2点计算得,每个子布局的中心点坐标公式统一为: x=width/2+sin(a)*R y=height/2+cos(a)*R 以上所用三角函数公式表:
通过上面计算得出子控件的位置公式后,开始我们的代码。
实现子控件按照圆形布局及平分角度代码如下:
//所有子控件的位置数据 //count:子控件数量; //startAngle:开始角度默认为0; //rotateAngle:偏转角度默认为0; List<Point> _childPointList({Size size = Size.zero}) { List<Point> childPointList = []; double averageAngle = 360 / count; double radius = size.width / 2 - childWidth / 2; for (int i = 0; i < count; i++) { /********************子布局角度*****************/ double angle = startAngle + averageAngle * i + rotateAngle; //子布局中心点坐标 var centerX = size.
1158又是排序(指针专题)
题目描述
将输入的四个整数按由大到小的顺序输出。
请你定义一个四个数排序的函数psort,psort的四个参数为要排序的四个整数变量的地址,请你按照从大到小的顺序把四个数分别放到四个指针所指向的变量里,不要在函数内输入输出任何内容。请务必使用函数实现四个数的排序。
void psort( int *pa, int *pb,int *pc,int *pd)
{
//实现四个数的排序,并分别放到四个指针所指向的变量里。
}
注意:本题如果采用C/C++提交时,至少要编写psort()函数和main()函数两个函数,并提交完整的程序代码。
输入
输入4个整数,用空格隔开。
输出
输出排序后的4个整数,由空格隔开。输出占一行。
样例输入 Copy
4 3 5 2
样例输出 Copy
5 4 3 2
#include <stdio.h> #include <stdlib.h> void psort( int *pa, int *pb,int *pc,int *pd); int main() { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); psort(&a,&b,&c,&d); printf("%d %d %d %d",d,c,b,a); return 0; } void psort( int *pa, int *pb,int *pc,int *pd) { int a; if(*pa>*pb)//4个数两两比较得到*pa<*pb<*pc<*pd就行了; { a=*pa; *pa=*pb; *pb=a; } if(*pa>*pc) { a=*pa; *pa=*pc; *pc=a; } if(*pa>*pd) { a=*pa; *pa=*pd; *pd=a; } if(*pb>*pc) { a=*pb; *pb=*pc; *pc=a; } if(*pb>*pd) { a=*pb; *pb=*pd; *pd=a; } if(*pc>*pd) { a=*pc; *pc=*pd; *pd=a; } } 1159最大的两个数(指针专题)
报错信息
源代码:
解决方法:
使用lean()
lean()方法描述:
告诉mongoose返回的是普通对象,而不是mongoose文档对象,方法内部先用JSON.stringify()这个方法将文档对象转换为字符串,将其他的属性格式全部去掉,然后只留下需要的数据字符串
成功显示数据:
package com.hgh.javase.security; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.Certificate; import java.util.Enumeration; public class ReadPFX { public ReadPFX (){ } //转换成十六进制字符串 public static String Byte2String(byte[] b) { String hs=""; String stmp=""; for (int n=0;n<b.length;n++) { stmp=(java.lang.Integer.toHexString(b[n] & 0XFF)); if (stmp.length()==1) hs=hs+"0"+stmp; else hs=hs+stmp; //if (n<b.length-1) hs=hs+":"; } return hs.toUpperCase(); } public static byte[] StringToByte(int number) { int temp = number; byte[] b=new byte[4]; for (int i=b.length-1;i>-1;i--){ b[i] = new Integer(temp&0xff).
前言
伴随硬件性能和网络带宽的提升,终端部署的三维实时渲染,VR,AR等高计算,高数据量的服务也逐步可实现集中部署或云端部署。如云游戏,智慧园区中的数字孪生,智慧城市中的数据可视化,智慧教育中的三维可视化课程。云端部署一方面有利于简化终端配置要求,另外一方面可以更方便的实现内容管理,版权保护等。
云游戏,数字孪生等应用场景中,实现云端部署的核心技术要求是必须做到在保证视频质量的前提下必须做到低延时。与传统的单项直播或者点播不同,该场景下伴随着操作交互。如云游戏中,视频画面必须快速伴随终端设备的操作做出调整(如终端鼠标,键盘操作切换视角)。最近公司做了一个三维实时编码传输模块,下面描述下具体需求和实现。
参数要求
视频:分辨率可支持720P/1080/2K/4K,帧率25/30/60fps,根据硬件配置和项目需求可选
视频编码格式:H.264,H.265
码率:可调(1-10M)
开启:秒开
全流程延时:<100ms(含编码 传输 解码)
架构:B/S, C/S可选
操作系统:Windows 和 Linux
方案
因为公司有行业领先的RTC实时低延时传输技术,因此对我们来讲关键是视频编码部分。因为三维图像实时渲染一般通过GPU实现,因此视频编码选择GPU编码,这样可以节省硬件投资。
GPU视频编码
图像和视频类算法的特性是数据量大,分块化,可并行。这种算法用通用CPU计算效率低,成本高,却特别适合硬件模块化,计算并行化。最早期的视频编码芯片(如TI)是将视频编码算法的部分硬件化(如运动估计,运动补偿,熵编码),整个算法的实现还需开发人员排流水,实现并行化。当前视频编码一般直接调用硬件厂商提供的接口即可。当然如果想根据自身应用特点对调整相应编码器参数,就需要对视频编码算法本身有一定的了解。
英伟达GPU 视频编码
首先需要对英伟达GPU架构做基本了解,同时对选择的GPU编码性能做一定评估。可以在英伟达相关网站查询了解相关信息。NVIDIA VIDEO CODEC SDK | NVIDIA Developer;Video Encode and Decode GPU Support Matrix [NEW] | NVIDIA Developer;
根据上图可以对GPU编码架构有整体认识,GPU编码单元与其他单元的关系
然后通过上图判断选择的GPU属于那个系列,具有多少个视频编码单元,编码路数是否有限制。
通过上图可以看下GPU对应型号在不同模式下的编码性能。
根据上图可以判断选择的GPU编码性能
最后根据需求或客户选定的GPU型号,对GPU视频能力有大致判断。
实现
实现上不做详细描述了,参考NVIDIA VIDEO CODEC SDK。
视频编码参数根据网络环境 服务器配置 客户需求进行相应调整。
传输上需要采用低延时传输算法,传统的流媒体传输算法无法满足。
最终实现低延时三维实时传输互动视频
首先
安装下animate.css
npm install animate.css --save 然后在vue文件的script中引入:
import $ from '../assets/js/jquery.js';//非必要 import animate from 'animate.css' 代码例子:
<template> <div> <button @click="isShow = !isShow">显示/隐藏</button> <transition-group appear name="animate__animated animate__bounce" enter-active-class="animate__bounceInLeft" leave-active-class="animate__animate__backOutRight" > <h1 v-show="!isShow" key="1">你好啊!</h1> <h1 v-show="isShow" key="2">无忧!</h1> </transition-group> </div> </template> <script> //引入animate.css import 'animate.css' export default { name:'Test', data() { return { isShow:true } }, } </script> <style scoped> h1{ background-color: orange; } </style> 注意点 这里name="animate__animated animate__bounce"是animate默认的,其中animate__animated是默认的,后面是animate__+动画风格
以下是animate.css官网给的动画风格和具体的动画效果,具体的可以去官网看
animate.css官网
##Attention seekers 动画风格 bounce flash pulse rubberBand shakeX shakeY headShake swing tada wobble jello heartBeat ##Back entrances backInDown backInLeft backInRight backInUp ##Back exits backOutDown backOutLeft backOutRight backOutUp ##Bouncing entrances bounceIn bounceInDown bounceInLeft bounceInRight bounceInUp ##Bouncing exits bounceOut bounceOutDown bounceOutLeft bounceOutRight bounceOutUp ##Fading entrances fadeIn fadeInDown fadeInDownBig fadeInLeft fadeInLeftBig fadeInRight fadeInRightBig fadeInUp fadeInUpBig fadeInTopLeft fadeInTopRight fadeInBottomLeft fadeInBottomRight ##Fading exits fadeOut fadeOutDown fadeOutDownBig fadeOutLeft fadeOutLeftBig fadeOutRight fadeOutRightBig fadeOutUp fadeOutUpBig fadeOutTopLeft fadeOutTopRight fadeOutBottomRight fadeOutBottomLeft ##Flippers flip flipInX flipInY flipOutX flipOutY ##Lightspeed lightSpeedInRight lightSpeedInLeft lightSpeedOutRight lightSpeedOutLeft ##Rotating entrances rotateIn rotateInDownLeft rotateInDownRight rotateInUpLeft rotateInUpRight ##Rotating exits rotateOut rotateOutDownLeft rotateOutDownRight rotateOutUpLeft rotateOutUpRight ##Specials hinge jackInTheBox rollIn rollOut ##Zooming entrances zoomIn zoomInDown zoomInLeft zoomInRight zoomInUp ##Zooming exits zoomOut zoomOutDown zoomOutLeft zoomOutRight zoomOutUp ##Sliding entrances slideInDown slideInLeft slideInRight slideInUp ##Sliding exits slideOutDown slideOutLeft slideOutRight slideOutUp ##Copy class name to clipboard https://animate.
🎉前言 学习算法肯定不是一条坦途,正如人生的奋斗之路也是异常曲折的,一个多月的摸爬滚打,也终于让我跨入了算法的大门,希望我这一个多月的一点经验积累能对初入算法之门的同学们,起到一点帮助。然而我的个人总结难免有些偏颇且局限,希望读者不吝赐教。
如果觉得一个人难以坚持,不妨加入万人千题打卡社区。百人打卡,你怎么会甘心懈怠呢? 万人千题打卡社区https://bbs.csdn.net/forums/hero?category=0
🐱💻作者概况: 就读南京邮电大学努力学习的大一小伙
🐱🐉联系方式:2879377052(QQ小号)
📚资源分享:《算法竞赛入门经典》 (30天有效) 🐱👤LeetCode主页:Leetcode 目录 一、案例分析
二、算法详解
三、算法模板
四、实战演练
五、课后练习
一、案例分析 【案例】调整数组使奇数全部都位于偶数前面
【分析】这个问题当然也有很多种解法,但能否只遍历一次数组就满足题目要求呢?我们可以试试双指针——一种简单却实用的方法。
二、算法详解 >: 什么是双指针法?
双指针法:一般是指的在遍历对象的过程中,不是使用单个指针进行访问,而是使用两个相同方向或者相反方向的指针进行扫描,从而达到相应的目的。
一般双指针法有两种表现方式:
同向移动:在同向移动时,指针移动有快慢之分。相向移动:在相向移动中,双指针一个指针在开头,另外一个指针在结尾,向中间逼近。 回到本题,我们可以采用相向移动的双指针,不妨分别定义为 left 和 right。我们通过双指针实现下面的功能:left指针左边的都是奇数,right指针右边的都是偶数。来看看下面的代码体悟一下吧,读代码的能力也是很重要的。这里就呈现核心代码。
void move(int* arr , int n) { int* left = arr; int* right = arr + n - 1; while (left < right)//(1) { while (left < right && *left % 2 == 1)//(2) left++; while (left < right && *right % 2 == 0)//(3) right--; if (left < right)//(4) { int tmp = *left; *left = *right; *right = tmp; } left++; right--; } } (1)左右指针相遇之前说明之间还有数没有被查找过,所以循环继续(2)左指针所指向的数为奇数时,则不需要交换继续查找。注意条件left<right,否则可能越界(3)右指针同理,只是找到奇数时才停止查找(4)当左右指针还没相遇时才需要交换 三、算法模板 void move(int* arr , int n) { int* left = arr; int* right = arr + n - 1; while (left < right) { while (left < right && XXXX) left++; while (left < right && XXXX) right--; if (left < right) { int tmp = *left; *left = *right; *right = tmp; } left++; right--; } } 四、实战演练 温馨提示:Leetcode是接口型的OJ平台,只要封装一个函数实现对应功能就可以了,不需要主函数。可以尝试先点击蓝色链接写题目,写不出来再看分析。