1.c# list中查找元素是否存在,如果存在返回索引,下面的代码为什么报错?
2.双向循环链表:鸿蒙轻内核中数据的“驿站”
3.面试官问线程安全的List,看完再也不怕了!
4.PHP实现一个账号同一时间只能一人登陆,给出源代码!洁霸洗衣粉溯源码
c# list中查找元素是否存在,如果存在返回索引,下面的代码为什么报错?
class Program{ static void Main(string[] args) { List<db> ls = new List<db> { }; ls.Add(new db() { id = 1, Name = "张三" }); ls.Add(new db() { id = 1, Name = "李四" }); ls.Add(new db() { id = 2, Name = "王五" }); string str = "李四"; Console.WriteLine(ls.FindIndex(x => x.Name == str)); //不存在:返回-1,存在:返回位置。 Console.ReadKey(); }}class db{ public int id; public string Name;}一. 基本概念
代码就是程序员用开发工具所支持的语言写出来的源文件,是一组由字符、符号或信号码元以离散形式表示信息的明确的规则体系。代码设计的原则包括唯一确定性、标准化和通用性、可扩充性与稳定性、便于识别与记忆、力求短小与格式统一以及容易修改等。
二. 作用
源代码主要功用有如下2种作用:
生成目标代码,stc 官方 源码即计算机可以识别的代码。
对软件进行说明,即对软件的编写进行说明。为数不少的初学者,甚至少数有经验的程序员都忽视软件说明的编写,因为这部分虽然不会在生成的程序中直接显示,也不参与编译。但是说明对软件的学习、分享、维护和软件复用都有巨大的好处。
需要指出的是,源代码的修改不能改变已经生成的目标代码。如果需要目标代码做出相应的修改,必须重新编译。
双向循环链表:鸿蒙轻内核中数据的“驿站”
摘要:双向循环链表Doubly Linked List在鸿蒙轻内核中扮演重要角色,广泛应用于各个模块。本文旨在深入解析双向循环链表在源代码中的应用,帮助读者理解和学习其在鸿蒙轻内核中的大白源码商城使用方法。以OpenHarmony LiteOS-M内核为例,通过详细讲解数据结构、初始化、判断、插入、删除、获取及遍历操作,本文将提供全面的双向循环链表操作指南。本文内容基于开源站点gitee.com/openharmony/k...
1 双向循环链表
双向循环链表的结构体LOS_DL_LIST在utils/los_list.h头文件中定义。它包含前驱和后继两个节点指针,用于实现环状数据结构。双向链表不存储业务数据,通常与业务数据结构结合使用。
双向链表的节点间操作方便,便于查找、插入和删除。通过定义一个LOS_DL_LIST类型的头结点,业务结构体的xise新版源码链表成员依次挂载,从而实现遍历。例如,互斥锁结构体LosMuxCB中,双向链表LOS_DL_LIST muxList与互斥锁业务信息成员协同工作。
初始化双向链表,可使用LOS_ListInit()函数为链表节点申请内存并链接环状。通过LOS_DL_LIST_HEAD()宏定义也可以直接初始化链表。
判断链表是否为空,使用LOS_ListEmpty()函数检查前驱和后继节点是否均为自身。
插入双向链表节点,提供三种方法:在指定节点后、尾部或头部插入。使用LOS_ListAdd()、LOS_ListTailInsert()和LOS_ListHeadInsert()内联函数分别实现。
删除双向链表节点,可使用LOS_ListDelete()函数移除指定节点,或使用LOS_ListDelInit()重置节点为新链表。
获取双向链表节点,discuz企业源码可通过LOS_DL_LIST_LAST()和LOS_DL_LIST_FIRST()获取前驱和后继节点。
遍历双向循环链表节点,使用LOS_DL_LIST_FOR_EACH()、LOS_DL_LIST_FOR_EACH_SAFE()和LOS_DL_LIST_FOR_EACH_ENTRY()等宏定义,实现节点的遍历。
获取链表节点所在结构体,利用LOS_OFF_SET_OF()和LOS_DL_LIST_ENTRY()宏定义,计算结构体内存地址。
基于以上操作,双向循环链表在鸿蒙轻内核中提供了高效、灵活的数据结构支持,是实现模块间高效数据传递和管理的关键。
面试官问线程安全的List,看完再也不怕了!
面试官提及线程安全的List时,多数求职者首先想到的是Vector,然而这只会让面试官感到失望。除了Vector,还有其他方法确保线程安全性。其中一种可行方案是使用java.util.Collections.SynchronizedList。此工具能将任何List接口的实现转换为线程安全的List,其构造方法如下:
由于SynchronizedList所有方法都带同步对象锁,性能可能不是最优。面试官可能还会追问,特别是在读多写少的情况下,SynchronizedList的性能表现不佳。这时,可以引入Java并发包中的并发集合类,如CopyOnWriteArrayList和CopyOnWriteArraySet。
CopyOnWriteArrayList,顾名思义,即复制再写入。在添加元素时,会先复制原有列表,再添加新元素。其add方法源码展示了这一过程:首先加锁,然后复制替换操作,最后释放锁。与此相对,其get方法源码显示,获取元素时无需加锁。这样设计使得在高并发情况下,读取性能得到显著提升,而写操作则需加锁以保证线程安全性。
CopyOnWriteArraySet的逻辑更为简单,通过调用CopyOnWriteArrayList的addIfAbsent方法来实现去重。在添加元素时,首先判断对象是否存在,若不存在则添加。这两种并发集合适用于读多写少的情况,但在读取多写取少的场景下,使用它们并无意义,因为每次写操作都涉及集合内存复制,可能导致性能损耗,尤其当集合较大时,容易引发内存溢出问题。
面试时,提及Vector > SynchronizedList > CopyOnWriteArrayList的线程安全List顺序,能展现对知识点的系统理解。掌握不同线程安全List的特性,有助于在面试中脱颖而出。
总结,确保线程安全的List选择多种多样,关键在于理解不同方案的适用场景与性能特性。对于求职者而言,通过了解这些内容,不仅能在面试中表现优异,也能在工作中灵活运用。请关注Java技术栈,了解更多多线程实战用法,获取更多接地气的干货内容。
PHP实现一个账号同一时间只能一人登陆,给出源代码!
对于一个帐号在同一时间只能一个人登录,可以通过下面的方法实现:
1 .在用户登录时,把用户添加到一个ArrayList中
2 .再次登录时查看ArrayList中有没有该用户,如果ArrayList中已经存在该用户,则阻止其登录
3 .当用户退出时,需要从该ArrayList中删除该用户,这又分为三种情况
① 使用注销按钮正常退出
② 点击浏览器关闭按钮或者用Alt+F4退出,可以用javascript捕捉该页面关闭事件,
执行一段java方法删除ArrayList中的用户
③ 非正常退出,比如客户端系统崩溃或突然死机,可以采用隔一段时间session没活动就删除该session所对应的用户来解决,这样用户需要等待一段时间之后就可以正常登录。
在LoginAction中定义:
// 用来在服务器端存储登录的所有帐号
public static List logonAccounts;
login() 登录方法中:
// 设置session不活动时间为分
request.getSession().setMaxInactiveInterval(*);
if(logonAccounts==null){
logonAccounts = new ArrayList();
}
// 查看ArrayList中有没有该用户
for (int i = 0; i < logonAccounts.size(); i++) {
Account existAccount = (Account)logonAccounts.get(i);
if(account.getAccountId().equals(existAccount.getAccountId())){
return "denied";
}
}
// 在用户登录时,把sessionId添加到一个account对象中
// 在后面 ③ 需要根据此sessionId删除相应用户
account.setSessionId(request.getSession().getId());
// 该用户保存到ArrayList静态类变量中
logonAccounts.add(account);
return "login";
① 使用注销按钮正常退出
logout() 退出方法中:
if(logonAccounts==null){
logonAccounts = new ArrayList();
}
// 删除ArrayList中的用户 ⑴
for (int i = 0; i < logonAccounts.size(); i++) {
Account existAccount = (Account)logonAccounts.get(i);
if(account.getAccountId().equals(existAccount.getAccountId())){
logonAccounts.remove(account);
}
}
② 点击浏览器关闭按钮或者用Alt+F4退出:
在后台弹出一个窗口,在弹出窗口中删除ArrayList中的用户
function window.onbeforeunload(){
// 是否通过关闭按钮或者用Alt+F4退出
// 如果为刷新触发onbeforeunload事件,下面if语句不执行
if (event.clientX>document.body.clientWidth && event.clientY<0||event.altKey){
window.open('accountUnbound.jsp','',
'height=0,width=0,top=,left=')
}
}
accountUnbound.jsp : 弹出窗口中删除ArrayList中的用户
<%
Account account = (Account) request.getSession().getAttribute("account");
if(account != null){
if(LoginAction.logonAccounts==null){
LoginAction.logonAccounts = new ArrayList();
}
// 删除ArrayList中的用户——下面代码和上面的 ⑴ 处一样
for (int i = 0; i < logonAccounts.size(); i++) {
Account existAccount = (Account)logonAccounts.get(i);
if(account.getAccountId().equals(existAccount.getAccountId())){
logonAccounts.remove(account);
}
}
}
%>
为了保证上面代码可以执行完毕,3秒后关闭此弹出窗口(也位于accountUnbound.jsp中)
<script>
setTimeout("closeWindow();",);
function closeWindow(){
window.close();
}
</script>
③ 使LoginAction 实现implements HttpSessionListener,并实现sessionCreated,sessionDestroyed方法,在sessionDestroyed中删除ArrayList中的用户(用户超过分钟不活动则执行此方法)
public void sessionDestroyed(HttpSessionEvent event) {
// 取得不活动时的sessionId,并根据其删除相应logonAccounts中的用户
String sessionId = event.getSession().getId();
for (int i = 0; i < logonAccounts.size(); i++) {
Account existAccount = (Account)logonAccounts.get(i);
if(account.getSessionId().equals(existAccount.getSessionId())){
logonAccounts.remove(account);
}
}
}
注:
对于上面的,由于弹出窗口很容易被防火墙或者安全软件阻拦,造成无法弹出窗口,从而短时间不能登录,这种情况可以用AJAX来代替弹出窗口,同样在后台执行删除用户的那段代码,却不会受到防火墙限制:
<script>
// <![CDATA[
var http_request = false;
function makeRequest(url) {
http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
}
}
}
if (!http_request) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
http_request.onreadystatechange = alertContents;
http_request.open('GET', url, true);
http_request.send(null);
}
function alertContents() {
if (http_request.readyState == 4) {
if (http_request.status == ) {
window.close();
} else {
alert('There was a problem with the request.');
}
}
}
function window. onbeforeunload() {
makeRequest ('accountUnbound.jsp');
}
//]]>
</script>