|
Batteriepolabdeckung Renault Scenic II – Warum verlegen Werkstätten ständig Dinge?
-
autotagebuch.net
-
2 years ago
-
deu
Nachdem ich letzten Monat die Federn hinten sowie einen ABS-Sensor getauscht hatte, um den Renault Scenic II wieder fit für die Hauptuntersuchung zu machen, probierte ich letzte Woche mein Glück. Bemängelt wurde allerdings die fehlende Batteriepolabdeckung und ein bis zwei andere Kleinigkeiten. Entsprechend beschaffte ich eine Ersatz-Batteriepolabdeckung für insgesamt 14,99€ inklusive Versand. Viel Geld für […] The post Batteriepolabdeck..
|
|
Batteriepolabdeckung Renault Scenic II – Warum verlegen Werkstätten ständig Dinge?
-
autotagebuch.net
-
2 years ago
-
deu
Nachdem ich letzten Monat die Federn hinten sowie einen ABS-Sensor getauscht hatte, um den Renault Scenic II wieder fit für die Hauptuntersuchung zu machen, probierte ich letzte Woche mein Glück. Bemängelt wurde allerdings die fehlende Batteriepolabdeckung und ein bis zwei andere Kleinigkeiten. Entsprechend beschaffte ich eine Ersatz-Batteriepolabdeckung für insgesamt 14,99€ inklusive Versand. Viel Geld für […] The post Batteriepolabdeck..
|
|
要么说 Compose 优雅呢,假如你想画个东西,用安卓 View 的话你要继承 View 并且实现其中的 onDraw 方法,然后才能拿到 Canvas 开始绘制,但 Compose 你只需要这样: Canvas ( modifier = Modifier . size ( 100 . dp )) { // draw in DrawScope } 非常的自然,没有比这个更自然的事情了。 先看下效果图吧。 贝塞尔曲线 贝塞尔曲线相关的科普网上有非常多的文章,这里就不详细介绍了,本文主要内容是如何通过 Compose 绘制上面样式的贝塞尔曲线趋势图。 首先简单回顾一下贝塞尔曲线,贝塞尔曲线一般分为一阶贝塞尔曲线(直线),二阶、三阶等更高阶的贝塞尔曲线,通过设置不同的控制点我们可以得到几乎所有类型的曲线。 我们可以通过这个特性绘制出一些很优美的曲线出来。 同样 Compose 的 Canva....
|
|
虽然 Android 提供了 CollapsingToolbarLayout,但是 Compose 并没有这个组件,好在 Compose 实现起来并不困难,借助 Compose 嵌套滚动的 Api 可以轻易实现,先看下效果图。 在开始实现之前,需要先了解下 NestedScrollConnection 。 NestedScrollConnection 这是 Compose 嵌套滚动系统提供的 Api,通过它可以参与嵌套滚动事件的处理。 主要包含了以下几个方法: /** * Pre scroll event chain. Called by children to allow parents to consume a portion of a drag * event beforehand * * @param available the delta available to consume for pre scroll * @param s....
|
|
亲手封装一个简单灵活的下拉刷新上拉加载 Compose Layout Compose 的下拉刷新有现成的 Material 库 可以直接使用,非常简单方便。 但是上拉加载目前没看到有封装的特别好的库,Paging 有些场景无法满足,而且上拉加载也是个比较简单的功能,没必要再去依赖一个质量未知的库。我们可以基于目前的 LazyList 简单的封装一个灵活的组件。 基本原则是仍然基于现有的 PullRefresh 以及 LazyList API 实现,不依赖三方库,使用简单灵活好用。 接口设计 首先我们将这个可以上拉加载下拉刷新的 Compose 函数命名为 LoadableLazyColumn。 上面说到我们需要基于 PullRefresh 以及 LazyList API 实现,这两个组件都具备各自的 State。 PullRefreshState :下拉刷新的 State LazyListState :LazyColumn 的 State 由于我们....
|
|
MVI MVI 架构核心思想是 单一可信数据源 。 ViewModel 中需要维护着一个 UiState ( 一般来说会是个 data class ),这个 UiState 包含了 UI 层所需要的所有数据,或者说描述了 UI 层的所有状态,同时这个 UiState 应该具备通知观察者更新的能力,例如使用 **StateFlow**。 UI 层应该仅通过该 UiState 渲染。那么对于这个页面的 Composable 函数来说,入参中表示数据的部分应该只有一个 UiState。 fun NavGraphBuilder . registerLoginPage ( navController : NavController ){ composable ( "login" ){ val viewModel : LoginViewModel = viewModel () val uiState ....
|
Gestern habe ich bei unserem Renault Scenic II die hinteren Federn getauscht, da diese am unteren Ende auf einer Seite einfach und auf der anderen zweifach gebrochen waren. Unser Scenic ist mit der HU dran, daher musste das erledigt werden. Der Tausch wird in folgendem Autodoc-Tutorial auf YouTube hinreichend behandelt, daher werde ich keine Schritte […] The post Fahrwerksfedern (hinten) am Renault Scenic II tauschen appeared first on ..
|
|
Gestern habe ich bei unserem Renault Scenic II die hinteren Federn getauscht, da diese am unteren Ende auf einer Seite einfach und auf der anderen zweifach gebrochen waren. Unser Scenic ist mit der HU dran, daher musste das erledigt werden. Der Tausch wird in folgendem Autodoc-Tutorial auf YouTube hinreichend behandelt, daher werde ich keine Schritte […] The post Fahrwerksfedern (hinten) am Renault Scenic II tauschen appeared first on ..
|
|
Filt 是 Fill+Hilt 的意思,用于简化在使用 Hilt 时注入接口所有的实现类的操作。 我先介绍下需求背景,首先需求上会对某一类事物与行为做一些统一的抽象,这些抽象被放在了一个单独的模块,app 层直接依赖这个模块并使用其中的实体与 UseCase,这个抽象层会包含多个实现,每个实现也都是单独的模块,这些模块必然需要依赖抽象层模块(类似于插件化架构),并实现其中的实体与 UseCase,app 层通过 runtimeOnly 的方式依赖了这些具体的实现模块,且抽象层不会依赖这些实现层。 那么抽象层就需要通过一些手段获取运行时接口的所有实现,一般来说我们通过 ServiceLoader 获取即可,但是 ServiceLoader 无法支持依赖注入,Hilt 虽然提供了获取接口所有实现的注入方式但使用起来非常麻烦,鉴于整体架构设计会导致出现很多类似的工作,所以考虑通过 KSP 自动生成 Hilt 所需要的相关代码,简化该场景的使用。 使用 Hilt @Int....
|
|
人工智能简要发展史 达特茅斯会议 达特茅斯会议是公认的人工智能成为一个新的研究领域的开端。 1955年夏天,麦卡锡去 IBM 做临时工,当时他的老板是纳撒尼尔·罗切斯特(Nathaniel Rochester,1919—2001),他是IBM公司信息中心的主任,也是第一代通用的商用计算机“IBM 701”的主设计师。 两人都对机器智能感兴趣,于是决定发起一场与机器和智能领域有关的活动,并且给出了如下七个明确的讨论范围: 自动计算机:所谓“自动”指的是可编程的计算。 编程语言:这里并不同于今天的Java、C、C++等编程语言,而是“如何为计算机编程使其能够使用人类语言”的意思。 神经网络。 计算规模理论(Theory of Size of a Calculation):这个议题说的是如何衡量计算设备和计算方法的复杂性。 自我改进:这个议题就是说机器学习。 抽象概念:令计算机可以理解和存储那些人类可以轻易判别,但是难以精确定义的概念。 随机性和创造性。 人工智能....
|
|
My grandfather G William Wiersdorf passed away Monday morning. He was 82 and survived COVID, a decades-long existence with MS , and World War II. While his health wasn't the best, none of us were expecting this. You can read his obituary here . German obituary UPDATE 2023-03-18: I've translated my grandpa's obituary into German. Here it is: G William "Bill" Wiersdorf verstarb friedlich am 13. März 2023 mit seiner liebevollen F....
|
|
在 Kotlin 协程以前我们在使用 Retrofit 的时候一般会结合 RxJava 一起使用,通过 Single 来表示一个已经创建的请求。 @GET ( "/info" ) fun requestUserInfo (): Single < BaseEntry < UserInfo >> .. . api . requestUserInfo () . subscribeOn ( Schedulers . io ()) . observeOn ( AndroidSchedulers . mainThread ()) . subscribe ({ //... },{ //... }) Single 在 RxJava 中表示只包含一个事件的流,所以用它来充当网络请求也是相对合理的。 不过既然是 HTTP 网络请求,那么返回值肯定是只有一次或者....
|
|
用 Compose 做了个开源的轻量级的 Notion 客户端 NotionLight,现已上架 Google Play。
-
0xzhangke.github.io
-
3 years ago
-
deu
迫于 Notion 的客户端比较慢,而且操作路径有点长,如果想当做快速笔记或者 TODO 来用还是不太够。 正好前段时间因为疫情在家待了三个月没出门,打算学学 Compose,所以顺便 :) 用 Notion 的 API 卷了个简单快速的客户端出来。 既然是当做快速笔记以及 TODO 来用,那内容的组织形式就是按照列表来的,会把 Notion 中的每个能被识别的内容块映射成列表中一个条目展开显示。每个 Notion 页面对应 NotionLight 中的一个 TAB。授权后自己选择将 Notion 中的对应的页面添加进来。 目前支持对内容快的添加、修改及删除操作,也支持 Android Shortcut 快速添加内容,可以说非常快速了。 主要技术栈:Compose+Kotlin+Coroutines+Retrofit. Google Play: https://play.google.com/store/apps/details?id=com.zhang..
|
|
最近准备做一些 RSS 相关的工作,但是发现除了 RSS 协议之外官方还提供了个 Atom 协议,算是继承自 RSS 并且进行了一些扩展,相对要比 RSS 复杂很多,而网上也没找到中文资料,阅读文档的时候就想着看都看了,那就顺便(并不)翻译成中文吧。 1. 介绍 Atom 是一种基于 XML 的文档格式,主要用于描述 Feed 相关的信息列表。 Feeds 流由很多 entries(条目)组成,每个条目都包含一组可扩展的附加元数据,例如标题等等。 1.1 实例 一个简短的单项 Atom Feed 文档:
|
|
I reinstalled Windows this month. As usual, it was a pretty arduous process, so let’s document what I did to make it suck less next time!
|
|
摘要 本文准主要介绍计算机这门学科的理论发展史,从计算机理论模型的设想开始到通用计算机的实现,以及关于下一代计算机的思考。笔者一直认为不管是学习什么学科,其发展史都是非常有必要的,只有了解了这个学科从零开始发展到现在的过程,才能对整体有更深刻的理解。另外本文也不会涉及太多硬件方面迭代发展的描述。 引言 我们都知道现代通用计算机的理论计算模型是图灵机,图灵被称为计算机之父,关于图灵本人也流传了很多故事,比如二战时期发明解码机破解了德军的通讯密码,这还被拍成了电影《模仿游戏》;还有他关于对人工智能的定义,能通过图灵测试的才算是真正的人工智能;以及他由于性取向问题导致最终咬了一口带毒的苹果而自杀,甚至传言 Apple 的 Logo 就源于此。 而直到 2013 年英国女王才宣布赦免早已去世的图灵,据说 2021 年英国的 50 英镑钞票上将会印上图灵的照片。但实际上图灵机最初发明的目的跟计算机并没有任何关系,只是为了解决一个困扰当时数学家们很久的一个问题:希尔伯特的判定问....
|
|
HashMap HashMap 实现了 Map 接口,用于存储键值对,与 Hashtable 不同的是,HashMap 允许 null 元素 。 HashMap 具有两个性能相关的参数: 初始容量( initial capacity ) 和 负载因子( load factor ) , 容量是指 HashMap 桶( buckets ) 的容量,初始容量即 HashMap 在创建时桶的默认大小。 负载因子默认是 0.75 ,默认初始容量是 16 ,初始容量如果设置过大会导致遍历时间变长,但可以降低 resize 的次数,需要结合场景自己权衡。 在容量达到阈值后会进行扩容,扩容后容量为当前的 两倍 。 另外设置的初始容量并不代表实际数组的初始大小,而是会根据设定值找到一个最近的 2 的次幂 当做初始容量。而因为每次扩容都是两倍,所以也保证了数组长度一直是 2 的次幂 。 HashMap 是 非线程安全 的,可以通过 Collections 类获....
|
|
Hashtable Hashtable 实现了 Map 接口,用于存储键值对, 禁止 null 元素 。 用作键的对象必须保证hashCode与equals的可用性。 Hashtable 是 线程安全 的,但一般来说,如果不需要考虑线程安全问题可以使用 HashMap 作为替代,如果需要线程安全的高并发哈希表可以使用 ConcurrentHashMap ,总的来说就是,一般不需要使用 HashTable。 Hashtable 具有两个性能相关的参数: 初始容量( initial capacity ) 和 负载因子( load factor ) , 容量是指 HashTable 桶( buckets ) 的容量,初始容量即 HashTable 在创建时桶的默认大小。在哈希冲突的情况下,每个桶会通过 链表 存储多条数据。 负载因子默认是 0.75 ,一般来说该值是最佳值。 当 HashTable 容量超出负载因子时将会进行 rehash 操作,该....
|
|
LinkedBlockingDeque LinkedBlockingDeque 是基于 链表 的 双端阻塞队列 , 线程安全 ,元素不允许为 null。 空间容量最大一般为Integer.MAX_VALUE,如果构造器中指定了最大值则队列长度将会被限制在该值以下。 大部分方法都以固定时间运行,批量操作,例如:remove, removeFirstOccurrence,removeLastOccurrence,contains,iterator.remove(),将以线性时间运行。 LinkedBlockingDeque 是 阻塞队列 ,是指对于一些指定的操作,在插入或者获取队列元素时如果队列状态不允许该操作可能会阻塞住该线程直到队列状态变更为允许操作,这里的阻塞一般有两种情况。 第一种是插入元素时,如果当前队列已满将会进入阻塞状态,一直等到队列有空的位置时再讲该元素插入,该操作可以通过设置超时参数,超时后返回 false 表示操作失败,也可以不设置超时参数一直....
|
|
ConcurrentLinkedDeque ConcurrentLinkedDeque 是基于 链表 的 无限双端队列 , 线程安全 ,不允许 null 元素。 ConcurrentLinkedDeque 内部通过 CAS 来实现线程同步,一般来说,如果需要使用线程安全的双端队列,那么推荐使用该类。 由于双端队列的特性,该类同样可以当做 栈 来使用,所以如果需要在并发环境下使用栈,也可以使用该类。 迭代器设计为 弱一致性 的(weakly consistent),此外还可以通过descendingIterator方法获取一个通过相反方向遍历的迭代器。 虽然跟 LinkedList 一样都是双端队列的链表实现,但由于其并发特性,导致无法简单点的通过计数来确定队列的长度,所以size方法将会 以线性时间 运行,并且如果在执行期间被其它线程修改可能返回 不准确的结果 。 对于批量操作,例如:addAll,removeAll,retainAll,containsA....
|
|
ArrayDeque ArrayDeque 是 Java 集合中 双端队列 的 数组实现 ,双端队列的链表实现( LinkedList )我们在前几篇文章中讲过了。 ArrayDeque 几乎没有容量限制,设计为 线程不安全的 , 禁止 null 元素 。 ArrayDeque 作为 栈 使用时 比 Stack 类效率要高 ,作为 队列 使用时 比 LinkedList 要快 。 ArrayDeque 大多数的额操作都在 固定时间 内运行,例外情况包括 remove,removeFirstOccurrence,removeLastOccurrence,contains,iterator.remove(),和批量操作,这些将以 线性时间 运行。 iterator同样也被设计为 fail-fast 。 方法 ArrayDeque 作为 队列(FIFO) 使用时的方法: 队列方法 等效的双端队列方法 add(e) addLast(e) ....
|
|
CopyOnWriteArrayList 先看看百科上关于 COW 的介绍 : 写入时复制(英语:Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时请求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。 简单来说,就是读取时直接读取不用加锁同步,写入数据时会 复制一份副本 ,然后将新的数据写入到副本中,然后再把副本替换成原来的数据。 因此 CopyOnWriteArrayList 是 线程安全 的,另外也允....
|
|
List 先看下 ArrayList 实现的接口 List 的相关概念。 List 可以称为有序集合或者序列,通过整数索引访问元素 允许插入相同元素 一般来说也允许插入 null 值 List 接口中还提供了一个特殊的迭代器:ListIterator ListIterator ListIterator 专门为了 List 打造,在 Iterator 基础上还提供了插入和替换元素以及双向访问的功能。 我们来看下使用: List < String > list = new ArrayList <>(); list . add ( "1" ); list . add ( "2" ); list . add ( "7" ); list . add ( "4" ); ListIterator < String > iterator = list . listIte....
|
|
LinkedList 实现了 List 以及 Deque 的 双向链表 ,元素允许为 null,所以 LinkedList 同时具备 List 以及 Deque 的特性。 跟 ArrayList 一样,LinkedList 也是 非线程安全 的,可以使用包装方法获取同步对象: List list = Collections . synchronizedList ( new LinkedList (...)); iterator以及listIterator同样也被设计为 fail-fast 。 使用特性 LinkedList 内部实现上是个 链表 ,所以可以把它当作 链表 使用。 LinkedList 同样还可以代替 Stack 类当做 栈 来使用(官方也推荐这么做)。 但不合适作为 List 使用,List 相关的方法会比较耗时,性能低。 链表和栈相关的操作基本都可以在 固定时间 内完成,但是 Li....
|
|
Last week I installed VSCode for the first time, after using exclusively SublimeText for about two years (and Notepad++ prior to that). I’m going to document my learning curve.
|
|
好久没写博客了,最近比较忙,在系统学习一些知识,没学完之前不太容易输出高质量文章,等过段时间学完了再整理一下写几篇文章出来。 但中间也在用零碎的时间学学别的,今天写总结一下回溯法。 概念 回溯法 作为一种搜索算法,可以找出所有或一部分解的一般性算法,尤其适用于约束满足问题,例如今天要讲的N皇后、解数独等等。 回溯法采用 试错 的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的 递归 方法来实现,在反复重复上述的步骤后可能出现两种情况: 找到一个可能存在的正确的答案 在尝试了所有可能的分步方法后宣告该问题没有答案 在最坏的情况下,回溯法会导致一次复杂度为指数时间的计算。 回溯法实际上是一种 DFS(深度优先搜索算法)的一种,不同的是,回溯法具备剪枝的能力,下面通过两个例子来具体分析回....
|
|
基本概念 APT 全称为 Annotation Processing Tool ,可翻译为注解处理器,APT 工具是用于注解处理的命令行程序,它可以找到源码中对应注解的对象并使用注解处理器对其进行处理。 一般来说,我们会使用 APT 生成一些源码,然后加入编译目录进行编译,从而简化开发周期。 注解 注解处理器是基于注解(Annotation)的,实际开发中自定义注解用的比较少,这里先简单的复习下相关概念。 Java 注解是 Java1.5 中引入的概念,是用来标注代码的元数据。 定义一个注解 定义一个注解使用 @interface 关键字。 public @interface Test {} 对,这样一个名为 Test 的注解就定义好了。 元注解 元注解是注解的注解,用来标注注解的元数据。 可以通过元注解来控制注解的一些属性与行为。 Java 中元注解共有四种:Retention、Inherited、Documented、Targ....
|
|
关于 Gradle 中的基础、Task 等知识,可以看我的 上一篇文章 。 Gradle 中的依赖 Gradle 中的依赖可以分为脚本文件依赖、插件依赖以及包依赖。 脚本文件依赖 随着项目结构的复杂,一个 build.gradle 已经无法满足我们的需求了,尤其是对依赖库版本的配置,如果多个 project 都需要用到某个依赖库,稍有不慎版本就会错乱,从而引发一些问题。 此时我们期望可以把所有用到的依赖库版本都配置在同一个文件中,build.gradle 使用这个文件中的版本来依赖相应的版本,Gradle 提供了 apply 方法来依赖其他文件。 apply from: 'config.gradle' 我们可以在 build.gradle 文件中添加上述代码来依赖 config.gradle 文件,这样就可以把这个文件中的设置应用到对应的 Project 中去, 包括其中的 Task 。 插件依赖 插件依赖是指依赖 编译插件 ,最常见的是我们....
|
|
Gradle 是用于构建项目的工具,除了管理依赖库之外,Gradle 还支持我们自己添加编译脚本、添加编译配置等控制项目的构建,通过提供 API 我们可以控制编译的每一步操作。 Gradle 目前使用最广泛的是 Android 项目的构建 ,几年前 Google 推出 Android Studio 的同时也把它也推选为默认的构建工具,因此我们也经历了从 Maven 到 Gradle 这一痛苦的转变过程,每天对着满屏的编译失败信息怀疑人生。 实际上 Gradle 也确实对开发者很不友好,用 Gradle 你能遇到各种各样的问题,版本混乱到无以复加,互相还不兼容,甚至对 Android Studio 都有版本要求。不过几乎所有的问题都能 Google 到答案,而我们也能看到确实在逐渐变好。 关于 Gradle 中的依赖与自定义插件,可以点此看我的 下一篇文章 。 Gradle 基本原理 我们知道 Gradle 是一种以 Groovy 语言 为基础的 自动化构....
|
|
流程分析 我们从一个简单的 HTTP 请求开始: client = new OkHttpClient (); Request request = new Request . Builder (). url ( "your url" ). build (); //同步发起请求 Response syncResponse = client . newCall ( request ). execute (); //异步发起请求 client . newCall ( request ). enqueue ( new Callback () { @Override public void onFailure ( @NotNull Call call , @NotNull IOException e ) { ....
|