以下哪些属于Java的三大特性:
a. 抽象 b. 封装 c. 面向对象 d. 分布式 e. 安全性 f. 平台独立
以下哪些是Object的公用方法?
a. equals() b. getContext() c. notify() d. toString() e. clone()
int和integer两个谁更占用内存?
a. Int b. integer
“a == b” 和 “a.equals(b)” 是否有区别?
a. Yes b. No
以下关于ArrayList的说法正确的是?
a. 有序 b. 无序 c. 元素能重复 d. 元素不能重复 e. 查询快 f. 增删快
目前市面上最新Android版本: Android 12 ,对应SDK版本为: API Level 31
Android四大组件(英语):
Activity
Service
Broadcast Receiver
Content Provider
Android 广播的分类:
Standard Broadcasts(标准广播)、Ordered Broadcasts(有序广播)、Sticky Broadcasts(粘性广播)、Local Broadcast(本地广播)
请列举Android进程间通讯的几种方式:
Binder(AIDL)
:Android 的主要进程间通讯机制,基于内核的 Binder 驱动进行跨进程通信。
Messenger
:一种轻量级的基于 Handler 和 Message 的 IPC 方式,通常用于一个进程向另一个进程发送消息。
Content Provider
:允许不同应用间共享数据的组件,可以通过 ContentResolver 来查询和操作不同应用的数据库。
BroadcastReceiver
:通过广播机制,应用可以接收系统或其他应用发出的广播信息。
Intent
:通过 Intent 发送数据进行跨进程通信,例如启动 Activity 或者 Service。
SharedPreferences
:虽然不常用于进程间通信,但多个进程也可以通过共享的 SharedPreferences 文件来进行简单的数据交换。
Activity完整的生命周期:
onCreate()
:Activity 被首次创建时调用,通常在此方法中执行初始化操作,如设置布局、初始化数据等。
onStart()
:Activity 由不可见变为可见状态时调用,但还未与用户交互。
onResume()
:Activity 开始与用户交互,此时 Activity 位于前台并处于可交互状态。
onPause()
:Activity 失去焦点,但仍然部分可见(如另一个 Activity 以对话框形式弹出时)。
onStop()
:Activity 对用户完全不可见时调用,可能正在进入后台。
onRestart()
:Activity 由不可见状态重新变为可见时调用,通常紧接在 onStop() 之后。
onDestroy()
:Activity 被销毁前调用,用于释放资源或做一些清理工作。
简化的生命周期流程图:
onCreate() → onStart() → onResume() → onPause() → onStop() → onDestroy()
onCreate
(Bundle savedInstanceState):在 Fragment 被创建时调用。此时可以进行初始化操作,但还不能访问视图。onCreateView
(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState):负责创建 Fragment 的视图,返回一个 View 对象。可以在此处加载布局文件。
onViewCreated(View view, Bundle savedInstanceState):
在视图创建后立即调用,适合在此处进行视图的设置和初始化。
onActivityCreated(Bundle savedInstanceState):
当 Activity 的 onCreate() 方法返回后调用,此时可以访问 Activity 的其他组件。
onStart():
Fragment 变得对用户可见时调用。适合在此处启动与 UI 相关的操作。
onResume():
Fragment 与用户交互的状态,此时 Fragment 可见并处于前台。
onPause():
Fragment 不再与用户交互,此时可以在此处保存数据或停止动画等操作。
onStop():
Fragment 不再可见,适合在此处释放资源或保存状态。
onDestroyView():
在 Fragment 的视图被销毁时调用,可以在此处进行视图的清理。
onDestroy():
在 Fragment 被销毁时调用,适合在此处进行资源释放。
onDetach():
当 Fragment 从 Activity 分离时调用,适合在此处清理与 Activity 相关的引用。
1. Activity 的显式启动和隐式启动
显式启动 (Explicit Intent)
显式启动是指通过 明确指定 要启动的目标 Activity 类名来启动的方式。
特点:
通过目标 Activity 的类名(ComponentName)启动。
启动目标非常明确,直接指向某个特定的 Activity。
常用于应用内部的 Activity 之间的跳转。
使用示例:
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
上述代码中,TargetActivity.class
明确指定了要启动的目标 Activity。
隐式启动 (Implicit Intent)
隐式启动是通过 不直接指定目标 Activity,而是通过 Intent Filter(意图过滤器) 匹配的方式来启动合适的 Activity。
特点:
不指定具体的 Activity,而是通过 Action、Category、Data 等来匹配符合条件的 Activity。
可能会触发其他应用程序中的 Activity,只要匹配了所定义的 Intent Filter。
适合在应用间进行交互或让系统选择合适的应用来处理某个任务。
使用示例:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.example.com"));
startActivity(intent);
上述代码会启动任何符合 Intent.ACTION_VIEW 处理网页的 Activity,比如浏览器应用,而不限定为某个特定的 Activity。
特点:
通过接收者的 ComponentName(即类名)来明确指定要接收广播的 BroadcastReceiver
。
这种广播仅由指定的接收者处理,不会被其他 BroadcastReceiver
接收到。
常用于应用内部的广播发送与接收。
使用示例:
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.example.app", "com.example.app.MyBroadcastReceiver"));
sendBroadcast(intent);
这里明确指定了 MyBroadcastReceiver
来接收该广播。
隐式广播 (Implicit Broadcast)
隐式广播是通过 Intent Filter 匹配接收者来发送广播的方式,系统会广播给所有符合条件的接收者。
特点:
通过广播的 Action、Category 等来匹配广播接收器(BroadcastReceiver)。
所有符合条件的接收者都可以接收到这条广播,适用于应用间或系统范围内的广播。
如一些系统广播(如网络状态变化、电量低等)通常是隐式广播。
使用示例:
Intent intent = new Intent(Intent.ACTION_BATTERY_LOW);
sendBroadcast(intent);
该广播将发送给所有注册了 ACTION_BATTERY_LOW 的接收者,不限定某一个。
Android 8.0 及之后的隐式广播限制
从 Android 8.0 (API Level 26) 开始,隐式广播受到了较大的限制。为了减少后台运行和提升设备性能,系统不再允许大部分应用在后台接收隐式广播,除非广播接收器是动态注册的或者广播属于特定的系统广播(例如 BOOT_COMPLETED 等)。
总结
类型 显式启动/广播 | 隐式启动/广播 |
---|---|
通过明确指定 Activity 类名启动。仅启动特定的 Activity。 | 通过 Intent 匹配 Intent Filter 启动,系统决定启动哪个 Activity。 |
通过明确指定 BroadcastReceiver 类名发送广播。仅特定接收者接收。 | 通过 Intent Filter 匹配广播接收器,多个接收者可以同时接收广播。 |
应用内部的通信或需要精准控制接收者的情况。 | 系统级广播、应用间通信或需要动态决定接收者的情况。 |
限制 | 无限制。隐式广播在后台运行受到限制。 |
在实际开发中,使用显式或隐式的方式取决于你的使用场景。
自定义 View 开发是一项重要的技能,它允许开发人员创建具有自定义外观和行为的视图。自定义 View 的开发主要分为以下几种方式,每种方式有不同的适用场景和开发流程:
TextView, Button, ImageView
等)并对其进行定制。View 或 ViewGroup
继承,完全自定义控件的外观和行为。Compound View
),也就是将多个已有的 View 组合在一起,形成一个自定义的组件。可以使用经典的快慢指针法(也叫“龟兔赛跑”算法)来找到链表的中间位置。这是一种简单且高效的算法,其时间复杂度为 O(n),并且只需要 O(1) 的空间。
具体步骤如下:
定义两个指针:
一个慢指针(slow),每次向前移动一个节点。
一个快指针(fast),每次向前移动两个节点。
同时移动这两个指针:
当快指针到达链表末尾时,慢指针刚好处于链表的中间节点。
详细过程:
慢指针从链表的头部开始,每次向前走一步。
快指针从链表的头部开始,每次向前走两步。
当快指针走到链表的末尾时,慢指针会正好位于链表的中间节点。
代码实现(以 C++ 为例):
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* findMiddle(ListNode* head) {
if (head == nullptr) return nullptr; // 如果链表为空,返回空指针
ListNode* slow = head;
ListNode* fast = head;
// 当快指针到达链表末尾或其下一个节点为 null 时,慢指针正好处于中间
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow; // 慢指针指向链表的中间节点
}
解释:
如果链表长度为奇数,则当快指针走到最后一个节点时,慢指针会停在正中间节点上。
如果链表长度为偶数,则当快指针走到 null 时,慢指针会指向靠近中间的前一个节点(如果需要中间两个节点中的后一个,可以根据具体需求调整)。
优点:
时间复杂度为 O(n):只需要遍历链表一次。
空间复杂度为 O(1):只使用了两个额外的指针,不需要额外的空间。
在漆黑的夜里,四人过桥一共只带了一只手电筒,而桥窄得只够让两个人同时通过。如果各自单独过桥的话,四人所需要的时间分别是1,2,5,10分钟;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。
1,如果四人都过河,累计最少的时间是几分钟?请描述每个步骤;
2,如果是N个人过桥,每人需要的时间是t[i],过桥规则不变,请列出算式,计算所有人过桥所用的最短时间T。
1. 四人过桥的最少时间
四个人分别需要 1、2、5 和 10 分钟过桥,手电筒必须被带回,以确保所有人都能通过桥。
要确保时间最短的策略是采用最快的人带手电筒来返回,而让时间最长的两个人一起过桥。具体步骤如下:
我们用 A、B、C、D 来表示这四个人,他们需要的时间分别是 A = 1 分钟,B = 2 分钟,C = 5 分钟,D = 10 分钟。
策略:最快的人尽可能多地带手电筒返回,以节省整体时间。
步骤:
A 和 B 先一起过桥,耗时 2 分钟(因为 B 慢,所以耗时是 B 的时间)。
A 返回,耗时 1 分钟。
C 和 D 一起过桥,耗时 10 分钟(因为 D 慢,所以耗时是 D 的时间)。
B 返回,耗时 2 分钟。
A 和 B 再次一起过桥,耗时 2 分钟。
总时间 = 2(A 和 B 过桥) + 1(A 返回) + 10(C 和 D 过桥) + 2(B 返回) + 2(A 和 B 再次过桥) = 17 分钟。
2. N 个人过桥最短时间的计算
设有 N 个人过桥,每个人过桥所需的时间为 t[i],并且遵循同样的规则:每次只能两个人带手电筒过桥,返回时也需要带手电筒。
为了计算最短时间,我们可以采用类似的策略,快的人尽可能多次返回,时间最长的人尽可能少次过桥。
算式:
我们可以将问题归纳为以下两种基本模式来计算最少时间:
模式一:最慢的两个人(C 和 D)过桥,由最慢的返回,接着最快的带手电筒返回。这种情况下,最快的人(A 和 B)先过桥,再返回其中一个快的带手电筒,然后最慢的两个人过桥,再由次慢的返回。
模式二:最快的两个人(A 和 B)多次来回,帮助其他人过桥。
通用的算法推导(贪心算法):
对于排序好的时间数组 t = [t1, t2, t3, …, tn](已从小到大排序),采用以下贪心策略:
t1 和 t2 先过桥,然后 t1 返回。
tn 和 tn-1 过桥,t2 返回。
重复上述步骤。
对于一个排列好的时间数组 t,最短时间 T 公式为:
T = min( (t[1] + 2 * t[2] + t[N]), (2 * t[1] + t[N-1] + t[N]) )
解释:
两个策略的比较:一个是让最快的人多次返回,一个是让次慢的人返回,比较这两者的最小值。
这个公式会依次递归处理,直到剩下两个或三个人过桥,然后应用该公式计算总时间。
总结
对于 4 个人过桥的情况,最短时间为 17 分钟。
对于 N 个人过桥的通用计算公式,可以使用贪心算法将所有人过桥时间最小化